【问题标题】:Minesweeper game - Maximum call stack side exceeded扫雷游戏 - 超出最大调用堆栈端
【发布时间】:2013-04-14 12:15:34
【问题描述】:

所以我在用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() 会再次在它上面运行。如果正方形旁边有地雷,该功能将不会从正方形“传播”。

我收到一个错误:超出了最大调用堆栈大小。但是该功能在到达一个有地雷的广场时停止它的“传播”,并且也不会在已经处理好的广场上运行。所以我想解释一下为什么会发生这种情况。

【问题讨论】:

  • 我猜你的循环/递归跑掉了。检查您的条件和限制条件。

标签: javascript recursion size stack max


【解决方案1】:

我认为问题在于您的函数内部定义了“显示”。这意味着每次调用该函数时,都会在本地为该函数创建一个新的“显示”。因此,一个周围没有地雷的方格会为相邻方格调用 doSquare,而相邻方格可能又会在原始方格上调用 doSquare。但是,doSquare 不会记住它已经检查过这个方格,因为为此调用创建了一个新的本地版本的 'revealed'。

解决方案:

要么将'revealed'作为参数传递给doSquare,因此所有调用都使用相同的变量(即function doSquare(x, y, revealed){...,初始调用为doSquare(x, y, []);,或者在doSquare之外声明'revealed',每次你都清空它希望检查地雷。

【讨论】:

  • 没错。我错过了……每次函数运行时,“已显示”都会重置为空数组。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-24
  • 2015-12-29
  • 2017-12-27
  • 2020-12-06
  • 2016-12-04
相关资源
最近更新 更多