1

So I'm making a minesweeper game in JS.

I have this function:

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);
                            }
                        }
                    }
                }


            }

The board's rows and cols are equal. countAround(x,y) returns the amount of mines around (x,y); revealed is an array which stores which squares have already been dealt with, to prevent dealing with them again.
This function is supposed to, when a square is clicked, reveal the number of mines near it and write it into the cell. Then, it checks every square around it, and if that square hasn't already been dealt with (if it isn't in the revealed array), the function doSquare() runs on it again. The function will not 'spread' from a square if the square has any mines next to it.

I get an error: maximum call stack size exceeded. But the function stops its 'spreading' upon reaching a square with mines, and also doesn't run on a square which already has been taken care of. So I would love an explanation as to why this happens.

4

1 回答 1

1

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

解决方案:

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

于 2013-04-21T15:41:11.943 回答