Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Building a Classic Snake Game

Snake MovementSnake Movement

To achieve movement, we need to update the snake's position based on its current direction. To do this we need to add direction (right, left, up, down) to the s

movement

Updating positions

To update positions we will use zip() function and generator expression that we will convert to tuple.

zip() is a built-in function that takes iterables (such as lists, tuples, or strings) as arguments and returns an iterator that produces tuples where the i-th tuple contains the i-th element from each of the input iterables. The returned iterator stops when the shortest input iterable is exhausted.

Note

It might seems hard to understand but it is really quite simple, look at the example below.

In this example, zip() combines the numbers list and the letters list element-wise and returns an iterator that yields tuples. We need it to update the position of snake segments.

Updating the snake head position

We represent direction and position using tuples. To derive the new position, we simply add the first element of the direction tuple to the first element of the position tuple, and then repeat this process for the second elements.

After obtaining the two new tuples (10, 1) and (10, 0), the final step is to add their respective values together and combine them into a single tuple, resulting in (11, 10).

Great! Now let's think what will happen if we applied our algorithms to the head of the snake. The problem is that if we call this function for each iteration of our game only head of the snake will move and its body will stay in place.

Note

While our snake moves forward, its body stays at the same position it was before.

To address this issue, we need to update the positions of the body segments. We'll begin iterating from the tail, setting each position to the previous one until we reach the head of the snake. Look at the example below:

The value of the last element at index 3, initially (0, 4), is now updated to (0, 3) with the value of the element at index 2. Similarly, the value of the previous element at index 2, originally (0, 3), is now (0, 2) with the value of the element at index 1. Finally, the values of the element at index 1 correspond to those of the snake's head. If we combine this with the updating the head of the snake we will get:

Boundary Wrapping

If you watch the animation of our snake's movement above, you'll notice it slithers out of view and keeps on going beyond the boundaries of the playing field. We can fix it by checking the collision of the snake head with invisible "walls" or we can approach this issue in amore creative way.

Note

In this loop that runs 10 times, each time i is calculated modulo 3 to keep its value within the range of 0 to 2.

The solution lies in the example above, we can use % operator to wrap our snake and limit its position values to the game field size. We can use zip() function again and it will look something like this:

The position increases from (9, 9) to (10, 9). However, since the field size is (10, 10), the x value of the position wraps around and resets to zero. As a result, our snake's movement pattern will look like this:

Task

  • Implement the move function.
    • Update the positions of the snake's body segments. Use a reverse range loop to iterate over the snake segments starting from the tail up to, but not including, the head. Within the loop, update the position of each segment to the position of the segment in front of it.
    • Update the positions of the snake's head based on current direction. After updating the segment positions, calculate the new position of the head. Remember that the head is the first element in the snake list.
    • Handle the boundary wrapping when the snake moves beyond the edges of the game field. Use the modulo operation to wrap the new head position within the boundaries of the game field.

Mark tasks as Completed

Everything was clear?

Section 1. Chapter 5
AVAILABLE TO ULTIMATE ONLY
course content

Course Content

Building a Classic Snake Game

Snake MovementSnake Movement

To achieve movement, we need to update the snake's position based on its current direction. To do this we need to add direction (right, left, up, down) to the s

movement

Updating positions

To update positions we will use zip() function and generator expression that we will convert to tuple.

zip() is a built-in function that takes iterables (such as lists, tuples, or strings) as arguments and returns an iterator that produces tuples where the i-th tuple contains the i-th element from each of the input iterables. The returned iterator stops when the shortest input iterable is exhausted.

Note

It might seems hard to understand but it is really quite simple, look at the example below.

In this example, zip() combines the numbers list and the letters list element-wise and returns an iterator that yields tuples. We need it to update the position of snake segments.

Updating the snake head position

We represent direction and position using tuples. To derive the new position, we simply add the first element of the direction tuple to the first element of the position tuple, and then repeat this process for the second elements.

After obtaining the two new tuples (10, 1) and (10, 0), the final step is to add their respective values together and combine them into a single tuple, resulting in (11, 10).

Great! Now let's think what will happen if we applied our algorithms to the head of the snake. The problem is that if we call this function for each iteration of our game only head of the snake will move and its body will stay in place.

Note

While our snake moves forward, its body stays at the same position it was before.

To address this issue, we need to update the positions of the body segments. We'll begin iterating from the tail, setting each position to the previous one until we reach the head of the snake. Look at the example below:

The value of the last element at index 3, initially (0, 4), is now updated to (0, 3) with the value of the element at index 2. Similarly, the value of the previous element at index 2, originally (0, 3), is now (0, 2) with the value of the element at index 1. Finally, the values of the element at index 1 correspond to those of the snake's head. If we combine this with the updating the head of the snake we will get:

Boundary Wrapping

If you watch the animation of our snake's movement above, you'll notice it slithers out of view and keeps on going beyond the boundaries of the playing field. We can fix it by checking the collision of the snake head with invisible "walls" or we can approach this issue in amore creative way.

Note

In this loop that runs 10 times, each time i is calculated modulo 3 to keep its value within the range of 0 to 2.

The solution lies in the example above, we can use % operator to wrap our snake and limit its position values to the game field size. We can use zip() function again and it will look something like this:

The position increases from (9, 9) to (10, 9). However, since the field size is (10, 10), the x value of the position wraps around and resets to zero. As a result, our snake's movement pattern will look like this:

Task

  • Implement the move function.
    • Update the positions of the snake's body segments. Use a reverse range loop to iterate over the snake segments starting from the tail up to, but not including, the head. Within the loop, update the position of each segment to the position of the segment in front of it.
    • Update the positions of the snake's head based on current direction. After updating the segment positions, calculate the new position of the head. Remember that the head is the first element in the snake list.
    • Handle the boundary wrapping when the snake moves beyond the edges of the game field. Use the modulo operation to wrap the new head position within the boundaries of the game field.

Mark tasks as Completed

Everything was clear?

Section 1. Chapter 5
AVAILABLE TO ULTIMATE ONLY
some-alt