我目前正在学习java,我想编写扫雷编码。但我有一个问题。当我揭露一个空白案例时,我想要揭露所有周围的案件,等等。我知道我必须使用递归方法,但每次我揭示一个空白案例时我都会出错。你能解释一下我应该用这个算法的逻辑吗?谢谢。
以下是我的2个方法(countBomb和revealBlank):
public boolean InRange(int x, int y){
if((x>=0 && x<l && y>=0 && y<h)) return true;
else return false;
}
public void revealBlank(int x, int y) {
for (int i = x-1; i <= x+1; i++) {
for (int j = y-1; j <= y+1; j++) {
if(ispressed[i][j]==false && i!=x && j!=y)
countBomb(i,j); //line 108
}
}
}
public void countBomb(int x, int y) {
ispressed[x][y]=true;
butarray[x][y].setBackground(Color.WHITE); //line 116
if(bomb[x][y]==true) {
butarray[x][y].setIcon(mineicn);
}
if(bomb[x][y]==false) {
countbomb=0;
for (int i = x-1; i <= x+1; i++) {
for (int j = y-1; j <= y+1; j++) {
if(InRange(i,j)==true) {
if(bomb[i][j]==true) {
countbomb++;
}
}
}
}
switch (countbomb) {
case 0:
revealBlank(x,y); //line 134
break;
case 1:
butarray[x][y].setForeground(Color.CYAN);
butarray[x][y].setFont(new Font("Dialog", Font.PLAIN, 25));
break;
case 2:
butarray[x][y].setForeground(Color.GREEN);
butarray[x][y].setFont(new Font("Dialog", Font.PLAIN, 25));
break;
case 3:
butarray[x][y].setForeground(Color.RED);
butarray[x][y].setFont(new Font("Dialog", Font.PLAIN, 25));
break;
case 4:
butarray[x][y].setForeground(Color.BLUE);
butarray[x][y].setFont(new Font("Dialog", Font.PLAIN, 25));
break;
case 5:
butarray[x][y].setForeground(Color.ORANGE);
butarray[x][y].setFont(new Font("Dialog", Font.PLAIN, 25));
break;
case 6:
butarray[x][y].setForeground(Color.YELLOW);
butarray[x][y].setFont(new Font("Dialog", Font.PLAIN, 25));
break;
case 7:
butarray[x][y].setForeground(Color.MAGENTA);
butarray[x][y].setFont(new Font("Dialog", Font.PLAIN, 25));
break;
case 8:
butarray[x][y].setForeground(Color.PINK);
butarray[x][y].setFont(new Font("Dialog", Font.PLAIN, 25));
break;
default:
break;
}
if(countbomb > 0)butarray[x][y].setText("" + countbomb);
}
}
我的错误是:
Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError
at java.awt.Component.firePropertyChange(Unknown Source)
at java.awt.Component.setBackground(Unknown Source)
at javax.swing.JComponent.setBackground(Unknown Source)
at packMinesw.mineswpr.countBomb(mineswpr.java:116)
at packMinesw.mineswpr.revealBlank(mineswpr.java:108)
at packMinesw.mineswpr.countBomb(mineswpr.java:134)
at packMinesw.mineswpr.revealBlank(mineswpr.java:108)
at packMinesw.mineswpr.countBomb(mineswpr.java:134)
at packMinesw.mineswpr.revealBlank(mineswpr.java:108)
at packMinesw.mineswpr.countBomb(mineswpr.java:134)
并且不断重复。
编辑: 我发现一个错误导致代码不检查revealBlank()方法中的周围单元格,但它仍然无法正常工作。
答案 0 :(得分:-1)
我假设你得到一个StackOverflowError引起的方法是让这些方法一直调用,让堆栈增长到无穷大。在countBomb() - 方法中,你不应该对结果做出反应,这意味着它计算的炸弹数量。只需让它返回该数字:
public int countBomb(int x, int y) {
ispressed[x][y]=true;
butarray[x][y].setBackground(Color.WHITE);
if(bomb[x][y]==true) {
butarray[x][y].setIcon(mineicn);
return -1; //or any other value indicating that the user clicked on a bomb
}
if(bomb[x][y]==false) {
countbomb=0;
for (int i = x-1; i <= x+1; i++) {
for (int j = y-1; j <= y+1; j++) {
if(InRange(i,j)==true) {
if(bomb[i][j]==true) {
countbomb++;
}
}
}
}
return countbomb;
}
}
然后你需要在你的revealBlank() - 方法中对那个结果做出反应,这意味着你应该在那里给它们着色以指示炸弹的数量(如果你这样做,重命名方法!)你还应该揭示周围如果结果是0,那么为了显示更远的空白案例,我建议你将点击的案例添加到一个ArrayList并在其坐标上调用countBomb()方法。如果删除调用该方法的每个案例,最终将显示连接到最初单击的一个空白案例,并再次清空ArrayList。
我知道这个描述相当普遍,但我不想通过提供太多代码来破坏你编写算法的乐趣。如果再次陷入困境,请寻求更多帮助。