Implementing the Snake Game in Python

-

cellphone my mother had is closely related to the sport it had. Yes, the classical snake game, so easy yet so addicting. I remember playing this game on end on my mother’s phone, losing after which trying many times!

In this text, we are going to learn to construct an easy Snake Game. We are going to use Python’s turtle module as a way to generate this game. Note that it is a beginners to intermediate level Python tutorial, and expects the reader to be accustomed to Python fundamentals corresponding to functions and loops, importing and accessing modules, and using conditional statements. It also requires one to have a surface-level understanding of Object Oriented Programming, especially creating objects instances from classes. For the sake of simplicity, I’ll explain every line of code. Let’s start!

Snake Game (Image by Writer)

Understanding the Game

The classical Snake game involves a small snake with a plain background. Food is provided on the screen. Because the snake eats the food, it grows in size, and the rating increases. As soon because the snake collides with the boundary wall or itself, the sport ends, and one loses.

To be able to code this game in Python, we are going to need to deal with the next points:

  1. Organising the Game Screen – within the classical Snake game, the background is a dull neon yellow-green screen
  2. Creating the Snake body – the sport starts with a small black snake, which progressively increases in size because it eats the food
  3. Moving the Snake – the snake can move within the 4 directions: up, down, left, and all the way through the arrow keys on the keyboard or corresponding buttons on the phone
  4. Creating the Food – the food for the snake appears at random locations on the screen
  5. The Snake eating the Food – because the snake’s body collides with the food created, the rating is increased in addition to the length of the snake, and latest food is generated randomly, and the sport continues.
  6. The Snake Colliding with itself or the Boundary Wall – if the snake’s body collides with itself or the boundary of the sport screen, the sport ends.

Allow us to start coding.

Organising the Game Screen

First things first, we are going to create a brand new project in our IDE, let’s call it “Snake Game”. I’m using PyCharm to code. Next, we are going to create a brand new “snake game.py” file. To begin with, we are going to import the Turtle module, specifically its Screen and Turtle classes.

from turtle import Screen, Turtle

The Turtle Module is a built-in Python package that enables one to attract shapes, lines, patterns, and animations on a screen through code. The module works as if there’s a turtle with a brush on its back, and whatever you command it to go to, it’s going to go there, thereby creating drawings. You may ask the turtle to maneuver forward, to show left by a certain angle, draw a circle etc. The turtle will draw exactly that, and it’s a straightforward tool to visualise one’s code. It helps practising variables, loops, functions, coordinates, and basic animation logic with easy visual outputs.

You may take a look at the Turtle Official Documentation here.

As may be seen within the line of code above, we’ve got imported two elements: Screen and Turtle. These are classes which can be defined within the module. In Python, a category is a blueprint used to create objects. Turtle and Screen are classes which will likely be used to create corresponding objects. These objects can have attributes (variables) and methods (functions) as defined of their blueprint, with the availability of customization.

Allow us to first create the background for our game. We are going to use the Screen class for this purpose and customise it based on our requirements. For reference, check the Screen methods from the official documentation here.

#Organising the Game Screen
screen = Screen()
screen.setup(width=600, height=600)
screen.bgcolor("green yellow")
screen.title("Snake Game")
screen.tracer(0)

screen.exitonclick()

As may be seen within the code above, we first created the screen object from the Screen Class. Next, we’ve got used the setup() approach to the Screen class and set the width of the Game Screen to 600×600. We’ve got customized the background color to “green yellow” using the bgcolor() method. The name of the colour may be found through this link. I chosen the colour that closely resembled the colour in the unique game. After that, we’ve got named the screen “Snake Game” using the title() method. The tracer() method from the Turtle class lets us control the animation. By giving an argument of “0”, we’ve got turned it off. This will likely be higher understood after we create the snake and food. Lastly, we’ve got used the exitonclick() method to set the window to shut only after we click on it. Otherwise, the window closes as soon because it pops up and executes the entire code.

Running the code above would output the next:

The Game Screen (Image by Writer)

Creating the Snake Body

Once we’ve got created the Game Screen, the following task is to create the snake. The snake will even be created using the Turtle class. We are going to create 3 turtle objects that won’t resemble a turtle in any respect. Fairly, they will likely be square segments, and when placed together, will resemble a snake’s body, similar to in the sport. For this purpose, we are going to use a for loop to create the three segments. Each segment will likely be placed at a specified position. Allow us to code this:

#Creating the Snake
segments = []
starting_positions = [(0,0), (-20,0), (-40,0)]
for position in starting_positions:
    new_segment = Turtle("square")
    new_segment.color("black")
    new_segment.penup()
    new_segment.shapesize(1,1)
    new_segment.goto(position)
    segments.append(new_segment)

screen.update()

Within the code above, we first created an empty list of segments. This list will contain the snake segments. Once the snake segments are created, it’s going to consist of three segments, and every time the snake eats its food, the variety of segments will increase. We’ve got created a tuple starting_positions. This can contain 3 positions specified by way of their x and y coordinates, and will likely be the positions where the snake segments will likely be created. We are going to create the primary segment at (0,0), the second at (-20,0), and the third segment at (-40,0). Using the for loop, we’ve got created 3 segments from the variable new_segment as a turtle object, of square shape and standard size 20×20. The arguments to shapesize() method is given as 1×1 because it stretches the scale of the drawing cursor relative to its default 20×20 pixel size. The penup() method allows us to cover the pen, and just output the form of the turtle object. The goto() method allows us to create the form ranging from that position. Lastly, we’ve got appended the newly created segment to the empty list we created to start with of this code block. In this manner, 2 more segments will likely be created as there are 2 more positions within the starting_positions tuple.

Ultimately, we are going to update our screen in order that it now shows each the customized screen and the newly created snake. This will likely be the output:

Creating the Snake Body (Image by Writer)

Notice that we’ve got created the segments using just the for loop. As we go ahead in our program, we are going to need to extend the snake’s segments because it eats the food. To be able to make this addition convenient to us, allow us to modify the code block and add a function called add_segments, to create the snake in addition to use it later when adding segments to the snake when it eats the food. This will likely be a greater approach to programming in the present scenario:

#Creating the Snake
segments = []
starting_positions = [(0,0), (-20,0), (-40,0)]

#Adding Segments Function
def add_segments(position):
    new_segment = Turtle("square")
    new_segment.color("black")
    new_segment.penup()
    new_segment.goto(position)
    segments.append(new_segment)

for position in starting_positions:
    add_segments(position)

screen.update()

Within the above code block, we’ve got done exactly what we were previously doing, that’s, creating the snake body, except that we’ve got used a Python function to accomplish that. We’ve got defined a function called add_segments, whose purpose is just so as to add the segments to the snake’s body, and the segments list. Furthermore, now could be where the screen’s tracer() method comes to make use of. Should you comment out the screen.tracer() line that we added within the begining you will note the animation of the snake’s body being created one segment at a time (and we don’t want that in our game!). This may higher be visualized by first importing the time module and using the sleep() function. The animation will likely be more visible.

import time

#Keep the remainder of the code same

for position in starting_positions:
    add_segments(position)
    time.sleep(1)
screen.update()

Snake Movement

The following task is to code the snake’s movement. To start with, allow us to just make the snake move forward. We are going to first create a variable game_is_on that will likely be True so long as the sport is running, and will likely be switched to False once we lose or the sport ends. This variable will likely be utilized in the while loop. So long as the sport is on, the snake will proceed moving, and we are going to only give you the option to alter its direction using the arrow keys. That is going to be the a part of our program that may keep the sport on.

Now comes the complex part. To maneuver the snake forward, we want to maneuver all of its segments ahead. The technique to make your complete snake body move forward is by making each segment, apart from the primary one, to maneuver to the one before it. Because of this at the start, when the snake is barely 3 segments long, segment 3 will move to the place of segment 2, and segment 2 will move to the place of segment 1, and segment 1 will move forward using the turtle forward() method. This may be coded within the for loop, by giving it a starting value of the last element of the list, which is the element on the 2nd position (list elements start from 0, thus 0, 1, 2) when the snake is created (having 3 segments) or otherwise calculated because the length of the segments, minus 1. The for loop will end at position 0, and because it is moving in reverse, we are going to give it a step size of -1. This whole scenario is coded as below:

game_is_on = True
while game_is_on:
    screen.update()
    time.sleep(0.1)
    for seg_num in range(len(segments)-1, 0, -1):
        new_x = segments[seg_num - 1].xcor()
        new_y = segments[seg_num - 1].ycor()
        segments[seg_num].goto(new_x, new_y)
    segments[0].forward(20)

Notice that we’ve got added the screen’s update() method, in addition to defined the speed of the snake using the time module’s sleep() function. By giving it an argument of 0.1, the snake segments will move forward with a time delay of 0.1 seconds, and this speed may be adjusted. If given an argument of 1, the time delay will likely be 1 second, and the speed of the snake will likely be slow. You may experiment with the snake’s speed by changing the values given to the sleep() function.

The inside the for loop elaborates how the segments will move to the previous segments’ position using its coordinates. And at the tip, we’ve got the primary segment of our snake moving ahead by 20 using the turtle’s forward() method. Running our code would output a moving snake:

Snake Moving Forward (Image by Writer)

Controlling the Snake

Now that we’ve got seen how one can make the snake move, the following thing is to regulate the up/down/left/right movements of the snake. For this, we are going to use the screen listeners. We are going to code this system in order that on pressing the up, down, left, and right keys, the snake will move accordingly by changing its head.

Another feature that we want so as to add, taking it from the unique snake game, is that when the snake is moving left, it cannot directly turn right, when it’s moving up, it will possibly indirectly turn downwards. Briefly, the snake cannot turn 180 degrees from where it’s moving. Allow us to add this feature to our code. Be certain so as to add these lines of code before the sport’s while loop we coded earlier.


#Controlling the Snake
screen.listen()
def turn_up():
    if segments[0].heading() != 270:
        segments[0].setheading(90)
def turn_down():
    if segments[0].heading() != 90:
        segments[0].setheading(270)
def turn_left():
    if segments[0].heading() != 0:
        segments[0].setheading(180)
def turn_right():
    if segments[0].heading() != 180:
        segments[0].setheading(0)

screen.onkey(turn_up, "Up")
screen.onkey(turn_down, "Down")
screen.onkey(turn_left, "Left")
screen.onkey(turn_right, "Right")

As may be seen above, we first used the screen’s listen() method that lets us hearken to the screen’s input keys. Next, we’ve got defined functions which will likely be called later within the screen’s onkey() method, which calls a function based on a keyboard key pressed. We’ve got defined 4 functions, each to show to a direction aside from the exact opposite, using the turtle’s method setheading(). This method sets the top of the turtle, which is the primary segment or segment[0] to 0, 90, 180, or 270, that’s, right, up, left, or down. The if conditional statements in each function make certain that the snake doesn’t turn in its other way, as we are able to see in the unique game.

Running the entire code with this code block addition will allow us to move our snake:

Controlling Snake’s Movement with Arrow Keys (Image by Writer)

Food Creation

Once the snake has been created and programmed to maneuver using the arrow keys, the following task is to create the food which the snake will eat and grow. This food will even be created as a turtle object in a circular shape, in red. We are going to set the shapesize to 0.5 so the food is 10×10 pixels on the screen. We’ve got also set the speed() to “fastest” so the animation is fast, and there isn’t any delay in food creation. Here, we are going to import Python’s random module to create the food at random positions on the sport screen. We’ve got set the boundary of food as -275 to 275 on each the x and y axes. That is in order that it is less complicated for the snake to eat its food without colliding with the outer screen boundary.

Furthermore, every time the snake eats its food, latest food must be generated. For this purpose, we are going to define a function refresh() and generate latest random coordinates where the turtle object called food will move to. Take a look at the code below:

#Creating the Food
import random
food = Turtle()
food.color("red")
food.shape("circle")
food.penup()
food.shapesize(stretch_len=0.5, stretch_wid=0.5)
food.speed("fastest")
random_x = random.randint(-275, 275)
random_y = random.randint(-275, 275)
food.goto(random_x, random_y)

def refresh():
    random_x = random.randint(-275, 275)
    random_y = random.randint(-275, 275)
    food.goto(random_x, random_y)
Food Creation (Image by Writer)

Detect Collision with Food

Once we’ve got created the food, we now should create a mechanism whereby the snake eats the food. Because of this every time the snake touches the food, the food vanishes, and the snake grows by one segment. We are going to code this scenario such that every time the snake and food are in close proximity, in order that their distance is lower than 15, it means the snake has eaten the food. We are going to make use of the turtle module’s distance() method that calculates the gap between a turtle and a particular point or one other turtle object. If this distance is lower than 15 (through trial and error), it could mean the snake has touched or eaten its food, and the food should now move to a brand new location for game continuity. Hence, we are going to now call the refresh() function that we defined earlier to maneuver the food object to a brand new location. Eating the food should increase the snake’s size by a segment. For this, we are going to define a function called extend() outside the while loop and call it contained in the if conditional statement when the snake eats the food.

#Snake extending
def extend():
    add_segments(segments[-1].position())

As may be seen, the extend() function will add a brand new segment to the last segment of the snake’s body. Now moving on to the primary game’s loop:


game_is_on = True
while game_is_on:
    ...
    #Retain the unique code here
    ...
    #Detect Collision with Food
    if segments[0].distance(food) < 15:
        refresh()
        extend()
Snake Eating Food and Extending (Image by Writer)

Scoreboard and Rating Updation

Next is to create a scoreboard that might display the rating. To do that, we are going to code outside the while loop. We are going to create this scoreboard and the rating as 2 turtle objects using turtle’s write() method, which allows us to display text on screen. First, we are going to initialize a variable called rating as 0. Because the snake eats its food, the rating variable will likely be increased by 1 every time. Next, we are going to create 2 turtle instances, scoreboard and my_score. The scoreboard object will display the text on screen “Rating = “, whereas the my_score object will display the rating variable, which can change because the snake eats its food. As may be seen within the code below, each of those turtle objects have been customized for the screen text display based on the necessity.

#Creating the Scoreboard & Rating
rating = 0

scoreboard = Turtle()
scoreboard.color("black")
scoreboard.penup()
scoreboard.hideturtle()
scoreboard.goto(0,250)
scoreboard.write("Rating = ", True, align="center", font=("Arial", 12, "normal"))

my_score = Turtle()
my_score.color("black")
my_score.penup()
my_score.hideturtle()

Once we've got created the above, we are going to now proceed so as to add the availability of fixing the core inside the while loop of the sport, contained in the if conditional statement when the snake collides with the food. Check the code below and update the particular lines of code:

game_is_on = True
while game_is_on:
    ...
    #Retain the unique code here
    ...
    #Detect Collision with Food
    if segments[0].distance(food) < 20:
        refresh()
        extend()
        rating = rating + 1
        my_score.goto(40, 250)
        my_score.clear()
        my_score.write(rating, True, align="center", font=("Arial", 12, "normal"))

The next is displayed on the screen after running this system with the above additions:

Scoreboard and Rating Display (Image by Writer)

Game Ending

When the sport ends, we want to inform the user that the sport is over, fairly than simply closing the monitor. For this we are going to define a function and call it every time the sport ends: either by collision with a wall or by collision with tail. We are going to use the turtle object for this as well. That is the function, and it's going to be called when game_is_on variable turns to False.

#Game Over Pop Up
def game_over():
    game_over = Turtle()
    game_over.color("black")
    game_over.penup()
    game_over.hideturtle()
    game_over.write("GAME OVER", True, align="center", font=("Arial", 40, "normal"))

Detect Collision with Wall

One other condition of the sport’s continuity is to make certain the snake doesn't collide with the boundary wall of the screen. To be able to code this, and knowing that the sport’s screen is 600×600, we are going to consider the boundary wall a square with its corners to be at these points: (290, 290), (290, -290), (-290, -290) and (-290, 290). The wall detection block will likely be inside the game loop in a separate if conditional statement as follows:

game_is_on = True
while game_is_on:
    ...
    #Retain the unique code here
    ... 
    # Detect Collision with Wall
    if segments[0].xcor() > 290 or segments[0].xcor() < -290 or segments[0].ycor() > 290 or segments[0].ycor() < -290:
        game_is_on = False
        game_over()
 

Within the above lines of code, we've got accessed the x and y coordinates of the primary segment of the snake and checked whether it falls inside or outside of the boundary wall.

Detect Collision with Tail

Lastly, we are going to end this program with one other condition of the sport, which is that if the snake’s head collides with itself, that's, the primary segment collides with some other segment, the sport ends. We are going to use the for loop to code this scenario:

game_is_on = True
while game_is_on:
    ...
    #Retain the unique code here
    ...   
    # Detect Tail Collision
    for segment in segments[1:]:
        if segments[0].distance(segment) < 10:
            game_is_on = False
            game_over()
 

When the sport ends, we want to inform the user that the sport is over, fairly than simply closing the monitor. For this, we are going to call the game_over function we defined earlier.

Game Over (Image by Writer)

Conclusion

On this tutorial, we've got successfully implemented the snake game in Python. We've got used our understanding of Python basics, corresponding to defining and calling functions, using lists and tuples, using for and while loops in addition to conditional statements. We've got also implemented our basic understanding of Object Oriented Programming to create objects from a module’s classes. If you've gotten any queries regarding any piece of code or a suggestion to make the code more robust and efficient, be happy to comment and share your ideas. Until then, code, play, and challenge your pals to the Snake Game you've gotten designed!

ASK ANA

What are your thoughts on this topic?
Let us know in the comments below.

0 0 votes
Article Rating
guest
0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments

Share this article

Recent posts

0
Would love your thoughts, please comment.x
()
x