1

2 人のプレーヤーが TicTacToe をプレイできるようにするプログラムがあります。各プレイヤーが移動した後、その時点でボードを表示し、プレイヤーが勝った場合、または引き分けの場合に、プレイヤーが続行するかどうかを示す Status と呼ばれる列挙を返す必要があります。ただし、アルゴリズムは StackOverflowError を返すか、入力を続行します。これが私が使用したアルゴリズムです。

       //Checks for winner by rows
       for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 1; j++) {
            if (board[i][j] == 'X') {
                if (board[i][j] == board[i][0 + 1] && board[i][j] == board[i][0 + 2]) {
                    printStatus(1);
                    return Status.WIN;
                } else {
                    return Status.CONTINUE;
                }
            } else if (board[i][j] == 'O') {
                if (board[i][j] == board[i][0 + 1] && board[i][j] == board[i][0 + 2]) {
                    printStatus(2);
                    return Status.WIN;
                } else {
                    return Status.CONTINUE;
                }
            }
        }
    }
    //Checks for winner by columns
    for (int i = 0; i < 1; i++) {
        for (int j = 0; j < 3; j++) {
            if (board[i][j] == 'X') {
                if (board[i][j] == board[0 + 1][j] && board[i][j] == board[0 + 2][j]) {
                    printStatus(1);
                    return Status.WIN;
                } else {
                    return Status.CONTINUE;
                }
            } else if (board[i][j] == 'O') {
                if (board[i][j] == board[0 + 1][j] && board[i][j] == board[0 + 2][j]) {
                    printStatus(1);
                    return Status.WIN;
                } else {
                    return Status.CONTINUE;
                }
            }
        }

    }
    //This group of if statements boards for winner diagnolly
    if (board[0][0] == 'X') {
        if (board[0][0] == board[1][1] && board[0][0] == board[2][2]) {
            printStatus(1);
            return Status.WIN;
        } else {
            return Status.CONTINUE;
        }
    }else if (board[0][0] == '0') {
        if (board[0][0] == board[1][1] && board[0][0] == board[2][2]) {
            printStatus(1);
            return Status.WIN;
        } else {
            return Status.CONTINUE;
        }
    }
    if (board[0][2] == 'O') {
        if (board[0][2] == board[1][1] && board[0][2] == board[2][0]) {
            printStatus(1);
            return Status.WIN;
        } else {
            return Status.CONTINUE;
        }
    }else if (board[0][2] == 'X') {
        if (board[0][2] == board[1][1] && board[0][2] == board[2][0]) {
            printStatus(1);
            return Status.WIN;
        } else {
            return Status.CONTINUE;
        }

    }

これが printStatus メソッドです。

private void printStatus(int player) {
    Status status = gameStatus();
    if (status == Status.DRAW) {
        System.out.println("The game has ended in a draw.");
        System.exit(0);
    } else if (status == Status.WIN) {
        System.out.println("Player " + player + " has won the game.");
        System.exit(0);
    } else if (status == Status.CONTINUE) {
        System.out.println("The game continues.");
        play();
    }

} 

エラーは次のとおりです。

Exception in thread "main" java.lang.StackOverflowError
at tictactoe.TicTacToe.gameStatus(TicTacToe.java:86)
at tictactoe.TicTacToe.printStatus(TicTacToe.java:69)
at tictactoe.TicTacToe.gameStatus(TicTacToe.java:92)
    at tictactoe.TicTacToe.printStatus(TicTacToe.java:69)
at tictactoe.TicTacToe.gameStatus(TicTacToe.java:92)
at tictactoe.TicTacToe.printStatus(TicTacToe.java:69)

などなど

4

2 に答える 2

2

問題は、自分自身を繰り返し呼び出して終わりのないサイクルを作成するコードがあることです。たとえば、メソッド A() にメソッド B() を呼び出すコードがあり、B() 内に A() を呼び出すコードがある場合、A() が B() を呼び出し、次に B() を呼び出すため、コードは無限に実行されます。 A() 再びサイクルが繰り返されます。多くの場合、StackOverflow エラーはこれを示しています。

あなたの場合、それはあなたの関数gameStatus()(あなたが投稿したコードの最初の部分だと思います)が を呼び出しprintStatus()、それが行で gameStatus() を再度呼び出すためですStatus status = gameStatus();

printStatus(2,Status.WIN);printStatus 内で gameStatus の戻り値を取得しようとするのではなく、 のように printStatus の引数としてステータスを渡してみてください。

于 2013-09-02T04:38:54.367 に答える
0

あなたが投稿したものには、StackOverflowError を引き起こすコードはないようです (で本当に奇妙なprintStatusことをしていない限り)。その原因となっているエラーは、コード内の別の場所にある必要があります。したがって、残念ながら、さらにコードを投稿しない限り、私は助けることができません.

ただし、改善できる点が 2 つあります。forまず、(これを実装している方法で) ネストされたループは必要ありません。for (int j = 0; j < 1; j++) {、および で始まるループfor (int i = 0; i < 1; i++) {は不要であり、3 つのボックスが連続してチェックされるのではなく、2 つのボックスのみがチェックされるチェックが生成されるため、エラーが発生します。これらのループを単純に排除することで、それらを単純化できます。(私はあなたの声明も修正ifしました。詳細については以下を参照してください)。

    //Checks for winner by rows
for (int i = 0; i < 3; i++) {
    if (board[i][j] == board[i][0 + 1] && board[i][j] == board[i][0 + 2]) { //Check if one player has matched a row
        if (board[i][j] == 'X') { //Then check which player won
            printStatus(1);
        }
        else{
            printStatus(2);
        }
        return Status.WIN;
    } else {
        return Status.CONTINUE;
    }
}

誰かが勝ったことがわかった後、スペースを占有しているXかどうかのみをチェックすることで、if ステートメントを簡素化することもできます。0したがって、たとえば、代わりに

if (board[0][0] == 'X') {
        if (board[0][0] == board[1][1] && board[0][0] == board[2][2]) {
            printStatus(1);
        }
        //More code here
}
else if (board[0][0] == 'O') {
        if (board[0][0] == board[1][1] && board[0][0] == board[2][2]) {
            printStatus(1);
        }
        //More code here
}

次のように変更することで、コードを単純化できます。

if (board[0][0] == board[1][1] && board[0][0] == board[2][2]) { //Check if first diagonal is complete
        if (board[0][0] == 'X') { //Check who won
            printStatus(1);
        }
        else{
            printStatus(1);
        }
        return Status.WIN;
    } else {
        return Status.CONTINUE;
    }

このように、ステートメントif (board[0][0] == board[1][1] && board[0][0] == board[2][2])は 1 回だけ実行され、2 番目のステートメント はif (board[0][0] == 'X')、誰かが対角線に勝った場合にのみ実行されます。あなたの実装では、 の最初のチェックif (board[0][0] == 'X')が実行され、次に内部の if ステートメントが実行されるか、2 番目のプレイヤー チェックが実行されif (board[0][0] == 'O')、次に内部のチェックが実行されます。このように、コードは 2 から 3 の異なるステートメントの間で実行する必要がありますが、私の場合は 1 から 2 の間です (2 つはプレーヤーが勝った場合にのみ発生します)。

于 2013-09-01T04:20:45.120 に答える