这是一场扫雷游戏。这里的目标是生成确切的地雷数量。在这种情况下,我有一个8x8网格的盒子,里面有10个地雷(见下图)。因此,嵌套for循环生成64个具有x
和y
坐标的对象(以便稍后绘制网格)和state
属性以指示该字段是否已被挖掘。然后,在generateBombs
中,我使用随机state:mined
和x
y
生成10个对象,以随机覆盖box数组中的64个对象中的8个,从而种植地雷。我的方法存在的问题是,有可能会生成2对非唯一的x
和y
对象,这样我最终会得到比原来少的对象地雷数量,因为同一个对象将被覆盖两次。这里有什么好方法?
另外,我的要求之一是让生成器为地雷使用辅助函数,但它们采用相同的参数,可能会失败。
var minesweeper = {
boxes: [],
//rows
boxesNum: 0,
bombsNum: 0,
//creates a 8x8 grid
generateMap: function (width, height, bombsNum) {
for (i = 1; i < height; i++) {
this.boxes.push({
x: i,
y: 1,
state: "safe"
});
for (j = 1; j < width; j++) {
this.boxes.push({
x: 1,
y: j,
state: "safe"
});
}
}
this.generateBombs(width, height, bombsNum)
},
//mines random fields from the grid
generateBombs: function (width, height, bombsNum) {
for (k = 0; k < bombsNum; k++) {
this.boxes.push({
x: Math.floor(Math.random() * width + 1),
y: Math.floor(Math.random() * height + 1),
state: "mined"
});
}
}
}
minesweeper.generateMap(8, 8, 10);
答案 0 :(得分:1)
你最好不要在盒子阵列上工作,而不是先生成炸弹。
generateBombs: function (width, height, bombsNum) {
var bombCount = 0; // Count how many bombs we planted,
while(bombCount < 10){ // Loop until we have 10 bombs,
var index = parseInt(Math.random() * this.boxes.length + 1); // Get a random box id,
if(this.boxes[index].state === "safe"){ // If the box is safe, plant a bomb.
this.boxes[index].state = "mined";
bombCount++; // Increase bomb count with 1.
}
}
}
这种方法可以保证在10个不同地点种植10枚炸弹。 可以两次选择同一个框,但如果它这样做,它只会再次尝试。
在最好的情况下,与其他需要检查每个要生成的炸弹的坐标数组的方法相比,你有10次循环迭代。
然而,这种随机挑选炸弹位置的方法存在一个问题:
如果你增加炸弹数量,该方法将会击中越来越多已经种植炸弹的盒子,导致生成任意数量的炸弹所需的迭代指数增加。基本上,该领域越密集,该函数越有可能随机选择已经有炸弹的单元格,因此它必须再试一次。
您的generateMap
功能也被破坏了。试试这个:
generateMap: function (width, height, bombsNum) {
for (var i = 0; i < width; i++) {
for (var j = 0; j < height; j++) {
this.boxes.push({
x: (i + 1),
y: (j + 1),
state: "safe"
});
}
}
this.generateBombs(width, height, bombsNum)
},