使用扫雷的递归算法无法按预期工作

时间:2015-05-10 23:14:16

标签: algorithm recursion minesweeper

我正在尝试理解递归,因此试图为扫雷游戏编写递归函数。我的程序没有游戏界面,因为它只是为了理解。

以下是我的理解:

我有一个给定大小的网格,其中将填充数字。为简单起见,我假设0代表我的,网格中的空单元格将用数字9表示。这是我的网格:
 0 1 9 9 9
 1 1 9 9 9
 9 9 9 9 9
 9 9 9 1 1
 9 9 9 1 0

这是我的递归算法。我认为我已经放入了正确的边界条件,但似乎是进入无限递归的算法:

基本情况:
如果网格坐标小于0,则x <0或y <0或x> 0。 grid.length-1或y&gt; grid.length-1
返回
ELSE
如果网格显示的数字不是0或9,则显示数字,即grid [x] [y]!= 0&amp;&amp;格[X] [Y]!= 9
否则如果网格显示0表示它是我的,则显示游戏结束 否则
  所有周围8个细胞的递归情况,因为所有周围细胞都可以安全打开

以下是一些代码,用于显示我在算法中列出的内容:

public static void playGame(int[][]grid, int x, int y){
        if(x > grid.length-1 || x <0 || y > grid.length-1 || y<0){
            return;
        }else{
            if(grid[x][y] !=0 && grid[x][y]!=9){
                //means this is a valid number to display to user
                System.out.println("opening cell:"+x+","+y+" "+grid[x][y]);
            }else if(grid[x][y] == 0){
                System.out.println("Game over!");
                //might want to show all mine locations
            }else{
                //all 8 cells are safe to open 
                playGame(grid,x-1,y-1); //left
                playGame(grid,x,y-1); //up
                playGame(grid,x,y+1);//down
                playGame(grid,x+1,y);//diagonal
                playGame(grid,x-1,y); //diagonal
                playGame(grid,x+1,y-1);//diagonal
                playGame(grid,x+1,y+1);//right
                playGame(grid,x-1,y+1);//diagonal

            }
        }
    }

我将单元格传递为2,2,它给了我java.lang.StackOverflowError。 有人可以在这里指导我。我对算法或递归的理解是否存在问题,或者我可能已经引入了一些错误。我无法发现问题。

1 个答案:

答案 0 :(得分:1)

在一般建议之后,在调试器中逐步执行代码不能按预期工作,总是一个好主意。查看给定的具体问题。

您的实施问题似乎是,打开空白字段,您不会跟踪已访问过的字段。导致在相同的两个字段之间递归越来越深的问题。

根据您示例中的数据,我使用交叉x标记实际访问的字段,并在顶部显示调用堆栈以向您显示我正在谈论的内容。

让我们从你的emample中给出的单元格2,2开始:

playGame(grid, 2, 2)
0 1 9 9 9
1 1 9 9 9
9 9 x 9 9
9 9 9 1 1
9 9 9 1 0

代码最终会调用  playGame(grid,x,y-1); //up

playGame(grid, 2, 2)
  playGame(grid, 2, 1)
0 1 9 9 9
1 1 x 9 9
9 9 9 9 9
9 9 9 1 1
9 9 9 1 0

我们将再次访问playGame(grid,x,y-1); //up

playGame(grid, 2, 2)
  playGame(grid, 2, 1)
    playGame(grid, 2, 0)
0 1 x 9 9
1 1 9 9 9
9 9 9 9 9
9 9 9 1 1
9 9 9 1 0

由于此字段仍为空,我们会再次调用playGame(grid,x,y-1); //up

playGame(grid, 2, 2)
  playGame(grid, 2, 1)
    playGame(grid, 2, 0)
      playGame(grid, 2, -1)

这次我们将返回,playGame(grid,x,y+1); //down将被调用。

playGame(grid, 2, 2)
  playGame(grid, 2, 1)
    playGame(grid, 2, 0)
     playGame(grid, 2, 1)
0 1 9 9 9
1 1 x 9 9
9 9 9 9 9
9 9 9 1 1
9 9 9 1 0

由于此字段为空,因此调用playGame(grid,x,y-1); //up将是下一步

playGame(grid, 2, 2)
  playGame(grid, 2, 1)
    playGame(grid, 2, 0)
      playGame(grid, 2, 1)
        playGame(grid, 2, 0)
0 1 x 9 9
1 1 9 9 9
9 9 9 9 9
9 9 9 1 1
9 9 9 1 0

从现在开始,我们将重复已经观察到的步骤,直到所有堆栈空间用完为止:

playGame(grid, 2, 2)
  playGame(grid, 2, 1)
    playGame(grid, 2, 0)
      playGame(grid, 2, 1)
        playGame(grid, 2, 0)
          playGame(grid, 2, 1)
            playGame(grid, 2, 0)
               ...