2013-09-01 68 views
1

我有一个允许2个玩家玩TicTacToe的程序。在每个玩家进行移动之后,它应该在当时显示棋盘并返回一个称为状态的激励,以显示玩家是否应该继续,如果玩家赢了,或者是平局。但是,该算法要么返回一个StackOverflowError,要么继续输入。这是我使用的算法。确定TicTacToe游戏状态的算法?

 //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) 

如此反复

回答

2

你的问题是你有代码重复调用自己创建一个永无止境的循环。例如,如果方法A()具有调用方法B()的代码,但在B()中有代码调用A(),那么随着A()调用B(),代码将无限运行,然后调用A()再次循环重复。 StackOverflow错误往往表明这一点。

在你的情况,那是因为你的函数gameStatus()(其中,我认为是你贴的代码的第一部分),在该行Status status = gameStatus();

尝试通过状态再次呼吁printStatus(),然后调用gameStatus()作为printStatus中的一个参数,如printStatus(2,Status.WIN);,而不是尝试在printStatus中获得gameStatus的返回值。

0

有没有出现在你发布什么会导致的StackOverflowError(除非你正在做的事情的任何代码真的很奇怪 in 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; 
    } 
} 

您也可以只检查X0是否占有一席之地,你已经想通了,有人赢了后简化您的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之间(其中两个只在玩家赢了时才会发生)。

+0

我修改了代码来简化我的算法,但在输入第一个玩家坐标后,我仍然立即得到了一个StackOverflowError。我添加了printStatus方法和一些错误 – tserran