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

线程“ 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;
    }
  }


帮助将不胜感激

最佳答案

您的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将不会执行,并且不会生成额外的调用,但这只是代码无限重复的一个示例。

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

关于java - 扫雷stackoverflowerror,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24598121/

10-11 00:19