【发布时间】:2020-04-18 18:28:53
【问题描述】:
我正在使用原生 JavaScript 构建扫雷游戏。我有一个处理网格逻辑的 Grid 类,一个基本上充当空间属性容器的 Space 类,以及一个处理游戏逻辑的 Game 类。
在 Grid 类中,我有一个名为 openAdjoiningSpaces 的方法。此方法的预期行为是打开板上每个方向上的所有连接空间,从单击的空白空间开始,并在下一个空间与地雷接壤时终止。如果您不熟悉 Minesweeper,您可以在 http://minesweeperonline.com/ 看到此行为。
openAdjoiningSpaces 方法调用另一个方法,getBorderingSpaces。此方法接受单击的空间作为参数,并返回一个包含每个边界空间的数组,包括在角落接触的空间。
当调用openAdjoiningSpaces 时,它首先获取不包含地雷的边界空间并将它们放入名为toOpen 的数组中。然后该方法使用一个while循环。在while循环中,toOpen中的每个空格都被打开,然后对于每个打开的空格,获取其边界空格,如果它们为空,则将它们添加到一个名为next的数组中。在循环结束时,如果next 数组的长度大于0,则将toOpen 变量重新分配给next,否则循环终止。
这应该会导致所需的行为,但事实并非如此。每次我以另一种方式重写它时,它要么使浏览器崩溃(即使它不是无限循环),要么它只打开单击空间的周围空间然后终止。这是方法本身:
openAdjoiningSpaces(space)
{
if (space.isEmpty) {
let loop = true;
var toOpen = [ ...this.getBorderingSpaces(space).filter(space => !space.hasMine)];
while (loop) {
const next = [];
toOpen.forEach(space => {
this.openSpace(space.id);
const neighbouring = this.getBorderingSpaces(space);
neighbouring.forEach(space => {
if (!space.hasMine && space.isEmpty) {
next.push(space);
}
});
});
if (next.length > 0) {
toOpen = next;
break;
} else {
loop = false;
}
}
}
}
我已经尝试创建这种空间打开行为两天了。每次我接近成功时,网格仍然显示某种错误行为。整个下午,我不断尝试以不同的方式重写此方法,但无济于事。我束手无策,真的需要一些外部输入。请不要犹豫,要求我澄清有关代码的任何内容。我应该澄清的一件事是,空间对象有两个独立的属性hasMine 和isEmpty。第一个只是指空间是否有地雷。第二个是指它是否包含数字。也许是设计缺陷,我不知道,但我想我应该提一下。
【问题讨论】:
-
澄清一下,while 循环应该一直持续到
next.length === 0?如果是这种情况,在您的代码中,您总是以任何一种方式结束循环(break打破循环),因此您应该删除break。无论如何,您能否将this.getBorderingSpaces的代码包含在内?如果您还可以添加一些测试“空格”和预期的结果,那就更好了。 -
有助于发布有效代码,第一行似乎缺少关键字。
-
@RobG 没有缺少关键字。 JavaScript 中的方法省略了
function关键字。 -
发布的代码包含语法错误。
-
我无法在此处发布
getBorderingSpaces方法,因为它太长了。但是,它确实正确获取了与目标空间接触的所有空间。
标签: javascript while-loop minesweeper