该程序最初工作正常,但在第六次转弯后,它返回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));
}
}
答案 0 :(得分:1)
除非播放方法调用自身直到用户或计算机获胜,否则我无法使程序正常工作。
我会对此提出质疑。任何使用递归的程序都可以转换为使用循环的等效程序。
如何解决此问题?
一般来说,有两种方法。
重写程序以使用循环而不是递归。这是(IMO)更好的解决方案。
使用更大的堆栈。例如,java -Xss 10m ...
将以10Mbyte堆栈运行您的应用程序。
但是,问题可能是由导致无限递归的错误引起的。如果是这种情况,那么更大的筹码将无法提供帮助。
事实上,我怀疑这可能就是这种情况,因为在整个棋盘被填满之前,一个井字游戏应该只能递归到9的深度......游戏结束。对于默认的Java堆栈大小,9级递归应该没问题。
因此,如果您想坚持使用递归算法,那么您需要仔细分析算法的递归模式和终止条件,并检查您是否已正确实现它们。 (有太多代码要求我们中的一个人为你做这项工作......)