C++ 逻辑错误,检查Tic Tac Toe中的赢家

C++ 逻辑错误,检查Tic Tac Toe中的赢家,c++,if-statement,C++,If Statement,好吧,我快完成这个节目了。我理解为什么我的程序没有采取行动,并且我能够修复它,但现在我正在努力寻找赢家。我意识到我的winGame()函数应该在某种while或do while循环中结束游戏。但是,当我试图做一些调试来解决一些问题时,我意识到一些令人不安的事情。它总是说这是一场平局,即使不应该这样。这些都是很小的事情,我不好意思不理解,我真的很想得到一些帮助,我可以如何解决它。而且,我知道如果赢了,应该有一段时间或者做一个while循环来结束比赛。我只是不知道该把它放在哪里,所以如果你有任何建议

好吧,我快完成这个节目了。我理解为什么我的程序没有采取行动,并且我能够修复它,但现在我正在努力寻找赢家。我意识到我的
winGame()
函数应该在某种while或do while循环中结束游戏。但是,当我试图做一些调试来解决一些问题时,我意识到一些令人不安的事情。它总是说这是一场平局,即使不应该这样。这些都是很小的事情,我不好意思不理解,我真的很想得到一些帮助,我可以如何解决它。而且,我知道如果赢了,应该有一段时间或者做一个while循环来结束比赛。我只是不知道该把它放在哪里,所以如果你有任何建议,请告诉我

*请注意,在我的有效move函数中有一个小数组,我计划将其设置为静态常量数组。我的get函数返回名称中的值(例如getIval()返回cell对象的初始值),而我的set函数只是适当地分配值

bool TicTacToe::validMove(char move){
    char options[9] = { '1','2', '3', '4','5','6','7', '8','9' };
    bool validate = false;
    for ( int i = 0; i < 9; i++ ){
        if ( move == options[i]){
            validate = true;
        }
    }

    return ( validate );
}

void TicTacToe::setMove( char move ){
    for ( int i = 0; i < ROW; i++ ){
        for ( int j = 0; j < COL; j++ ){
            if ( board[i][j].getiVal() == move ){
                board[i][j].setiVal( players[currentPlayer].getMarker() );
                switchPlayer();
                break;
            }
        }
    }
}

void TicTacToe::makeAMove(){
    char move;
    int turns = 1;
    bool validate = true;

    do{
        cout << "Player " << (getCurrentPlayer() + 1) << " make a move." << endl;
        cin >> move;

        if ( validMove( move ) ){
            if ( turns > 4 ){
                cout << "Nested if-else statement." << endl;
                winGame();
                setMove( move );
            }
            else
                setMove(move);
        }
        else{
            cout << "Invalid Move. Please reenter." << endl;
            cin >> move;
        }

        DrawBoard();
        turns++;

    } while ( turns <= 9 );   
}

bool TicTacToe::winGame(){
    cout << "Calling winGame() "  << endl;
    bool validate = false;
    int k = 0;
    for ( int i = 0; i < COL; i++ ){
        //check column wins
        if ( board[0][i].getMarker() == board[1][i].getMarker() && board[1][i].getMarker() == board[2][i].getMarker() && board[2][i].getMarker() != (' ')){
            cout << "Column win " << endl;
            validate = true;
            break;
        }
        //check row wins
        else if ( board[i][0].getMarker() == board[i][1].getMarker() && board[i][1].getMarker() == board[i][2].getMarker() && board[i][2].getMarker() !=  (' ')){
            cout << "Row win." << endl;
            validate = true;
            break;
        }
    }

    if( board[0][0].getMarker() == board[1][1].getMarker() && board[1][1].getMarker() == board[2][2].getMarker() && board[2][2].getMarker() != (' ')){
        cout << "Diagonal 1" << endl;
        validate = true;
    }
    else if ( board[0][2].getMarker() == board[1][1].getMarker() && board[1][1].getMarker() == board[2][0].getMarker() && board[2][0].getMarker() != (' ') ){
        cout << "Diagonal 2 " << endl;
        validate = true;
    }
    else{
        cout << "It's a draw!" << endl;
        validate = true;
    }

    return (validate);
}

此代码有3个问题

  • 游戏循环不会在胜利后结束
  • win功能不会在确认胜利后立即返回
  • 绘制条件的逻辑不正确
  • 不过,这些问题很容易解决

    • 如果WinGame==true,则在do-while循环中放置一个中断
    • 使用return-validate更改行和列胜利中的换行符
    • Pass转换为wingame函数,并生成一个额外的if语句 检查匝数是否=9

      void TicTacToe::makeAMove(){ 焦移动; 整数匝数=1; bool-validate=true

          do{
                  cout << "Player " << (getCurrentPlayer() + 1) << " make a move." << endl;
                  cin >> move;
      
                  if ( validMove( move ) ){
                          if ( turns > 4 ){
                                  cout << "Nested if-else statement." << endl;
      
                                  setMove( move );
                                  if (winGame(turns)==true)
                                  {
                                      break;
                                  }
                          }
                          else
                                  setMove(move);
                  }
                  else{
                          cout << "Invalid Move. Please reenter." << endl;
                          cin >> move;
                  }
      
                  DrawBoard();
                  turns++;
      
          } while ( turns <= 9 );
          cout << "Game Over" <<endl;
      
      do{
      库特
      它总是说这是一场平局,即使不应该这样

      原因是
      winGame
      函数在检测到行或列赢家时不会立即返回。相反,如果行或列赢家,则会进行额外的检查,以无理由检查对角赢家

      当检测到列或行赢家时,代码应该立即返回,而不是进行对角检查。如果代码是这样执行的,则也不需要使用
      validate
      变量

      如果你采用一种更系统的方法,只需为三种不同的赢家方式编写代码就更好了:按行、按列和按对角线。如果其中任何一种是赢家,请立即返回

      此外,在检查行、列或对角线之前,先检查是否有标记会更快。您的代码最后会检查标记是否为空,因此不需要在不需要调用它时调用
      getMarker

      代码说明了以下要点:

      bool TicTacToe::winGame()
      {
          char marker;
      
          // row check
          for ( int i = 0; i < COL; i++ )
          {
             marker = board[i][0].getMarker();  // get the initial marker
             // test if something is there
             if ( marker != ' ')
             {
                // now test the other two markers to see if they match
                if (  board[i][1].getMarker() == marker && 
                      board[i][2].getMarker() == marker )
                  return true;
             }
          }
      
          // column check
          for ( int i = 0; i < COL; i++ )
          {
             marker = board[0][i].getMarker();
             if ( marker != ' ')
             {
                if (  board[1][i].getMarker() == marker && 
                      board[2][i].getMarker() == marker )
                  return true;
             }
          }
      
          // check diagonals next
          //... (code not shown)
          return false; // if the diagonals fail
      }
      
      bool TicTacToe::winGame()
      {
      煤焦标记;
      //行检查
      for(int i=0;i

      我没有编写测试对角线的代码,但是你应该明白了。行和列检查是在单独的循环中完成的(没有什么特别的)。如果在这些循环的任何迭代中都有赢家,则返回值为
      true
      ,表示赢家。

      如果检测到赢家,为什么不立即返回
      true
      ?相反,您检测到的是赢家,而不是立即返回,您的代码会无缘无故地执行更多检查。我的讲师t在一个函数中有多个返回是一种糟糕的编程实践。但是考虑到很多人都在告诉我同样的事情,我开始认为我的导师给了我不正确的信息。现在我知道了,我会考虑到这一点。谢谢你的回复!嗨,谢谢你深思熟虑的回复,我真的很感激。我的讲师告诉我在一个函数中有多个返回是不好的编程实践。然而,这不是第一次有人通知我添加其他返回语句。这是常见的做法吗?
      bool TicTacToe::winGame(int turns)
      {
              cout << "Calling winGame() "  << endl;
              bool validate = false;
              int k = 0;
              for ( int i = 0; i < COL; i++ )
              {
                      //check column wins
                  if ( board[0][i].getMarker() == board[1][i].getMarker() &&
                       board[1][i].getMarker() == board[2][i].getMarker() &&
                       board[2][i].getMarker() != (' ')){
                              cout << "Column win " << endl;
                              validate = true;
                              break;
                      }
                      //check row wins
                       else if ( board[i][0].getMarker() == board[i][1].getMarker() &&
                                 board[i][1].getMarker() == board[i][2].getMarker() && 
                                 board[i][2].getMarker() !=  (' ')){
                              cout << "Row win." << endl;
                              validate = true;
                              break;
                      }
              }
      
              if( board[0][0].getMarker() == board[1][1].getMarker() && 
                  board[1][1].getMarker() == board[2][2].getMarker() && 
                  board[2][2].getMarker() != (' ')){
                      cout << "Diagonal 1" << endl;
                      validate = true;
              }
              else if ( board[0][2].getMarker() == board[1][1].getMarker() &&
                        board[1][1].getMarker() == board[2][0].getMarker() &&
                        board[2][0].getMarker() != (' ') ){
                      cout << "Diagonal 2 " << endl;
                      validate = true;
              }
              else
              {
                  if (turns==9)
                      {
                          cout << "It's a draw!" << endl;
                          validate = true;
                      }
              }
      
              return (validate);
      } 
      
      bool TicTacToe::winGame()
      {
          char marker;
      
          // row check
          for ( int i = 0; i < COL; i++ )
          {
             marker = board[i][0].getMarker();  // get the initial marker
             // test if something is there
             if ( marker != ' ')
             {
                // now test the other two markers to see if they match
                if (  board[i][1].getMarker() == marker && 
                      board[i][2].getMarker() == marker )
                  return true;
             }
          }
      
          // column check
          for ( int i = 0; i < COL; i++ )
          {
             marker = board[0][i].getMarker();
             if ( marker != ' ')
             {
                if (  board[1][i].getMarker() == marker && 
                      board[2][i].getMarker() == marker )
                  return true;
             }
          }
      
          // check diagonals next
          //... (code not shown)
          return false; // if the diagonals fail
      }