Reputation: 41
I need help with understanding this part of code with Snake collision in javascript, I marked parts that I do not fully understand how they work: Full code at: https://codeincomplete.com/posts/starting-snakes/
// do not understand this function
function occupies(a, b) {
return a && b && (a.x == b.x) && (a.y == b.y);
};
//do not understand this function
function snakeOccupies(pos, ignoreHead) {
var segment = ignoreHead ? head.next : head;
do {
if (occupies(segment, pos))
return true;
} while (segment = segment.next);
return false;
};
function unoccupied() {
var pos = {};
do {
//understand this part but i do not understand what does while do
pos.x = Math.round(random(0, nx-1));
pos.y = Math.round(random(0, ny-1));
} while (foodOccupies(pos) || snakeOccupies(pos));
return pos;
};
Upvotes: 2
Views: 108
Reputation: 3454
In this code, a position on the game area is represented by an object with properties x
and y
.
occupies
checks whether two such objects represent the same position. It's not sufficient to just return a == b;
or return a === b;
, because separate objects can be copies of each other and represent the same position. For example, the expression { x: 1, y: 1 } === { x: 1, y: 1 }
will evaluate to false
.
The a && b &&
part is to handle the case where one/both of the arguments a
and b
is undefined
or null
or something. If a
is falsy, occupies
will return a
. If a
is truthy but b
is falsy, it will return b
. (In javascript, the values false
, undefined
, null
, 0
, ''
and NaN
are falsy; all others are truthy.) Since the return value is only used inside an if(...)
, any falsy value is treated as false
and any truthy value is treated as true
.
The do-while loop in unoccupied
runs the contents of the block, then evaluates foodOccupies(pos) || snakeOccupies(pos)
. If it evaluates to true
(or otherwise truthy) it will run the block again; otherwise it will stop. It will keep running the loop until the condition is falsy. The only difference between this and a while loop without do
is that this one will not check the condition before the first iteration of the loop (so it's guaranteed to run the block at least once).
The loop in snakeOccupies
is slightly unusual: the condition (segment = segment.next
) doesn't just return a value which is checked for truthiness, it also changes the value of a variable.
head
is the position of the snake's head. It has properties x
and y
, just like the other positions, except that it also contains a property called next
. The value of this property is another position, representing the next square after the snake's head, which has its own next
property referencing the next position on the snake, and so on. This is what Bergi meant about a "linked list": It's a sequence of (x
, y
) pairs, and could have been implemented as an array, but instead it's implemented by links between the elements.
So the do-while loop iterates over the positions in the snake (possibly ignoring head
). If it reaches one positioned at pos
, snakeOccupies
returns true
. Otherwise, the loop will eventually reach the end of the snake, segment
will be set to something falsy (probably undefined
or null
), the loop will be exited and snakeOccupies
will return false
.
Upvotes: 1