2015-12-19 54 views
5

好的,所以我非常接近完成这个程序。我明白为什么我的计划没有采取行动,而且我能够解决这个问题,但现在我正在努力检查赢家。我意识到我的winGame()函数应该在某种时候或者在循环结束游戏时做。但是,当我试图做一些调试来分析一些事情时,我意识到一些令人不安的事情。它总是说它是平局,即使它不应该是平局。这些小事是我惭愧不明白的,我真的很想帮助我解决这个问题。另外,我知道如果有一场胜利,应该有一段时间,或者在循环结束时进行。我只是不确定放在哪里,所以如果你有任何建议,请让我知道。 *请注意,在我的有效移动函数中有一个小数组,我计划使它成为一个静态常量数组。我的get函数返回名称中的值(例如getIval()返回单元格对象的初始值),而我的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); 
} 

下面是该程序的示例运行供您参考。

//sample run 
+--+--+--+ 
|1 |2 |3 | 
+--+--+--+ 
|4 |5 |6 | 
+--+--+--+ 
|7 |8 |9 | 
+--+--+--+ 
Player 1 make a move. 
1 

+--+--+--+ 
|X |2 |3 | 
+--+--+--+ 
|4 |5 |6 | 
+--+--+--+ 
|7 |8 |9 | 
+--+--+--+ 
Player 2 make a move. 
2 

+--+--+--+ 
|X |O |3 | 
+--+--+--+ 
|4 |5 |6 | 
+--+--+--+ 
|7 |8 |9 | 
+--+--+--+ 
Player 1 make a move. 
3 

+--+--+--+ 
|X |O |X | 
+--+--+--+ 
|4 |5 |6 | 
+--+--+--+ 
|7 |8 |9 | 
+--+--+--+ 
Player 2 make a move. 
5 

+--+--+--+ 
|X |O |X | 
+--+--+--+ 
|4 |O |6 | 
+--+--+--+ 
|7 |8 |9 | 
+--+--+--+ 
Player 1 make a move. 
+--+--+--+ 
|X |O |X | 
+--+--+--+ 
|4 |O |6 | 
+--+--+--+ 
|7 |8 |9 | 
+--+--+--+ 
Player 1 make a move. 
7 
Nested if-else statement. 
Calling winGame() 
It's a draw! 

+--+--+--+ 
|X |O |X | 
+--+--+--+ 
|4 |O |6 | 
+--+--+--+ 
|X |8 |9 | 
+--+--+--+ 
Player 2 make a move. 
8 
Nested if-else statement. 
Calling winGame() 
It's a draw! 

+--+--+--+ 
|X |O |X | 
+--+--+--+ 
|4 |O |6 | 
+--+--+--+ 
|X |O |9 | 
+--+--+--+ 
+1

为什么一旦你发现一个胜利者,你就不会立即返回'true'?相反,您正在检测获胜者,而不是立即返回,您的代码会无缘无故地执行更多检查。 – PaulMcKenzie

+0

我的讲师告诉我,在一个函数中有多个回报是不好的编程习惯。但鉴于多人告诉我同样的事情,我开始认为我的导师给了我不正确的信息。现在我知道了,我会考虑这一点。感谢您的答复! –

回答

2

这个代码有3个问题。

  1. 游戏循环不会在胜利结束。
  2. 胜利确认后,赢得功能不会返回。
  3. 绘制条件的逻辑错误。

虽然这些很容易修复。

    在do-while循环的地方
  • 如果WinGame ==真
  • 变化的行和列的胜利休息时间,返回验证
  • 通行证变成了WinGameme功能,并作出额外的if语句休息 检查是否转向== 9

    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; 
    
              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; 
    

    }

然后

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); 
} 
2

它总是说,这是一场平局,甚至当它不应该是。

原因是您的winGame函数在检测到行或列胜者时不会立即返回。相反,如果某一行或某列获胜,则会进行额外的检查以无缘由地检查对角冠军。

代码应该在检测到列或行优胜者时立即返回,而不是跑入对角线检查。如果以这种方式完成代码,那么也不需要变量validate

如果你采取更系统化的方法,并且只写出3种不同的获胜方式:按行,按列和按对角线,那会更好。如果其中任何一个是获胜者,则立即返回。

此外,在检查行,列或对角线之前检查是否有标记首先更快。您的代码最后会进行空白标记检查,因此无需在不需要调用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 
} 

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

+0

嗨,感谢您的深思熟虑,我非常感谢。我的老师告诉我,在一个函数中有多个返回是不好的编程习惯。但是,这不是第一次有人通知我添加其他返回语句。这是一件常见的事情吗? –