2013-04-21 48 views
0

所以我在JS上做了掃雷遊戲。掃雷遊戲 - 超過最大調用堆棧面

我有這樣的功能:

function doSquare(x, y) { //takes x,y coordinates of a square. checks and acts accordingly to what's around it 
       var revealed = []; 
       var size = board.length; 
       var mines = countAround(x,y); 
       table.rows[x].cells[y].innerHTML = mines; 



       if (mines === 0) { 
        for (var i=Math.max(0,x-1), l = Math.min(x+1, size-1); i<=l; i++) { 
         for (var j=Math.max(0, y-1), k = Math.min(y+1, size-1); j<=k; j++) { 
          if (x == i && y==j) {continue;} 
          if (revealed.indexOf(i+"."+j) === -1) { 
           doSquare(i, j); 
           revealed.push(i+"."+j); 
          } 
         } 
        } 
       } 


      } 

董事會的行列數相等。 countAround(x,y)返回(x,y)周圍地雷的數量; revealed是一個數組,存儲哪個方格已經處理,以防止再次處理它們。
這個函數應該是,當點擊一個正方形時,顯示它附近的地雷數量並將其寫入單元格。然後,它檢查周圍的每個方塊,如果該方塊尚未處理(如果它不在revealed數組中),則功能doSquare()再次運行。如果廣場旁邊有任何地雷,該功能不會從廣場「傳播」。

我收到一個錯誤:超出了最大調用堆棧大小。但是,這個功能在與礦井達成平方時停止「傳播」,也不會在已經被照顧的廣場上運行。所以我很想解釋爲什麼會發生這種情況。

+0

你的循環/遞歸運行我猜想,檢查你的條件和限制器 – Joseph 2013-04-21 15:31:00

回答

1

我認爲問題在於「揭示」是在你的函數內部定義的。這意味着每次調用該函數時,都會在本地爲該函數創建一個新的「顯示」。因此,周圍沒有地雷的廣場將爲相鄰的廣場調用doSquare,然後在原廣場上調用doSquare。但是,doSquare不會記得它已經檢查了這個方塊,因爲爲這個調用創建了一個新的「顯示」本地版本。

解決方案:

要麼通「揭示」作爲參數傳遞給doSquare因此所有呼叫使用相同的變量(即function doSquare(x, y, revealed){...,使得初始呼叫作爲doSquare(x, y, []);,或聲明「揭示」 doSquare的外部,並清空它每次你想檢查地雷

+0

準確地,我錯過了......每次函數運行時,'顯示'被重置爲一個空數組。 – frrlod 2013-04-21 15:46:55

相關問題