扫雷艇stackoverflower

时间:2014-07-06 16:48:10

标签: java recursion stack-overflow minesweeper

我正在为扫雷编写一种方法,如果那里没有我的话,就会打开一个单元格。如果地雷旁边没有相邻的单元格,它会打开周围没有地雷的单元格。我经常有这个错误:

线程中的异常" AWT-EventQueue-0" java.lang.StackOverflowError的 这是我的源代码:

public void open(int row, int col) {
    // row = vertical index of the matrix
    // col = horizontal index of matrix
    unclicked--;
    butt[row][col].setEnabled(false); // disable the called button 
    if (aray[row][col] !=0) // checks if there are no adjacent cells with an adjacent mine count >0
      butt[row][col].setText(Integer.toString(aray[row][col]));
    else{

      if(row < size-1){
        open(row+1, col);
        if(col<size-1)
          open(row+1, col+1);
        if(col>0)
          open(row+1, col+1);
      }
      if(row>0){
        if(col>0)
          open(row-1, col-1);
        if(col< size)
          open(row-1, col+1);
      }

      if(col<size-1)
        open(row, col+1);
      if(col>0)
        open(row, col-1);

      return;   
    }  
  }

非常感谢帮助

2 个答案:

答案 0 :(得分:1)

您的Open方法在某些情况下具有无限递归,这就是您获得StackOverflowError的原因。你的算法不会检查它是否已经处理过一个单元格,所以最终会一遍又一遍地调用相同的单元格,直到它吹掉堆栈。

考虑3 x 3网格的场景。在这个例子中size = 3。想象一下,第2行,第1列被点击,我们最终得到以下调用堆栈:

open(2,1) //initial call
//row = 2, col = 1
open(row-1,col-1) // as row>0 and col>0
//row = 1, col = 0
open(row+1, col) //as row < size-1
//row = 2, col = 0
open(row-1, col+1) //as row > 0 and col< size
//row = 1, col = 1
open(row+1, col) //as row < size-1
//row = 2, col = 1
open(2,1) //uh-oh, this is the initial call so we're going to overflow the stack.

显然,只有在每个调用aray[row][col] == 0时才会出现这种情况,否则else将不会执行,并且不会生成额外调用,但这只是代码无限重复的一个示例。 / p>

要解决此问题,您需要检查是否已处理当前单元格。正如@ Marco13在他的评论中指出的那样,您可以通过在方法的开头添加一个检查来查看该单元格是否已被禁用,因为这意味着已经为该单元格调用了该方法:if (!butt[row][col].isEnabled()) return;。 / p>

答案 1 :(得分:0)

太多的递归是你的问题。你的open函数被递归调用太多次并导致堆栈溢出。尝试在没有递归的情况下更改“其他”部分。它会是这样的(伪代码):

public void clean(int i, int j) {
    list = [(i,j)]
    while list.size() > 0:
        i, j = list.pop()
        /*
        Do stuff here:
        Add neighbours to list and unhide current i,j
         */
}