2014-07-06 100 views
1

我正在寫一個掃雷的方法,打開一個單元,如果沒有礦在那裏。如果礦旁沒有相鄰的單元格,則會打開沒有地雷的單元格周圍的單元格。我經常有這樣的錯誤:掃雷stackoverflowerror

異常在線程 「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; 
    } 
    } 

幫助,將不勝感激

+0

您是否嘗試過調試? – Jens

+0

看起來像可能的無限遞歸。 – paisanco

+0

遞歸應該如何結束?可能會插入'if(!butt [row] [col] .isEnabled())return;'作爲此方法的第一行。 – Marco13

回答

0

太多遞歸是你的問題。您的開放函數遞歸調用次數過多並導致堆棧溢出。嘗試改變你的「其他」部分,而不用遞歸。這將是這樣的(僞代碼):

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 
     */ 
} 
0

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;