无法弄清楚如何循环播放器转弯和移动 Tic Tac Toe (C++)

Can't figure out how to loop playerturns and moves Tic Tac Toe (C++)

编辑:现在解决了,谢谢 triple_r 和 AJNeufield 对我遇到的这个问题的帮助。

我已经在多个网站和 YouTube 上浏览过有关此内容的内容,但我似乎找不到任何关于我专门寻找的内容,因为我的程序格式与其他程序有很大不同。因此,很难破译我需要把我知道的东西放在哪里。

请注意,我是 C++ 的新手,因此非常感谢您向我提供的所有反馈或批评。

此外,请注意我的代码确实可以编译,运行 它只是不允许我输入多个输入,而且很可能不允许切换玩家回合。

快速编辑:用 triple_r 建议的新设置切换了代码,但我似乎把它弄乱了,它确实编译了(除了 x 和 y 没有被使用和另一个错误)但它总是从玩家 2 先开始,一旦它收到输入,它就会自动以分段错误结束。

#include <iostream>
#include <cstdlib>
using namespace std;
//////////////////////////////////////////////////////////
void initboard(char board[3][3])
{
    int x,y;
    for (x=0;x<3;x++)
            for (y=0;y<3;y++)
            board[x][y]=' ';
    return;
}
//////////////////////////////////////////////////////////
void printboard(char board[3][3])
{
    int x,y;
    for (x=0;x<3;x++)
    {
        cout<<"\n";
        for (y=0;y<3;y++)
        {
            cout<<" "<<board[x][y]<<" ";
            if (y<2) cout<<"|";
        }
        if (x<2) cout<<"\n===========";
    }
    return;
}
//////////////////////////////////////////////////////////
void getmove(char board[3][3], int player)
{
    return;
}
//////////////////////////////////////////////////////////
int main()
{
    bool done=false;
    char board[3][3];
    int x,y,player=1,turn,playerchoice,playermark;

    initboard(board);
    turn=0;
    do
    {
        if (player==1)
            playermark='X';
        else
            playermark='O';
        if (turn%2)
            player=1;
        else
            player=2;

        cout<<"Player "<<player<<" where do you want to move?: ";   
        cin>>playerchoice;
        if (playerchoice==1)
        {
            board[0][0]=playermark;
        }
        else if (playerchoice==2)
        {
            board[0][1]=playermark; 
        }
        else if (playerchoice==3)
        {
            board[0][2]=playermark;
        }
        else if (playerchoice==4)
        {
            board[1][0]=playermark;
        }
        else if (playerchoice==5)
        {
            board[1][1]=playermark;
        }
        else if (playerchoice==6)
        {
            board[1][2]=playermark;
        }
        else if (playerchoice==7)
        {
            board[2][0]=playermark;
        }
        else if (playerchoice==8)
        {
            board[2][1]=playermark;
        }
        else if (playerchoice==9)
        {
            board[2][2]=playermark;
        }
        else
        {
            cout<<"Invalid move ";
        }
        if (board[x][y]!=' ')
            cout<<"Move is already taken."; 
        board[x][y]=playermark;

        if(board[x][y]==' ')
            turn++;
    }while (!done);
    void printboard(char board[3][3]);
    return 0;
}

您的 cin >> playerchoicedo { ... } while ( moves != 9); 循环之外。把它移到里面。

编辑:基于更新后的代码

所以,我首先看到的是您在程序中使用了 xy,但您没有初始化它们或为它们分配任何值。另外,尝试使用 functions/classes/... 哟使您的代码更具可读性。你已经有一个玩家移动的功能,但你没有使用它。您可以在该函数内移动大的 if 语句,这将使您的主代码更短且更易读。

以下是我对您程序主要部分的评论:

int main()
{
    // add a new variable to see if the move was valid or not:
    bool done=false, validmove = true;
    char board[3][3];
    int x, y, player = 1, turn = 0, playerchoice, playermark;

    initboard(board);
    do
    {
        // swap the two `if`s so you decide who`s turn it is then assign the player mark,
        //  also, reverse the condition to make sure turn '0' is player 1's turn.
        if (!(turn % 2))
            player = 1;
        else
            player = 2;
        if (player == 1)
            playermark = 'X';
        else
            playermark = 'O';

        cout << "Player " << player << " where do you want to move?: ";
        cin >> playerchoice;

        // Assign `x` and `y` here instead of updating the board, because you want to make
        //  sure that the move is valid before putting the mark:
        validmove = true;
        if (playerchoice == 1)
        {
            x = 0; y = 0;
        }
        else if (playerchoice == 2)
        {
            x = 0; y = 1;
        }
        else if (playerchoice == 3)
        {
            x = 0; y = 2;
        }
        else if (playerchoice == 4)
        {
            x = 1; y = 0;
        }
        else if (playerchoice == 5)
        {
            x = 1; y = 1;
        }
        else if (playerchoice == 6)
        {
            x = 1; y = 2;
        }
        else if (playerchoice == 7)
        {
            x = 2; y = 0;
        }
        else if (playerchoice == 8)
        {
            x = 2; y = 1;
        }
        else if (playerchoice == 9)
        {
            x = 2; y = 2;
        }
        else
        {
            cout << "Invalid move, try again!";

            // Make sure to mark the move as invalid so they get a chance to
            //  change their move:
            validmove = false;
        }

        // check to see if the turn was valid:
        if(validmove)
        {
            if (board[x][y] != ' ')
            {
                cout << "Move is already taken, try again";
            }
            else
            {
                board[x][y] = playermark;
                turn++;
            }
        }

        // have to make sure you have a condition for end of game. A simple
        //  one is to check if turn is less than `9`, otherwise the board is
        //  full:
        if(turn == 9)
            done = true;

        // you probably want to add a few more checks to see who won the game.
    }while (!done);

    // when calling a function, no need to put the return type or parameter type:
    printboard(board);
    return 0;
}

============================================= ===========================

您的程序中有两个 do-while 循环,它们似乎都是游戏循环。我会做的是:

initboard(...);
turn = 0;
do{
    //this is the game loop
    ...;
    if( validturn )
        turn++;
}while(!done);
release_resources(...);
return 0;

因此,您将所有内容折叠成一个循环。在那个循环中,你想要:

  1. 找出轮到谁了:

    if (turn % 2)
        player = 1;
    else
        player = 2;
    
  2. 获取用户输入:

    std::cin >> playerchoice;
    ...
    
  3. 将玩家选择转换为网格位置:

    switch ( move )
    {
        case 0:
            x = 0;
            y = 0;
            break;
        case 1:
            ...;
        ...
        default:
            //invalid move
    }
    
  4. 看看着法是否有效:

    if( board[x][y] != ' ' )
        //already taken, invalid move
    
  5. 然后应用移动:

    board[x][y] = playermark;
    

希望对您有所帮助。