繁体   English   中英

如何修复stackOverFlow错误

[英]How to fix stackOverFlow error

该程序一开始运行良好,但在第六轮之后,它返回一个 stackOverFlow 错误。 除非播放方法调用自身,否则我无法使程序运行,直到用户或计算机获胜。 我该如何解决这个问题?

井字游戏测试仪

public class TicTacToeTester {

public static void main(String[] args)
{

String name = JOptionPane.showInputDialog("Welcome to the Tic-Tac-Toe game! What is your name?");
JOptionPane.showMessageDialog(null, "Nice to meet you, " + name + ", we'll now decide whose turn it is");

//decide who will go first
Random r = new Random();  
int x = r.nextInt(2);
String turn = " ";
char mark = ' ';

if (x == 0)
{
  JOptionPane.showMessageDialog(null, "The computer will go first");
  turn = "Computer";
  mark = 'O';
}
else
{
  JOptionPane.showMessageDialog(null, "Congrats! You will go first");
  turn = "Player";
  mark = 'X';
}

//create game
TicTacToe game = new TicTacToe(name, turn);
game.play(turn, mark);

}
}

井字游戏

public class TicTacToe {

private String name;
private char[][] board = new char[3][3]; 
Random r = new Random(); 
private static char mark;
private static String turn;

//constructor 
public TicTacToe(String name, String turn)
{
   this.name = name;
   this.turn = turn;
   initializeBoard();
}


public void initializeBoard() {  

    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            board[i][j] = '-';
        }
    }
}

public void printBoard()
{
  JOptionPane.showMessageDialog(null, board[0][0] + "|" + board[0][1] + "|" +  board[0][2] + "\n"   
                                  + board[1][0] + "|" + board[1][1] + "|" + board[1][2] + "\n"
                                  + board[2][0] + "|" + board[2][1] + "|" + board[2][2] );  
}

public boolean isFull()
{
 boolean isFull = true;

    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            if (board[i][j] == '-') {
                isFull = false;
            }
        }
    }
    return isFull;
}

 public boolean isEmpty(int row, int col)
 {
   if ((row >= 0 && row < 3) &&
     (col >= 0 && col < 3) &&
      (board[row][col] == '-'))
   return true;
   else
   return false;
 }

public void play(String turn, char mark)
{

 if (turn.equals("Player") && !checkForWinner() && !isFull())
 {
    mark = 'X';
   JOptionPane.showMessageDialog(null, "Think about where you would like to place your mark");
   int row = Integer.parseInt (JOptionPane.showInputDialog("Type row")) - 1;
   int col = Integer.parseInt (JOptionPane.showInputDialog("Type column")) - 1;

   if (isEmpty(row,col) == true)
   {
        board[row][col] = mark;
        printBoard();

        if (checkForWinner() == true)
          JOptionPane.showMessageDialog(null, "Congrats, you won!");
        else if (isFull() == true)
          JOptionPane.showMessageDialog(null, "We have a tie!");
        else
        {
         JOptionPane.showMessageDialog(null, "It's the computer's turn");
         play("Computer", 'O');
        }
       }

   else 
   {
     JOptionPane.showMessageDialog(null, "That slot is already occupied or it does not exist. Please show a new one");
     play("Player", 'X');
  }
}

 else if (turn.equals("Computer") && !checkForWinner() && !isFull())
 {
   mark = 'O';

   int col = r.nextInt(2);
   int row = r.nextInt(2);

       if (isEmpty(row,col) == true)
      {
        board[row][col] = mark;
        printBoard();

        if (checkForWinner() == true)
          JOptionPane.showMessageDialog(null, "Sorry, the computer won!");
        else if (isFull() == true)
          JOptionPane.showMessageDialog(null, "We have a tie!");
        else
        {
         JOptionPane.showMessageDialog(null, "It's your turn");
         play("Player", 'X');
        }
      }

      else 
        play("Computer", 'X');
    }
  }   


public boolean checkForWinner()
{
  return (checkRows() || checkCols() || checkDiagonals());
}

private boolean checkRows() {
    for (int i = 0; i < 3; i++) {
        if (checkRowCol(board[i][0], board[i][1], board[i][2]) == true) {
            return true;
        }
    }
    return false;
 }


private boolean checkCols() {
    for (int i = 0; i < 3; i++) {
        if (checkRowCol(board[0][i], board[1][i], board[2][i]) == true) {
            return true;
        }
    }
    return false;
}


private boolean checkDiagonals() {
    return ((checkRowCol(board[0][0], board[1][1], board[2][2]) == true) || (checkRowCol(board[0][2], board[1][1], board[2][0]) == true));
}

// Check to see if all three values are the same (and not empty) indicating a win.
private boolean checkRowCol(char c1, char c2, char c3) {
    return ((c1 != '-') && (c1 == c2) && (c2 == c3));
}

}

除非播放方法调用自身,否则我无法使程序运行,直到用户或计算机获胜。

我会对此提出异议。 任何使用递归的程序都可以转换为使用循环的等效程序。

我该如何解决这个问题?

一般来说,有两种方法。

  • 重写程序以使用循环而不是递归。 这是(IMO)更好的解决方案。

  • 使用更大的堆栈。 例如java -Xss 10m ...将使用 10Mbyte 堆栈运行您的应用程序。

但是,该问题可能是由导致无限递归的错误引起的。 如果是这种情况,那么更大的堆栈将无济于事。

事实上,我怀疑这里可能就是这种情况,因为在整个棋盘被填满之前,井字棋游戏应该只递归到 9 的深度……然后游戏结束。 对于默认的 Java 堆栈大小,9 级递归应该没问题。

所以,如果你想坚持使用递归算法,那么你需要仔细分析算法的递归模式和终止条件,并检查你是否正确实现了它们。 (有太多的代码不能指望我们中的一个人为您完成这项工作......)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM