2012-05-04 11 views
1

まず、余分なクレジット宿題の一部ですので、私に答えを与えないでください。何が起こっているのか、私はどこに問題があるかもしれないか理解するのを手伝ってください。 Tic-Tac-Toeジェネレータで、プレイヤーに基づいて最良の動きを決定するためにゲームが再帰的に行われます。 (教授はXとOの代わりに白い 'W'と黒の 'B'を使用します)なぜ私の再帰は返されませんが、スタックオーバーフローで終わりますか?

私の主な再帰的方法は、TTTボードの入力位置に基づいて状態スコアを返します。 1であれば、それは引き分けで、そして場合、その位置から0を勝利に強制されます白-1黒はその位置から勝利を強制する場合:

public int stateScore(boolean whiteMove, int[] BestMove) { 
    return stateScore(whiteMove,BestMove,TTTBoard); 
} 

私の根底にある民間の再帰メソッドを呼び出します:

private int stateScore(boolean whiteMove, int[] BestMove,char[][] TestBoard) { 
    char [][] newTestBoard = new char [3][3]; 
    for(int rowVal = 0; rowVal < 3; rowVal++){ 
     for(int colVal = 0; colVal < 3; colVal++){ 
      newTestBoard[rowVal][colVal] = TestBoard[rowVal][colVal]; 
     } 
    } 

    int [] bestMove = new int [2]; 

    for(int rowVal = 0; rowVal < 3; rowVal++){ 
     for(int colVal = 0; colVal < 3; colVal++){ 
      if(isFull(newTestBoard) == true){ 
       return 0; 
      } 
      else if(newTestBoard[rowVal][colVal] == '-'){ 
       bestMove[0] = rowVal; 
       bestMove[1] = colVal; 

       //if boolean is white 
       if(whiteMove == true){ 
        newTestBoard = testEntry(rowVal,colVal,'W',newTestBoard); 
        if(threeInRow(newTestBoard) == 1){ 
         return 1; 
        } 
        else if(threeInRow(newTestBoard) == 0 && isFull(newTestBoard) == true){ 
         return 0; 
        } 
        else if(threeInRow(newTestBoard) == -1 && isFull(newTestBoard) == true){ 
         return -1; 
        } 
        else{ 
         return stateScore(!whiteMove,bestMove,newTestBoard); 
        } 
       } 
       //if boolean is black 
       else{ 
        newTestBoard = testEntry(rowVal,colVal,'B',newTestBoard); 
        if(threeInRow(newTestBoard) == -1){ 
         return -1; 
        } 
        else if(threeInRow(newTestBoard) == 0 && isFull(newTestBoard) == true){ 
         return 0; 
        } 
        else if(threeInRow(newTestBoard) == 1 && isFull(newTestBoard) == true){ 
         return 1; 
        } 
        else{ 
         return stateScore(!whiteMove,bestMove); 
        } 
       } 
      } 
     } 
    } 
    return 0; 
} 

whiteMoveのブール値は、白い移動の場合はtrue、黒の場合はfalseです。

public int threeInRow(char[][] TTTBoard){ 
    boolean whiteIs = false; 
    boolean blackIs = false; 
     //Horizontal? 
     char [] colChar = new char [3]; 
     for(int rowVal = 0; rowVal < 3; rowVal ++){ 
      for(int colVal = 0; colVal < 3; colVal++){ 
       colChar[colVal] = TTTBoard[rowVal][colVal]; 
      } 
      if(colChar[0] == colChar[1] && colChar[1] == colChar[2]){ 
       if(colChar[0] == 'W'){ 
        whiteIs = true; 
       } 
       if(colChar[0] == 'B'){ 
        blackIs = true; 
       } 
      } 
     } 

     //Vertical? 
     char [] rowChar = new char [3]; 
     for(int colVal = 0; colVal < 3; colVal ++){ 
      for(int rowVal = 0; rowVal < 3; rowVal++){ 
       rowChar[colVal] = TTTBoard[rowVal][colVal]; 
      } 
      if(rowChar[0] == rowChar[1] && rowChar[1] == rowChar[2]){ 
       if(rowChar[0] == 'W'){ 
        whiteIs = true; 
       } 
       else if(rowChar[0] == 'B'){ 
        blackIs = true; 
       } 
      } 
     } 

     //Diagonal 
      //topLeft to bottomRight 
      if(TTTBoard[0][0] == TTTBoard[1][1] && TTTBoard[1][1] == TTTBoard[2][2]){ 
       if(TTTBoard[0][0] == 'W'){ 
        whiteIs = true; 
       } 
       else if(TTTBoard[0][0] == 'B'){ 
        blackIs = true; 
       } 
      } 

      //topRight to bottomLeft 
      if(TTTBoard[0][2] == TTTBoard[1][1] && TTTBoard[1][1] == TTTBoard [2][0]){ 
       if(TTTBoard[1][1] == 'W'){ 
        whiteIs = true; 
       } 
       else if(TTTBoard[1][1] == 'B'){ 
        blackIs = true; 
       } 
      } 


    //Return Vals 
    if(whiteIs == true && blackIs == true){ 
     return 0; 
    } 
    else if(blackIs == true && whiteIs == false){ 
     return -1; 
    } 
    else if(blackIs == false && whiteIs == true){ 
     return 1; 
    } 
    else if(blackIs == false && whiteIs == false){ 
     return 0; 
    } 
    else{ 
     return 0; 
    } 

} 

とtestEntry:関数内のセカンダリ方法はthreeInRowが含ま

public char[][] testEntry(int row,int col,char newChar, char[][] TestBoard){ 

    char [][] returnBoard = new char[3][3]; 
    for(int rowVal = 0; rowVal < 3; rowVal++){ 
     for(int colVal = 0; colVal < 3; colVal++){ 
      returnBoard[rowVal][colVal] = TestBoard[rowVal][colVal]; 
     } 
    } 
    returnBoard[row][col] = newChar; 
    return returnBoard; 

} 

スタックオーバーフローがどこから来ている私は理解していません。私のリターンはすべてのケースをカバーし、私の方法は適切なリターンを持っているようです。私は再帰を伴うforループを使用したことはありませんでした。また、type [] name = name(同じタイプ)はうまくいきませんよね。だからこそ私はforループをやったのです。

+0

外にこれを移動しないのはなぜ、それを最小限にしてください:両方の枝は同じ結果を返しますすぐに問題をカバーする最小のコンパイル可能なスナップです。 – amit

+0

申し訳ありませんカンタンレジスト:奇妙なゲーム。唯一の勝利の動きはプレーしないことです。チェスの素敵な試合はいかがですか? – flolo

+0

私はここ2番目のMarko、Zach - あなたは6つの前の質問を見直すために数分かかりますか?彼らはすべて答えを持っています(回答が役に立たなかったと思われる場合は、特定のケースで受諾することはできません)。 – halfer

答えて

4

あなたの黒い枝であなたのリターンは間違っています。

あなたは再帰を再起動し

return stateScore(!whiteMove,bestMove); 

を返します。

  • があなたのブール値を修正:

    if(whiteMove == true) -> if (whiteMove) 
    
  • クラスの大文字の使用、変数のためのlowerCamelCaseあなたは

    return stateScore(!whiteMove,bestMove,newTestBoard); 
    

    ヒントを返すようにしたいです。

  • ifブランチに戻ると、elseを必要としません。

    if (condition) { 
        ... 
        return ...; 
    } 
    else 
    { 
        ... 
    } 
    

    書く方が良いです:

    if (condition) { 
        ... 
        return ...; 
    } 
    ... 
    

    は低くネスト保持し、従うことが、コードが容易になり代わりの

  • リファクタリング共通のコード:

    return stateScore(!whiteMove,bestMove,newTestBoard); 
    

    これは、多くのコードです(whiteMove)の場合

+0

ありがとう、非常にありがとう。 –

+0

あなたはどこにいましたか? –

0

スタックトレースをポストしますが、私はstateScoreを無限再帰呼び出しに再帰的に呼び出すと賭けるでしょう。

関連する問題