1

首先,这是额外功课的一部分,所以请不要给我答案。请帮助我了解我可能对正在发生的事情有什么问题。它是一个井字游戏生成器,游戏在其中递归地根据玩家确定最佳移动。(教授用白色'W'和黑色'B'代替X和O)

我的主要递归方法根据 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 的布尔值如果是白方走,则为真,如果是黑方走,则为假。函数中的辅助方法包括threeInRow:

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

}

和测试入口:

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 循环。

4

2 回答 2

4

在你的黑色分支中,你的回报是错误的。

你回来

return stateScore(!whiteMove,bestMove);

重新开始递归。你想回来

return stateScore(!whiteMove,bestMove,newTestBoard);

提示:

  • 修复你的布尔值:

    if(whiteMove == true) -> if (whiteMove)
    
  • 对类使用大写,对变量使用小写。

  • 如果你在 if 分支中返回,那么你不需要 else。

    代替:

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

    最好写:

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

    保持较低的嵌套并使代码更易于遵循。

  • 重构公共代码:两个分支返回相同的结果:

    return stateScore(!whiteMove,bestMove,newTestBoard);
    

    为什么不把它移到 if (whiteMove) 之外

于 2012-05-04T21:25:21.313 回答
0

发布堆栈跟踪,但我敢打赌,当您stateScore递归调用时,您将获得无限递归。

于 2012-05-04T21:22:06.680 回答