所以我在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 :(得分:1)
我认为问题是'揭示'是在你的功能中定义的。这意味着每次调用函数时,都会为函数在本地创建一个新的“透露”。因此,围绕它的没有地雷的正方形将为相邻的正方形调用doSquare,这可以在原始正方形上调用doSquare。但是,doSquare将不记得它已经检查了这个方块,因为为此次调用创建了一个新的“透露”本地版本。
解决方案:
将'reveal'作为doSquare的参数传递,以便所有调用使用相同的变量(即function doSquare(x, y, revealed){...
,将初始调用设为doSquare(x, y, []);
,或在doSquare之外声明'显示',并清空它每次你想检查地雷。