首页 > 解决方案 > 为什么这个 javascript while 循环会挂起?

问题描述

我正在尝试使用 javascript 做一个非常简单的事情,以创建一个扫雷网格。

gridsize=9;

//grid initialisation 
var grid=Array(gridsize).fill(Array(gridsize).fill(null));

// this comes from  <https://stackoverflow.com/questions/1527803/generating-random-whole-numbers-in-javascript-in-a-specific-range>
function randint(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

nbombs=20;
insertedbombs=0;

while (insertedbombs<nbombs){
    rx=randint(0,gridsize-1);
    ry=randint(0,gridsize-1);
    if (grid[rx][ry] == null){
        insertedbombs++;
        grid[rx][ry]='b';
    }
}

在 Chrome 和 Firefox 控制台中,while 循环都挂起,网格的所有值都被填充,而不仅仅是 20,我不知道为什么,我想我对 javascript 语言有一些错误的理解,因为 python 中的相同代码有效.

工作python代码:

grid= [[None for i in range(9)]for i in range(9)]

nbombs=20;
insertedbombs=0;
while (insertedbombs< nbombs):
    rx=random.randint(0,8)
    ry=random.randint(0,8)
    if (grid[rx][ry]== None):
            grid[rx][ry]='b'
            insertedbombs+=1

标签: javascriptwhile-loopfreeze

解决方案


问题是它Array#fill没有做你认为它做的事情。

在您的示例中,您创建了一个 SINGLE 数组Array(gridsize).fill(null),然后将该数组放在外部数组的每个索引处。这意味着您grid实际上包含相同的数组,超过 9 次。因此,当您分配时,grid[0][0]您实际上是一次分配grid[0][0], grid[1][0], grid[2][0], grid[3][0], 等等... (ish)。

const gridSize = 9;

//grid initialisation 
const grid = Array(gridSize).fill(Array(gridSize).fill(null));

console.log(grid[0] === grid[1]);

grid[0][0] = 10;

console.log(grid[0][0], grid[0][0] === grid[1][0]);

你想要做的是首先用一些虚拟值填充数组,比如null. 然后映射数组并将每个条目替换为它自己的Array(gridsize).fill(null).

const gridSize = 9;

//grid initialisation 
const grid = Array(gridSize)
  .fill(null)
  .map(() => Array(gridSize)
    .fill(null)
  );

const randInt = (min, max) =>
  Math.floor(Math.random() * (max - min + 1)) + min;

const nbombs = 20;
let insertedbombs = 0;

while (insertedbombs < nbombs){
    const rx = randInt(0, gridSize - 1);
    const ry = randInt(0, gridSize - 1);
    if (grid[rx][ry] === null){
        insertedbombs += 1;
        grid[rx][ry] = 'b';
    }
}

console.log(grid);


推荐阅读