如何修复stackOverFlow错误

时间:2015-11-21 02:50:09

标签: java stack-overflow

该程序最初工作正常,但在第六次转弯后,它返回stackOverFlow错误。我不能让程序工作,除非play方法调用自己,直到用户或计算机获胜。我该如何解决这个问题?

TicTacToeTester

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

}

1 个答案:

答案 0 :(得分:1)

  

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

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

  

如何解决此问题?

一般来说,有两种方法。

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

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

但是,问题可能是由导致无限递归的错误引起的。如果是这种情况,那么更大的筹码将无法提供帮助。

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

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