我有一个允许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)
等等
答案 0 :(得分:2)
你的问题是你有重复调用自己的代码创建一个永无止境的循环。例如,如果方法A()具有调用方法B()但在B()内的代码,则有代码调用A(),然后代码将无限运行,因为A()调用B(),然后调用A()再次循环重复。 StackOverflow错误通常表明这一点。
在你的情况下,这是因为你的函数gameStatus()
(我假设它是你发布的代码的第一部分),调用printStatus()
,然后在{{1}行再次调用gameStatus() 1}}
尝试将状态作为参数传递给printStatus,如Status status = gameStatus();
,而不是尝试在printStatus中返回gameStatus。
答案 1 :(得分:0)
在您发布的内容中似乎没有任何代码会导致StackOverflowError(除非您在printStatus
中执行非常奇怪的)。导致该错误的错误必须在您的代码中的其他位置。所以,不幸的是,除非你发布更多代码,否则我无能为力。
然而,这里有两件事我注意到你可以使用一些改进。首先,(你实现它的方式)你不需要嵌套的for
循环。以for (int j = 0; j < 1; j++) {
和for (int i = 0; i < 1; i++) {
开头的循环不是必需的,它们会导致错误,因为它们会生成只检查两个框的检查,而不是连续三个。您可以通过简单地消除这些循环来简化它们。 (我还修改了您的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
或0
是否占用空间来简化您的if语句。所以,例如,而不是做
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])
只执行一次,第二个语句if (board[0][0] == 'X')
仅在有人赢得对角线时执行。在您的实现中,将运行if (board[0][0] == 'X')
的第一次检查,然后是内部if语句,或者它将执行第二次玩家检查if (board[0][0] == 'O')
,然后执行内部检查。通过这种方式,你的代码必须在2到3个不同的语句之间运行,而在我的代码中,它在1到2之间(其中两个仅在玩家获胜时发生)。