假设我有一个20格的20格“格子”。我随机产生食物的方式是使用以下公式:
Math.floor(Math.random() * ((max - min) / 20) + 1) + 20 * min;
这基本上可以确保食物在一个网格单元内整齐地生成。
我想避免在蛇身上产生食物。我没有找到最好的方法来保持分布式随机性。
不太有用的解决方案:
我见过有些人这样做,但它不起作用,因为它不能保证食物永远不会在蛇身上产生,它只会降低它的可能性。 getRandomPoint()可能仍然让我在蛇上随机点。
for (let i = 0; i < snake.length; i++) {
if (foodPosition.x === snake[i].x && foodPosition.y === snake[i].y) {
foodPosition.x = getRandomPoint();
foodPosition.y = getRandomPoint();
}
}
下一个也不起作用,因为食物仍然可以在尚未检查的蛇的任何细胞上产卵。例如,当i = 0时,它只检查foodPosition.x和foodPosition.y是否等于snake [0] .x和snake [0] .y。在i = 0的循环迭代中,食物仍会在蛇[2] .x,蛇[2] .y所占据的细胞上产生(例如,我认为?)。
for (let i = 0; i < snake.length; i++) {
while (foodPosition.x === snake[i].x && foodPosition.y === snake[i].y) {
foodPosition.x = getRandomPoint();
foodPosition.y = getRandomPoint();
}
}
还有其他一些我尝试过的东西,但我会留下它。做我想做的事情的好方法是什么?
答案 0 :(得分:2)
我会生成一个允许食物产卵的可能位置列表。类似于所有位置的集合减去蛇体位置的集合。
我在JavaScript和p5.js中做过与Minesweeper类似的事情。两个地雷不能占用同一个小区。当我生成地雷时,我从可能的位置列表中删除了它们的位置。
let numRows = 20;
let numColumns = 20;
let possibleFoodLocations = [];
for (let row = 0; row < numRows; row++) {
for (let column = 0; column < numColumns; column++) {
let isLocationValid = snake.every(bodyPart => {
return row !== bodyPart.y || column !== bodyPart.x;
});
if (isLocationValid) {
possibleFoodLocations.push({ x: column, y: row });
}
}
}
请注意,这将执行numRows * numColumns * snake.length * 2
操作,因此当这些值中的任何一个很大时重复执行将变得效率低下。我认为,最好的方法是当这些值很大时将它们组合在一起,并在这些值很小时选择一个随机点。
答案 1 :(得分:1)
您是否可以获得随机点,然后检查以确保它与蛇的任何一点不匹配?如果是这样,你可以得到另一个随机点。
答案 2 :(得分:1)
我在您的解决方案中添加了一个标志,然后它就能正常工作
let colliding = true;
let new_x, new_y;
while(colliding) {
colliding = false;
new_y = getRandomPoint();
new_x = getRandomPoint();
for (let box of snake) {
if (new_x == box.x && new_y == box.y) {
colliding = true;
break;
}
}
}
foodPosition.x = new_x;
foodPosition.y = new_y;