Creating a Snake Game in Python

Building a small game is a useful way to learn Python because the program has to respond to input, update state, apply rules, and render a result repeatedly. A Snake game is a compact project that brings these ideas together without requiring a large framework.

Snake game in Python using the Turtle graphics module

This tutorial builds a simple Snake game with Python’s built-in turtle module. The focus is on the game loop, state management, event handling, and collision logic.

What You Will Build

  • A 600 × 600 game window
  • A controllable snake head
  • Randomly positioned food
  • A growing body stored as a list of segments
  • Wall and self-collision handling
  • Keyboard controls and a simple score counter

Requirements

You need Python 3 and a desktop environment that supports Tk-based Turtle graphics. The example uses only the standard-library modules turtle, time, and random, so there is no separate package installation.

Understand the Game State

  • Direction: the current movement direction.
  • Head position: the snake’s current coordinates.
  • Food position: the target the snake is trying to reach.
  • Body segments: the positions that follow the head.
  • Score and game status: values that change during play.

Step 1: Import the Modules

import turtle
import time
import random

turtle draws the game, time controls the update delay, and random generates new food positions.

Step 2: Create the Game Window

screen = turtle.Screen()
screen.title("Snake Game in Python")
screen.bgcolor("black")
screen.setup(width=600, height=600)
screen.tracer(0)

Calling tracer(0) gives the program control over screen refreshes. We will call screen.update() once per loop iteration.

Step 3: Create the Snake Head

head = turtle.Turtle()
head.shape("square")
head.color("green")
head.penup()
head.goto(0, 0)
head.direction = "stop"

The custom direction attribute stores movement state, while penup() prevents drawing a line as the head moves.

Step 4: Create the Food

food = turtle.Turtle()
food.shape("circle")
food.color("red")
food.penup()
food.goto(100, 0)

Step 5: Add Direction Controls

def go_up():
    if head.direction != "down":
        head.direction = "up"

def go_down():
    if head.direction != "up":
        head.direction = "down"

def go_left():
    if head.direction != "right":
        head.direction = "left"

def go_right():
    if head.direction != "left":
        head.direction = "right"

The checks prevent an immediate 180-degree turn, which would make the snake move directly into its existing body.

Step 6: Register Keyboard Events

screen.listen()
screen.onkeypress(go_up, "Up")
screen.onkeypress(go_down, "Down")
screen.onkeypress(go_left, "Left")
screen.onkeypress(go_right, "Right")

Step 7: Move the Head

def move():
    step = 20

    if head.direction == "up":
        head.sety(head.ycor() + step)
    elif head.direction == "down":
        head.sety(head.ycor() - step)
    elif head.direction == "left":
        head.setx(head.xcor() - step)
    elif head.direction == "right":
        head.setx(head.xcor() + step)

Step 8: Move the Snake Body

Store the body segments in a list. Update the list from the tail toward the head so each segment receives the position that was previously occupied by the segment ahead of it.

segments = []

def move_body():
    for index in range(len(segments) - 1, 0, -1):
        segments[index].goto(
            segments[index - 1].xcor(),
            segments[index - 1].ycor()
        )

    if segments:
        segments[0].goto(head.xcor(), head.ycor())

Step 9: Add a New Segment

def add_segment():
    segment = turtle.Turtle()
    segment.shape("square")
    segment.color("green")
    segment.penup()

    if segments:
        segment.goto(segments[-1].xcor(), segments[-1].ycor())
    else:
        segment.goto(head.xcor(), head.ycor())

    segments.append(segment)

Step 10: Build the Main Game Loop

score = 0

while True:
    screen.update()
    move_body()
    move()

    if head.distance(food) < 20:
        score += 10
        food.goto(
            random.randint(-280, 280),
            random.randint(-280, 280)
        )
        add_segment()

    if (head.xcor() > 290 or head.xcor() < -290 or
            head.ycor() > 290 or head.ycor() < -290):
        break

    for segment in segments:
        if segment.distance(head) < 20:
            break

    time.sleep(0.1)

screen.bye()

The loop is the game engine: it updates the display, moves the body and head, handles food, checks boundaries, checks the body, and waits briefly before the next frame.

Collision Handling

Food collision increases the score and adds a segment. Wall collision ends the basic game. For a complete game-over implementation, track a game_over flag and exit the loop when the head touches a segment.

Common Bugs to Watch For

  • Updating body segments from the head toward the tail instead of backward.
  • Allowing an immediate reverse direction.
  • Generating food outside the playable area.
  • Forgetting screen.update() when using manual tracing.
  • Checking self-collision against stale segment positions.

How to Turn This Into a Better Project

  • Add a proper game-over screen and restart control.
  • Display the score inside the game window.
  • Increase speed as the score grows.
  • Prevent food from spawning on the snake body.
  • Separate input, update, collision, and rendering into independent functions.
  • Refactor the game into classes once the procedural version is understood.

What This Project Teaches

ConceptWhere It Appears
FunctionsMovement, input, body updates, collisions
ListsStoring snake segments
LoopsGame updates and body movement
ConditionsDirection and collision rules
EventsKeyboard input
StateDirection, food, score, and game status

Conclusion

A Snake game is small enough to understand end to end, yet rich enough to demonstrate application state, event handling, control flow, collections, and collision logic. Build the simplest version first, test each rule, and then add features incrementally. That workflow teaches more than copying a large finished project.

Read More

2 thoughts on “Creating a Snake Game in Python”

Leave a Comment