2017-11-23 3 views
0

これは私の最初の投稿ですが、私はしばらくスタックオーバーフローをストーカーしました。私はティックタックトウボードを表すBoardクラスを作るという課題を持っています。私はまた、ファイルからティックタックのつま先の動きを読み込んでボードに再生するReaderクラスを作成する必要があります(代わりに...知っているプレイヤー...実際にゲームをプレイしています)。リーダークラスのゲームボード:正しくブール値を返す

ゲームボードが

array[row][column] 
00 01 02 
10 11 12 
20 21 22 

likeso 2D配列として設定されている割り当てのための要件は、.txtファイルからBoardオブジェクトに値を読み込み、ゲームをプレイするためにReaderクラスのブール機能が欲しいです。しかし、ファイルが二度同じ動きを再生しようとすると、それはfalseを返す必要があります。oは以来01で再生することはできませんので

game.txt 
01 
11 
12 
01 

falseを返す必要があります:たとえば(ノタのベーネ最初の動きは、x常にあります) xはそこから始まった。

ゲームが終了してもファイル内に「再生」がある場合は、falseも返す必要があります。たとえば:

game2.txt 
00 
10 
11 
12 
22 
02 

oはxが既に獲得しているにもかかわらず02を再生しようとします。これはまたfalseを返します(何とか勝った場合も同じです)。

今、私は正しく返すものは得られません。コードは、このリンクである(私が知っている、私が知っている...ない最高の共有方法が、私は初心者だと私はそれを受け入れることを積み重ね取得する方法を見つけ出すことができませんでした):

bool Reader::readGameFile(string fileName) 
{ 
    ifstream inputFile; 
    int row, column; 
    bool flagVar = true; 
    inputFile.open(fileName); 

    if (inputFile) 
    {  
     while(inputFile >> row >> column) //keep looping until the file runs out of input 
     {  
      if (board.checkOneBlank(row, column)) 
      { 
       if(board.gameState() == X_WON) 
        flagVar = false; 
       if(board.gameState() == O_WON) 
        flagVar = false; 
       if(board.gameState() == UNFINISHED) 
        flagVar = true; 
       board.makeMove(row, column, playerTurn); 
       if(playerTurn == 'x') 
       { 
        playerTurn = 'o'; 
       } 
       else 
       { 
        playerTurn = 'x'; 
       } 

      } 
     } 
    } 
    if(flagVar) 
     return true; 
    else if(flagVar == false) 
     return false; 
    else if (board.gameState() == DRAW) 
     return true; 
    else 
     return true; 
    inputFile.close(); 
} 

Boardクラスには次の機能があります。

bool makeMove(int, int char); // which calls checkOneBlank and will record a move to the board if it is blank 
void print();     // which prints the board 
bool checkOneBlank(int, int); // checks to see if a value is blank 
bool checkState(char);  // checks to see if there are any horizontal, vertical, or diagonal wins 
bool checkAllBlanks();  // checks to see if there are any blanks left on the board and counts them. if there are more than 0 then it returns false (used to check for a draw) 
Game game();     // checks to see if the game has an x winner, an o winner, a draw, or is unfinished. is an enumerated data type due to the specifications of the project 

これらの機能はすべてテスト済みです。彼らは期待どおりに動作します。

上記の機能を正しく動作させるための助けに感謝します。これは私を夢中にさせている。ありがとう!

編集:bool値が正しく返されるようにする方法を知りたいと思います。私の質問は、これらのループを機能させる方法です。プレイヤーがまだ遊んでいても、whileループをファイルの最後まで実行する必要があります。それはプロジェクトの仕様です。

+0

ゲームが完了していなくても、ゲームが完了していない場合は、プレーヤーを変更する必要があります(今はやっています)。前にファイルを閉じる必要があります!機能から戻る。また、単にflagVarを返すこともできます(実行結果は現在のコードと同じになります) –

+0

@AndrewKashpur '〜ifstream'がファイルを閉じます。 'ifstream inputFile(filename)'はすべてが必要です。 – Caleth

答えて

0

あなたの実際の質問が何であるかを理解することは難しいと思いますが、ここに私の仮説があります。 あなたの選手は、他の選手が勝利したにもかかわらず、動きを続けています。なぜ彼らがそれをやっているのか疑問に思っています。

これは、あなたがwhileループを壊すことがないためです。私はmakeMoveメソッドがあなたのゲーム状態を返すことを提案します。そのメソッドを実行するとすぐに戻り値をチェックし、xまたはyが勝った場合、または描画された場合はbreakコマンドを使用してwhileループを終了します。あなたが本当にする必要があり、代わりに状態を返すmakeMove有するので、あなたはちょうどそれが状態を変更するとgameStateを使用して、それを確認することができた場合gameState方法の必要性を除去するであろう

は、しかし、あなたはそれを維持することができます。

このコードを簡略化して改善する機会は他にもたくさんありますが、私はそれらを見つけることができます。

+0

プロジェクトの自由な治世があれば、私はそういうことをします。私は教授によって設計されたもので、makeMoveメソッドがゲームの状態を返すようなことをすると、私はポイントを取得します。 – folknameded

+0

奇妙なデザインの選択肢ですが、最終的にどのような方法がどの値を返すのかがポイントになりません。 私が言ったように、2番目のアプローチを取って、ボードクラスのインターフェイスを保持して、勝利状態またはドロー状態になったときに状態ポストを確認して休憩することができます。 – Vidrohi

+0

さらに、あなたは正しいです - 私は実際には質問ではありませんでした。私の質問はこれです:私はどのようにコードを適切にbool値を返すようにしますか?プロジェクトの仕様では、whileループを.txtファイルの最後まで実行しておく必要があります。 – folknameded

0

結果が得られたときにループを停止する最も簡単な方法は、結果としてreturnです。

bool Reader::readGameFile(string fileName) 
{ 
    ifstream inputFile(fileName); 
    // Opens the file. When inputFile is destroyed, the file is closed 
    // The principle of doing an action at the end of a scope, by using 
    // some object's destructor is called RAII. It is one of the most important 
    // parts of idiomatic C++ 

    for (int row, column; inputFile >> row >> column;) 
    {  
     // We only need row and column within the loop, so they are only defined here 
     if (board.checkOneBlank(row, column)) 
     { 
      board.makeMove(row, column, playerTurn); 
      // move first, so that we check the state after the move 
      // otherwise we don't return the correct result if a win 
      // happens as the last move in a file 

      if(board.gameState() == X_WON) 
       return false; 
      if(board.gameState() == O_WON) 
       return false; 
      if(board.gameState() == DRAW) 
       return true; 
      // We are done with this function. 
      // Because our local objects tidy up after themselves, 
      // we don't need any "goto cleanup" etc. 

      if(playerTurn == 'x') 
      { 
       playerTurn = 'o'; 
      } 
      else 
      { 
       playerTurn = 'x'; 
      } 

     } 
    } 
    // always have to return a value. 
    return true; 
} 
+0

'playerTurn'はここでは疑わしいですが、それはおそらくグローバル変数ではなくパラメータでなければなりません。 – Caleth

+0

N.B.ファイル全体を読むことは、ファイル全体を読むことと、残りの部分を何もしないことと区別できません。 – Caleth

+0

あなたが押されているならば、 'if(hasResult && board.checkOneBlank(row、column))'にif条件を変更し、代わりに 'hasResultとresult'を設定すると、' bool hasResult = false、result = true;戻るの – Caleth

関連する問題