This page is part of the Snake in MIT Scratch Tutorial.
Calculating the Snake’s Next Position
Before moving or growing the snake the system calculates the next position that the snake’s head should occupy.
This is achieved by using the snake’s current direction and position to calculate the next adjacent square.
The system should also allow the snake to ‘wrap’ around if it reaches the screen edge:
The Calculate Next Position Function
The Game Controller sprite script contains a function called Calculate Next Position.
The following image shows an example of the function when the snake is traveling Up.
The Snake Direction value is compared with the Direction Up enumeration. If the two are equal then the snake is traveling Up.
As the snake is traveling vertically the snake’s next X position will remain the same as its current position.
The value of Snake Next X is set to item 1 of snake parts X.
The first item in the snake parts list is the head so this statement is setting the next X position of the head to the current X position.
There are two parts to the calculation of the Y position:
- Moving: Subtracting one from the snake’s current position will move it one grid space upwards.
- Wrapping: The calculation uses the mod operation with the Grid Height to make the position wrap around.
Adding or subtracting one to a grid coordinate will move the snake’s head by one space on the grid.
The mod operation is used to keep the head within the bounds of the grid.
Using the Mod Operation to Make the Movement Wrap
The Wrapping section of the calculation uses the modulo (mod) operation.
The mod operation gives the remainder of a division.
Using the mod operation with a grid coordinate that is outside the bounds of the grid and the grid size will calculate how far outside the grid the coordinate is.
The following grid will be used as an example:
The grid has a width of 12 and a height of 9. The range of X values is 0 to 11 and the range of Y values is 0 to 8
The green square is at position (X : 5, Y : 5). Adding 1 to the X value will move it to the right:
X = 5 + 1 = 6
The result of this operation is constrained to grid by using the mod operation, which sets the value to the remainder of the division of the value by the grid width:
X = 6 mod 12 = 6
The value is unchanged by the mod operation. This is because 6 is within the bounds 0 to 11:
6/12 = 0 remainder 6
The mod operation sets the value to the remainder of the division. If the value is within the allowed range it remains unchanged.
The blue square is at position (X : 11, Y : 8). Adding 1 to the X value will move it to the right:
X = 11 + 1 = 12
The result is outside the allowed horizontal range of 0 to 11. The value can be constrained to the range using the mod operation:
X = 12 mod 12 = 0
The mod operation has set the out-of-bounds horizontal value of 12 to 0.
The square would have moved to the right off the edge of the grid. Using mod wrapped the value around to the left edge of the grid at 0.
The mod operation worked like this:
12/12 = 1 remainder 0
The mod operation is useful for making the snake wrap when the range of coordinates starts at zero and ends at the grid size -1.
The mod operation can constrain negative values as well.
The red square is at position (X : 0, Y : 0). Subtracting 1 from the Y value will move the square upwards.
Y = 0 – 1 = -1
This negative value is outside the allowed range for vertical positions of 0 to 8 so using mod with the grid height will constrain it:
Y = -1 mod 9 = 8
The result of the division is as follows:
-1/9 = 0 remainder 8
The vertical movement brought the square off the bottom edge and the mod operation moved it to the top edge.
The mod operation can be visualized using this number line:
The mod operation constrains values to the limits allowed by the grid size and can be used to make out of bounds values wrap around to the opposite side of the grid.
The Complete Function
The complete Calculate Next Position consists of four if statements that supply the correct values for each possible direction:
In each direction the mod operation is used to constrain the movement to the grid.
The next position that the snake should move to is calculated using its current position and direction.
An if statement determines the direction so that the correct X or Y value can be changed.
To move one square 1 is added or subtracted to the current X or Y position value.
The modulo operation is used to constrain the position to the range of values allowed by the grid size and allows the snake to wrap around the screen when it reaches the edge.
Next Section: Detect if the Snake Eats its Own Tail