HexXx
HexXx

Reputation: 41

Javascript Snake Collision Understanding

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

Answers (1)

David Knipe
David Knipe

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

Related Questions