1

I'm trying to write a program with Python to emulate an 'old' online game in which you drive a worm through the screen with some inputs from the keyboard.

import turtle

# Set screen and background
wn = turtle.Screen()
wn.title("Turn with Left and Right buttons your keyboard. Click on screen to EXIT.")
wn.bgcolor("black")

# Snake settings
snake = turtle.Turtle()
snake.color("purple")
snake.shape("circle")
snake.shapesize(0.25,0.25)
snake.pensize(5)

snake.speed(10)
t = 0
# Define Go loop, turn Left and Right       
def go():
    t = 0
    while t < 1000:
        snake.forward(1)
        t += 1

def left():
    snake.circle(1,8)
    go()

def right():
    snake.circle(1,-8)
    go()


# Inputs and Exit on click
wn.onkey(right, "Right")
wn.onkeypress(right, "Right")
wn.onkey(left, "Left")
wn.onkeypress(left, "Left")
wn.listen()
wn.exitonclick()

turtle.done()

The problem here is that, after some moves, the program crashes returning:

RecursionError: maximum recursion depth exceeded while calling a Python object.

I'm still a beginner so i don't get what I'm doing wrong. How can I fix the error?

3
  • You should post the entire stack trace (without the sensitive parts of the file path) to show where the recursion occurs. Commented Oct 26, 2022 at 15:34
  • 1
    @AshSmith88 what has that got to do with recursion? Commented Oct 26, 2022 at 15:39
  • Dont know where my previous comment has gone @RandomDavis. But in short, I was saying that if every time they pressed left or right it was calling the go() function again. Which is essentially what you found when debugging and what your answer eludes to Commented Oct 26, 2022 at 16:21

2 Answers 2

1

What you're experiencing is a faux recursion due to events stacking. However, your code design:

while t < 1000:
    snake.forward(1)
    t += 1

actually relies on event stacking! That is, you expect left and right commands to come in during the go() portion of the event handler which keeps the turtle moving. This is a problematic design. Let's rework your code using an event timer instead:

from turtle import Screen, Turtle

def go():
    snake.forward(1)
    screen.ontimer(go, 50)

def left():
    screen.onkeypress(None, 'Left')  # disable handler inside handler
    snake.circle(1, 8)
    screen.onkeypress(left, 'Left')  # reenable handler

def right():
    screen.onkeypress(None, 'Right')
    snake.circle(1, -8)
    screen.onkeypress(right, 'Right')

screen = Screen()
screen.title("Turn with Left and Right buttons your keyboard. Click on screen to EXIT.")
screen.bgcolor('black')

snake = Turtle()
snake.color('purple')
snake.shape('circle')
snake.shapesize(0.25)
snake.pensize(5)
snake.speed('fastest')

screen.onkeypress(left, 'Left')
screen.onkeypress(right, 'Right')
screen.listen()

go()

screen.exitonclick()
Sign up to request clarification or add additional context in comments.

Comments

0

From testing, what is apparent is that if your go function hasn't completed, and you are still holding down a key, it's called again, meaning that now there's two go functions on the call stack (plus a bunch of other functions like eventfun and update). Because holding the key calls the go function many times a second, and the fact that the go function takes 8+ seconds to complete, you're filling up the call stack with calls to go, hence the crash. The call stack is just something like this repeated over and over:

update, __init__.py:1314
_update, turtle.py:561
_update, turtle.py:2663
_goto, turtle.py:3197
_go, turtle.py:1606
forward, turtle.py:1638
go, script.py:21
left, script.py:26
eventfun, turtle.py:700
__call__, __init__.py:1892

Even holding down left for just 3 seconds, my call stack grows to over 600, which is really high.

To fix this you could make it so that left or right cannot be called again while that key is still held down. That's one possible way.

Comments

Your Answer

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.