Python Snake Eating and Growing
Eating means the head reaches the food's square. The program tests the distance between the head and the food after every move.
The body and the score
The segments list holds the body squares, and it starts empty. The score starts at zero.
# The body starts empty; the score starts at zero
segments = []
score = 0The eat check
The check runs inside the loop, right after move(). head.distance(food) measures the straight-line distance between the centres of the head and the food.
# Eat: the head reached the food
if head.distance(food) < 20:What one bite does
new_food_spot() jumps the food to a fresh square first. A new grey square Turtle is then built and appended to segments, and the score line runs last in the block.
new_food_spot()
new_segment = turtle.Turtle()
new_segment.speed(0)
new_segment.shape("square")
new_segment.color("grey")
new_segment.penup()
segments.append(new_segment)
score = score + 10Example
import turtle
import time
import random
# The game window
screen = turtle.Screen()
screen.setup(width=600, height=600)
screen.bgcolor("black")
screen.title("Snake")
screen.tracer(0)
# The snake head
head = turtle.Turtle()
head.speed(0)
head.shape("square")
head.color("white")
head.penup()
head.goto(0, 0)
head.direction = "right"
# The food: one red circle on the board
food = turtle.Turtle()
food.speed(0)
food.shape("circle")
food.color("red")
food.penup()
# The body starts empty; the score starts at zero
segments = []
score = 0
def move():
if head.direction == "up":
head.sety(head.ycor() + 20)
if head.direction == "down":
head.sety(head.ycor() - 20)
if head.direction == "left":
head.setx(head.xcor() - 20)
if head.direction == "right":
head.setx(head.xcor() + 20)
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"
def new_food_spot():
x = random.randint(-14, 14) * 20
y = random.randint(-14, 14) * 20
food.goto(x, y)
new_food_spot()
# The keyboard steers the snake
screen.listen()
screen.onkey(go_up, "Up")
screen.onkey(go_down, "Down")
screen.onkey(go_left, "Left")
screen.onkey(go_right, "Right")
# The game loop: redraw, move, check for a bite, wait, repeat
while True:
screen.update()
move()
# Eat: the head reached the food
if head.distance(food) < 20:
new_food_spot()
new_segment = turtle.Turtle()
new_segment.speed(0)
new_segment.shape("square")
new_segment.color("grey")
new_segment.penup()
segments.append(new_segment)
score = score + 10
time.sleep(0.1)Key points
- A distance under 20 means the head sits on the food's square
- The eat check runs after move(), so it tests the square the head just reached
- Each bite adds 10 to the score
- The segments list grows by one segment per bite
In this example, the game gains an empty segments list and a score of zero beside the food. The loop still redraws, moves the head and waits, and one new check runs between the move and the wait. When head.distance(food) comes back under 20, the head has reached the food's square. The bite calls new_food_spot() to jump the food to a new square, then builds one grey square Turtle and appends it to segments. The new segment appears in the centre of the board, where every new Turtle starts, and it sits there for now. The score also rises by 10 on each bite, and nothing shows it on the screen yet. The Following Body lesson makes the body squares trail behind the head, and the Score on Screen lesson puts the score on the window.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
When does the program decide that the snake has eaten the food?