假设我有一个 20 乘 20 的“网格”。我随机生成食物的方式是使用以下公式:
Math.floor(Math.random() * ((max - min) / 20) + 1) + 20 * min;
这基本上确保了食物会在一个网格单元内整齐地生成。
我想避免在蛇的 body 上产卵。我还没有找到在保持分布式随机性的同时做到这一点的最佳方法。
不太有效的解决方案:
我见过一些人这样做,但它不起作用,因为它不能保证食物永远不会在蛇身上生成,它只是降低了这种可能性。 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 时,食物仍然可以在 Snake[2].x、snake[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();
}
}
我还尝试过其他一些方法,但我就到此为止。做我想做的事情的好方法是什么?
最佳答案
我会生成一个允许食物产卵的可能位置列表。类似于所有位置的集合减去蛇 body 位置的集合。
我在 JavaScript 和 p5.js 中对扫雷做了类似的事情。两个地雷不能占据同一个单元。当我生成地雷时,我从可能位置列表中删除了它们的位置。
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
操作,因此当这些值中的任何一个很大时,重复执行将会变得低效。我认为最好的方法是当这些值很大时将其结合起来,当这些值很小时选择一个随机点。
关于Javascript 贪吃蛇游戏(食物生成位置),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47103792/