8
\$\begingroup\$

I have created a snake game in Python. It is a single-player game, where the snake has to eat the red dots in order to grow longer. I just wanted to review if there are any improvements.

import turtle
import random
import time
screen = turtle.Screen()
screen.title('Snake made in Python')
screen.setup(width = 800, height = 700)
screen.tracer(0)
turtle.bgcolor('turquoise')
turtle.speed(5)
turtle.pensize(4)
turtle.penup()
turtle.goto(-310,250)
turtle.pendown()
turtle.color('black')
turtle.forward(600)
turtle.right(90)
turtle.forward(500)
turtle.right(90)
turtle.forward(600)
turtle.right(90)
turtle.forward(500)
turtle.penup()
turtle.hideturtle()
score = 0
delay = 0.1
snake = turtle.Turtle()
snake.speed(0)
snake.shape('square')
snake.color("black")
snake.penup()
snake.goto(0,0)
snake.direction = 'stop'
fruit = turtle.Turtle()
fruit.speed(0)
fruit.shape('circle')
fruit.color('red')
fruit.penup()
fruit.goto(30,30)
old_fruit=[]
scoring = turtle.Turtle()
scoring.speed(0)
scoring.color("black")
scoring.penup()
scoring.hideturtle()
scoring.goto(0,300)
scoring.write("Score :",align="center",font=("Courier",24,"bold"))
def snake_go_up():
 if snake.direction != "down":
 snake.direction = "up"
def snake_go_down():
 if snake.direction != "up":
 snake.direction = "down"
def snake_go_left():
 if snake.direction != "right":
 snake.direction = "left"
def snake_go_right():
 if snake.direction != "left":
 snake.direction = "right"
def snake_move():
 if snake.direction == "up":
 y = snake.ycor()
 snake.sety(y + 20)
 if snake.direction == "down":
 y = snake.ycor()
 snake.sety(y - 20)
 if snake.direction == "left":
 x = snake.xcor()
 snake.setx(x - 20)
 if snake.direction == "right":
 x = snake.xcor()
 snake.setx(x + 20)
screen.listen()
screen.onkeypress(snake_go_up, "Up")
screen.onkeypress(snake_go_down, "Down")
screen.onkeypress(snake_go_left, "Left")
screen.onkeypress(snake_go_right, "Right")
while True:
 screen.update()
 if snake.distance(fruit)< 20:
 x = random.randint(-290,270)
 y = random.randint(-240,240)
 fruit.goto(x,y)
 scoring.clear()
 score+=1
 scoring.write("Score:{}".format(score),align="center",font=("Courier",24,"bold"))
 delay-=0.001
 
 new_fruit = turtle.Turtle()
 new_fruit.speed(0)
 new_fruit.shape('square')
 new_fruit.color('red')
 new_fruit.penup()
 old_fruit.append(new_fruit)
 
 
 for index in range(len(old_fruit)-1,0,-1):
 a = old_fruit[index-1].xcor()
 b = old_fruit[index-1].ycor()
 old_fruit[index].goto(a,b)
 
 if len(old_fruit)>0:
 a= snake.xcor()
 b = snake.ycor()
 old_fruit[0].goto(a,b)
 snake_move()
 if snake.xcor()>280 or snake.xcor()< -300 or snake.ycor()>240 or snake.ycor()<-240:
 time.sleep(1)
 screen.clear()
 screen.bgcolor('turquoise')
 scoring.goto(0,0)
 scoring.write(" GAME OVER \n Your Score is {}".format(score),align="center",font=("Courier",30,"bold"))
 
 for food in old_fruit:
 if food.distance(snake) < 20:
 time.sleep(1)
 screen.clear()
 screen.bgcolor('turquoise')
 scoring.goto(0,0)
 scoring.write(" GAME OVER \n Your Score is {}".format(score),align="center",font=("Courier",30,"bold"))
 
 time.sleep(delay)
turtle.Terminator()
toolic
14.5k5 gold badges29 silver badges203 bronze badges
asked Jun 30, 2021 at 20:19
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

UX

It is not obvious what the user should do when the GUI opens up. You should display some simple instructions in the GUI, such as:

Use arrow keys on keyboard to move right, left, etc.

When I exit out of the GUI window, I see several errors in the shell in which I ran the game. Perhaps this is specific to the version of Python I am using.

Efficiency

In the snake_move function, the 4 if statements should be combined into a single if/elif because the 4 conditions are mutually exclusive:

def snake_move():
 if snake.direction == "up":
 y = snake.ycor()
 snake.sety(y + 20)
 elif snake.direction == "down":
 y = snake.ycor()
 snake.sety(y - 20)
 elif snake.direction == "left":
 x = snake.xcor()
 snake.setx(x - 20)
 elif snake.direction == "right":
 x = snake.xcor()
 snake.setx(x + 20)

You should also be able to eliminate the intermediate variables. For example:

 if snake.direction == "up":
 snake.sety(snake.ycor() + 20)

Magic number

The 20 in the snake_move function should be a declared constant. You should also add a comment describing why you chose this value.

DRY

The 4 functions:

def snake_go_up():
def snake_go_down():
etc.

could be combined into a single function with an argument passed in corresponding to the direction.

This group of lines is repeated twice:

time.sleep(1)
screen.clear()
screen.bgcolor('turquoise')
scoring.goto(0,0)
scoring.write(" GAME OVER \n Your Score is {}".format(score),align="center",font=("Courier",30,"bold"))

They can be placed into a function.

Layout

Move the functions to the top after the import lines. Having them in the middle of the code interrupts the natural flow of the code (from a human readability standpoint).

There is inconsistent whitespace around operators, such as

 a= snake.xcor()
 b = snake.ycor()

The black program can be used to automatically format the code to add consistency. This will also help with the inconsistent indentation and excessive blank lines.

answered Nov 30, 2024 at 12:43
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.