2013-04-21 55 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

相关问题