2015-12-19 80 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

嗨,感謝您的深思熟慮,我非常感謝。我的老師告訴我,在一個函數中有多個返回是不好的編程習慣。但是,這不是第一次有人通知我添加其他返回語句。這是一件常見的事情嗎? –