如何修复在C++中回放Tic-Tac-Toe游戏时前三个回合的隐藏

How to fix hiding for the first three turns when replaying a game of Tic Tac Toe in C++?

本文关键字:三个 隐藏 C++ 何修复 回放 游戏 Tic-Tac-Toe      更新时间:2023-10-16

我正在使用基于控制台的界面在C中创建一个Tic-Tac-Toe游戏。两名球员通过从1-9中选择一个数字将他们的棋子放在棋盘上进行对抗。我有一个奇怪的问题,当比赛结束时(比如一名球员赢得比赛或比赛以平局结束)。将向用户提供再次播放的提示。

如果玩家再次输入"Y",棋盘将被清除,然后再次显示。然而,在前三个回合,当玩家键入一个数字来选择棋盘上的位置时,控制台会发出一个"错误",说"这个动作无效,因为这个空间已经被占用",然而在第四个回合,游戏照常进行,玩家在本轮比赛中选择的所有棋子现在都显示在棋盘上,没有向用户打印"错误"。有没有办法解决这个奇怪的故障?如果我措辞不好,我很抱歉。非常感谢。

//Libaries
#include <iostream>
#include <string>
#include <array>
#include <limits>
using namespace std;
//Indentifers
void gamescreen(); //Used to display the board
char gamecondition(); //This is indentifer is used to check the game is won lost/draw
void playerturn();
void playernames();
int resultsscreen();
int turn;
int playerinput(int playerchoice);
int Player1Score, Player2Score;
//Variables
//int menuchoice; //Not Neeeded for now
char PlayerPiece = 'X';
char GameWinner; //Declare for game winner
char board[3][3] = { '1', '2', '3', '4', '5', '6', '7', '8', '9' }; //Creates a 3 by 3 matrix, which is basically the board.
int playerchoice; //Reason why playerchoice is a int rather than a char is because
string Player1Name, Player2Name, Player;
char finalchoice;
void playernames()
{
    cout << "Player 1 please enter your name" << endl; //Asks for the first username
    cin >> Player1Name; // Gets the first user name
    cout << "Player 2 please enter your name" << endl; //Asks for the second username
    cin >> Player2Name; // Gets the second user name
    cout << "Player 1 Name is: " << Player1Name << " " << "and Player 2 name is: " << Player2Name << endl; //Displays Usernames
}
void gamescreen() //Displays the board on the screen to the players
{
    system("cls"); //CLears the screen again, to make the game clean and tidy
    cout << "SCOREBOARD: " << Player1Name << ": " << Player1Score << " " << Player2Name << ": " << Player2Score << endl;
    cout << "n" << endl;
    cout << board[0][0] << " | " << board[0][1] << " | " << board[0][2] << endl;
    cout << board[1][0] << " | " << board[1][1] << " | " << board[1][2] << endl;
    cout << board[2][0] << " | " << board[2][1] << " | " << board[2][2] << endl;
}
void playercheck()
{
    if (PlayerPiece == 'X')
    {
        cout << "It is " << Player1Name << " Turn, please put select a piece on the board" << endl;
    }
    if (PlayerPiece == 'O')
    {
        cout << "It is " << Player2Name << " Turn, please put select a piece on the board" << endl;
    }
    cin >> playerchoice;
    playerinput(playerchoice);
}
int playerinput(int playerchoice)
{
    if (playerchoice > 9 || playerchoice < 1 || cin.fail())
    {
        cin.clear();
        cin.ignore(std::numeric_limits<std::streamsize>::max(), 'n');
        cout << "Please enter a number from 1-9!" << endl;
        playercheck();
    }
    else
    {
        if (playerchoice == 1) //If the player chose this one then
        {
            if (board[0][0] == '1') //This turns the number into a position on the board, it checks if the place is valid and there isn't a position on the board. If so then it places the player piece down
                board[0][0] = PlayerPiece; //If the condition is true, then it replaces that board space with the player piece
            else
            {
                cout << "This move is invalid because this space has been claimed" << endl; //However if there was not a space or the player just decides to put a number other than 1-9 then this message pops up
                playercheck(); //This function is called again to elimate the need for loops.
            }
        }
        else if (playerchoice == 2) //If the player chose this one then
        {
            if (board[0][1] == '2') //This turns the number into a position on the board, it checks if the place is valid and there isn't a position on the board. If so then it places the player piece down
                board[0][1] = PlayerPiece;
            else
            {
                cout << "This move is invalid because this space has been claimed" << endl; //However if there was not a space or the player just decides to put a number other than 1-9 then this message pops up
                playercheck(); //This function is called again to elimate the need for loops.
            }
        }
        else if (playerchoice == 3) //If the player chose this one then
        {
            if (board[0][2] == '3') //This turns the number into a position on the board, it checks if the place is valid and there isn't a position on the board. If so then it places the player piece down
                board[0][2] = PlayerPiece;
            else
            {
                cout << "This move is invalid because this space has been claimed" << endl; //However if there was not a space or the player just decides to put a number other than 1-9 then this message pops up
                playercheck(); //This function is called again to elimate the need for loops.
            }
        }
        else if (playerchoice == 4) //If the player chose this one then
        {
            if (board[1][0] == '4') //This turns the number into a position on the board, it checks if the place is valid and there isn't a position on the board. If so then it places the player piece down
                board[1][0] = PlayerPiece;
            else
            {
                cout << "This move is invalid because this space has been claimed" << endl; //However if there was not a space or the player just decides to put a number other than 1-9 then this message pops up
                playercheck(); //This function is called again to elimate the need for loops.
            }
        }
        else if (playerchoice == 5) //If the player chose this one then
        {
            if (board[1][1] == '5') //This turns the number into a position on the board, it checks if the place is valid and there isn't a position on the board. If so then it places the player piece down
                board[1][1] = PlayerPiece;
            else
            {
                cout << "This move is invalid because this space has been claimed" << endl; //However if there was not a space or the player just decides to put a number other than 1-9 then this message pops up
                playercheck(); //This function is called again to elimate the need for loops.
            }
        }
        else if (playerchoice == 6) //If the player chose this one then
        {
            if (board[1][2] == '6') //This turns the number into a position on the board, it checks if the place is valid and there isn't a position on the board. If so then it places the player piece down
                board[1][2] = PlayerPiece;
            else
            {
                cout << "This move is invalid because this space has been claimed" << endl; //However if there was not a space or the player just decides to put a number other than 1-9 then this message pops up
                playercheck(); //This function is called again to elimate the need for loops.
            }
        }
        else if (playerchoice == 7) //If the player chose this one then
        {
            if (board[2][0] == '7') //This turns the number into a position on the board, it checks if the place is valid and there isn't a position on the board. If so then it places the player piece down
                board[2][0] = PlayerPiece;
            else
            {
                cout << "This move is invalid because this space has been claimed" << endl; //However if there was not a space or the player just decides to put a number other than 1-9 then this message pops up
                playercheck(); //This function is called again to elimate the need for loops.
            }
        }
        else if (playerchoice == 8) //If the player chose this one then
        {
            if (board[2][1] == '8') //This turns the number into a position on the board, it checks if the place is valid and there isn't a position on the board. If so then it places the player piece down
                board[2][1] = PlayerPiece;
            else
            {
                cout << "This move is invalid because this space has been claimed" << endl; //However if there was not a space or the player just decides to put a number other than 1-9 then this message pops up
                playercheck(); //This function is called again to elimate the need for loops.
            }
        }
        else if (playerchoice == 9) //If the player chose this one then
        {
            if (board[2][2] == '9') //This turns the number into a position on the board, it checks if the place is valid and there isn't a position on the board. If so then it places the player piece down
                board[2][2] = PlayerPiece;
            else
            {
                cout << "This move is invalid because this space has been claimed" << endl; //However if there was not a space or the player just decides to put a number other than 1-9 then this message pops up
                playercheck(); //This function is called again to elimate the need for loops.
            }
        }
        else
        {
            cout << "Please enter in a valid number!" << endl;
            playercheck();
            //Fail safe just in case the first one failed somehow.
        }
    }
    //The if statements about choices, etc. Checking if this space has not been picked yet
    //NEED TO CHANGE ALL OF THE NUMBERS
    return 1;
}
void playerturn()
{
    if (PlayerPiece == 'X')
        PlayerPiece = 'O';
    else
        PlayerPiece = 'X';
}
char gamecondition() //This is used to check the win conidtion aka who won or if not how does this game draw?
{
    //Checks for the first player
    if (board[0][0] == 'X' && board[0][1] == 'X' && board[0][2] == 'X')
        return 'X'; //Basically this checks if the there is three in a row in the board, if show it returns the value X, which will be shown in the main. (Basically if GameWinner == X, cout << "Player1 wins!" << endl;
    if (board[1][0] == 'X' && board[1][1] == 'X' && board[1][2] == 'X')
        return 'X';
    if (board[2][0] == 'X' && board[2][1] == 'X' && board[2][2] == 'X')
        return 'X';
    if (board[0][0] == 'X' && board[1][0] == 'X' && board[2][0] == 'X')
        return 'X';
    if (board[0][1] == 'X' && board[1][1] == 'X' && board[2][1] == 'X')
        return 'X';
    if (board[0][2] == 'X' && board[1][2] == 'X' && board[2][2] == 'X')
        return 'X';
    if (board[0][0] == 'X' && board[1][1] == 'X' && board[2][2] == 'X')
        return 'X';
    if (board[2][0] == 'X' && board[1][1] == 'X' && board[0][2] == 'X')
        return 'X'; //Returns X to the gamecondition()
                    //Checks for the second player
    if (board[0][0] == 'O' && board[0][1] == 'O' && board[0][2] == 'O')
        return 'O'; //Basically this checks if the there is three in a row in the board, if show it returns the value X, which will be shown in the main. (Basically if gameconidition == X, cout << "Player1 wins!" << endl;
    if (board[1][0] == 'O' && board[1][1] == 'O' && board[1][2] == 'O')
        return 'O';
    if (board[2][0] == 'O' && board[2][1] == 'O' && board[2][2] == 'O')
        return 'O';
    if (board[0][0] == 'O' && board[1][0] == 'O' && board[2][0] == 'O')
        return 'O';
    if (board[0][1] == 'O' && board[1][1] == 'O' && board[2][1] == 'O')
        return 'O';
    if (board[0][2] == 'O' && board[1][2] == 'O' && board[2][2] == 'O')
        return 'O';
    if (board[0][0] == 'O' && board[1][1] == 'O' && board[2][2] == 'O')
        return 'O';
    if (board[2][0] == 'O' && board[1][1] == 'O' && board[0][2] == 'O')
        return 'O';
    else
        return '/'; //If it isn't either O or X then returns '/' which shows it's a draw
}
int main()
{
    playernames();
    turn = 0; //This is a turn counter, this will be used to determine the draw (Without it the game will keep on going)
    gamescreen(); //Displays the game screen again
    while (1)
    {
        turn++; //If the game hasn't been completed yet then adds 1 to the number counter
        playercheck();
        gamescreen();
        if (gamecondition() == 'X')
        {
            cout << Player1Name << " wins!" << endl;
            Player1Score++;
            resultsscreen();
        }
        else if (gamecondition() == 'O')
        {
            cout << Player2Name << " wins!" << endl;
            Player2Score++;
            resultsscreen();
        }
        else if (gamecondition() == '/' && turn == 9)
        {
            cout << "It's a draw!" << endl;
            resultsscreen();
        }
        playerturn();
    }
}
int resultsscreen()
{
    cout << "The current score is:" << endl;
    cout << Player1Name << ":" << Player1Score << endl;
    cout << Player2Name << ":" << Player2Score << endl;
    cout << "Would you like to play again, Y/N?" << endl;
    cin >> finalchoice;
    if (finalchoice == 'Y' || finalchoice == 'y')
    {
        turn = 0;
        board[0][0] = '1', board[0][1] = '2', board[0][2] = '3';
        board[1][0] = '4', board[1][1] = '5', board[1][2] = '6';
        board[2][0] = '7', board[2][1] = '8', board[2][2] = '9';
        system("cls");
        gamescreen();
        playercheck();
        playerturn();
        playerinput(playerchoice);
    }
    if (finalchoice == 'N' || finalchoice == 'n')
    {
        if (Player1Score > Player2Score)
        {
            cout << Player1Name << " wins!" << endl;
            system("pause");
            exit(0);
        }
        if (Player1Score < Player2Score)
        {
            cout << Player2Name << " wins!" << endl;
            system("pause");
            exit(0);
        }
        else if (Player1Score == Player2Score)
        {
            cout << "It's a draw!" << endl;
            system("pause");
            exit(0);
        }
    }
    return 0;
}

您正在调用

playerinput();
playercheck();
gamescreen(); 

的功能

resultsscreen(); 

这是不必要的,会导致您的问题。从resultsscreen()中删除这些函数,因为如果用户选择继续游戏,它们将在主函数循环中再次调用(因此它显示插槽已被占用)。