I’m making the popular snake game for js homework. I have a function which is meant to ensure that after an apple is eaten it moves to a different location on the canvas while not being on any part of the snake, the function without the loop works fine (though apples are placed on the snake too):
move() {
let onSnake = true;
let x = this.getRandomNumber(0, canvas.width - 1); //UnitSize);;
let y = this.getRandomNumber(0, canvas.height - 1); //UnitSize);;
this.x = x;
this.y = y;
this.draw();
}
the function though with the loop ends up freezing after a few apples are eaten (right before hitting an apple):
move() {
let onSnake = true;
let x = this.getRandomNumber(0, canvas.width - 1); //UnitSize);;
let y = this.getRandomNumber(0, canvas.height - 1); //UnitSize);;
while (onSnake) {
onSnake = false;
x = this.getRandomNumber(0, canvas.width - 1); //UnitSize);
y = this.getRandomNumber(0, canvas.height - 1); //UnitSize);
for (let index = 0; index < snake.parts.length; index++) {
if (x === snake.parts[index].x || y === snake.parts[index].y) {
onSnake = true;
break;
}
}
}
this.x = x;
this.y = y;
this.draw();
}
with getRandomNumber being:
getRandomNumber(min, max) {
let r = Math.floor(Math.random() * (max - min + 1)) + min;
r = r - (r % UnitSize);
return r;
}
this is my second question on SO, don’t fry me please….
Advertisement
Answer
I didn’t get a moment to test but I suspect it’s as simple as the following evalutation.
if (x === snake.parts[index].x || y === snake.parts[index].y) {
onSnake = true;
break;
}
You are accepting either X or Y collision. Meaning the apple cannot share any X or Y coordinates with any of the snake pieces. What you want instead is and I believe. It’s like saying we both live on the same house because we live on the same street. No, we need to also have the same address.
As a safety, you could add a limit to how many iterations of the loop can run in the event their is no more space remaining for an apple.
let counter = 0;
while (onSnake && counter < 5000) {
onSnake = false;
x = this.getRandomNumber(0, canvas.width - 1); //UnitSize);
y = this.getRandomNumber(0, canvas.height - 1); //UnitSize);
for (let index = 0; index < snake.parts.length; index++) {
if (x === snake.parts[index].x && y === snake.parts[index].y) {
onSnake = true;
break;
}
}
counter += 1;
}
if (counter == 5000) {
alert("Could not find space for any more apples!");
}