[英]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.