pythonturtle-graphicspython-turtlerecursionerror

How to fix a RecursionError in Turtle?


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?


Solution

  • 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.