2015-12-19 10 views
5

申し訳ありませんが、私はこのプログラムを完了するのに非常に近いです。なぜ私のプログラムが動いていなかったのか、私はそれを修正できたのですが、今は勝者を確認しようとしています。私は私のwinGame()関数がある種の中にあるべきであるか、またはゲームを終了するためにループ中に行うべきであることを認識します。しかし、私はいくつかのものを並べ替えるために少しデバッグをしようとしていたとき、私は不安を感じる。常にそうでないと言われても、それはドローだと言われています。これらは私が理解できないほど恥ずかしく思っているような軽微なものであり、私はそれをどのように修正できるかについていくつかの助けが本当に好きです。また、もし勝利があれば、試合を終わらせるためにはしばらく時間がかかることがあると知っています。私はどこにそれを置くか分からないので、あなたは何か提案があれば、私に知らせてください。論理的な誤り、Tic Tac Toeの受賞者を確認する

*私の有効な移動関数では、配列が小さいことに注意してください。静的なconst配列にする予定です。私のget関数は名前の値を返します(例えば、getIval()はセルオブジェクトの初期値を返します)。

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

勝者を検出したらすぐに「真」に戻すのはなぜですか?代わりに、勝者を検出しています。すぐに戻るのではなく、あなたのコードは何も理由がないかどうかチェックします。 – PaulMcKenzie

+0

私はインストラクターから、関数内で複数のリターンを持つことはプログラミングの習慣が貧弱であることを知っていました。しかし、複数の人が私に同じことを言っていることを考えると、私はインストラクターが私に間違った情報を与えたと思っています。今私が知っているので、私はそれを考慮に入れます。お返事をありがとうございます! –

答えて

2

このコードには3つの問題があります。

  1. 勝利でゲームループが終了しません。
  2. 勝利が確認されるとすぐに勝利関数は戻りません。
  3. 描画条件のロジックが正しくありません。

これらは簡単に固定されます。あなたのDO-whileループの代わりに

  • リターンと行と列の勝利に破損がPassがWinGameme機能に変わり
  • を検証し、if文の余分な作りWinGame ==真

  • 変更した場合はブレーク turn == 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

こんにちは、あなたの思いやりのある応答のおかげで、本当に感謝しています。私のインストラクターは、関数内で複数のリターンを持つことはプログラミングの習慣が悪いことだと教えてくれました。しかし、他のリターンステートメントを追加するように通知したのはこれが初めてのことではありません。それは共通のことですか? –

関連する問題