所以我正在用 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
是一个数组,用于存储哪些方 block 已经被处理过,以防止再次处理它们。
这个函数应该是,当点击一个方 block 时,显示它附近的地雷数量并将其写入单元格。然后,它检查其周围的每个方 block ,如果该方 block 尚未处理(如果它不在 revealed
数组中),则函数 doSquare()
再次运行。如果该方格旁边有任何地雷,则该函数不会从该方格“扩散”。
我收到错误:超出最大调用堆栈大小。但该函数在到达有地雷的方格时会停止“传播”,并且也不会在已经被处理的方格上运行。所以我希望能解释一下为什么会发生这种情况。
最佳答案
我认为问题在于“revealed”是在您的函数内部定义的。这意味着每次调用该函数时,都会在本地为该函数创建一个新的“显示”。因此,周围没有地雷的方格将调用相邻方格的 doSquare,该方格又可能对原始方格调用 doSquare。但是,doSquare 不会记住它已经检查过这个方 block ,因为为此调用创建了新的本地版本“revealed”。
解决方案:
要么将“revealed”作为参数传递给 doSquare,以便所有调用都使用相同的变量(即 function doSquare(x, y, Revealed){...
,将初始调用设为 doSquare(x, y, []);
,或者在 doSquare 之外声明“显示”,并在每次您想要检查地雷时将其清空。
关于javascript - 扫雷游戏 - 超出最大调用堆栈边,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16132809/