簡體   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