Search code examples
pythonturtle-graphicspython-turtle

The error "turtle.Terminator" occurs when using turtle


I have created a function which uses the turtle module in python:

def printmaze(sizeX, sizeY, walls):

    startX = -300
    startY = 300

    high = (-startX // sizeX) * 2
    width = (startY // sizeY) * 2

    turtle.clear()
    turtle.speed(0)
    turtle.penup()
    turtle.goto(-startX, startY)
    turtle.pendown()
    turtle.goto(-startX, -startY)
    turtle.goto(startX, -startY)

    turtle.setheading(0)
    for i in range(sizeX):
        turtle.penup()
        turtle.goto(startX, startY - high * i)
        for l in range(sizeY):
            if walls[i][l][1] ==  1:
                turtle.pendown()
            else:
                turtle.penup()
            turtle.forward(width)

    turtle.right(90)
    for i in range(sizeY):

        turtle.penup()
        turtle.goto(startX  + width * i, startY)
        for l in range(sizeX):

            if walls[l][i][0] ==  1:
                turtle.pendown()
            else:
                turtle.penup()
            turtle.forward(high)
    screen = turtle.Screen()
    screen.exitonclick()

When I execute this function for the first time, there is no error. However, when I execute it for the second time, it returns turtle.Terminator. Why is this happening?


Solution

  • Turtle uses a variable called _RUNNING which becomes false when .exitonclick() is called. So, you need to call turtle.Screen() at the beginning and call .exitonclick() at the end of the program. Both of them should be called outside the function. Modified code:

    #Import necessary modules
    import turtle
    
    screen = turtle.Screen() #At beginning outside function
    
    #Create the function to draw the maze
    def printmaze(sizeX, sizeY, walls):
        startX = -300
        startY = 300
    
        high = (-startX // sizeX) * 2
        width = (startY // sizeY) * 2
    
        turtle.clear()
        turtle.speed(0)
        turtle.penup()
        turtle.goto(-startX, startY)
        turtle.pendown()
        turtle.goto(-startX, -startY)
        turtle.goto(startX, -startY)
    
        turtle.setheading(0)
        for i in range(sizeX):
            turtle.penup()
            turtle.goto(startX, startY - high * i)
            for l in range(sizeY):
                if walls[i][l][1] ==  1:
                    turtle.pendown()
                else:
                    turtle.penup()
                turtle.forward(width)
    
        turtle.right(90)
        for i in range(sizeY):
    
            turtle.penup()
            turtle.goto(startX  + width * i, startY)
            for l in range(sizeX):
    
                if walls[l][i][0] ==  1:
                    turtle.pendown()
                else:
                    turtle.penup()
                turtle.forward(high)
    
    screen.exitonclick() #At the end outside the function
    

    You need to call screen = turtle.Screen() and .exitonclick() only once in your program. There is no need to call them every time the function is called. So, you need to put them outside the function.

    Edit:

    If the above method doesn't work, then you can manually set the _RUNNING variable to true after .exitonclick() is called. Modified code:

    #Import necessary modules
    import turtle
    
    screen = turtle.Screen() #At beginning outside function
    
    #Create the function to draw the maze
    def printmaze(sizeX, sizeY, walls):
        startX = -300
        startY = 300
    
        high = (-startX // sizeX) * 2
        width = (startY // sizeY) * 2
    
        turtle.clear()
        turtle.speed(0)
        turtle.penup()
        turtle.goto(-startX, startY)
        turtle.pendown()
        turtle.goto(-startX, -startY)
        turtle.goto(startX, -startY)
    
        turtle.setheading(0)
        for i in range(sizeX):
            turtle.penup()
            turtle.goto(startX, startY - high * i)
            for l in range(sizeY):
                if walls[i][l][1] ==  1:
                    turtle.pendown()
                else:
                    turtle.penup()
                turtle.forward(width)
    
        turtle.right(90)
        for i in range(sizeY):
    
            turtle.penup()
            turtle.goto(startX  + width * i, startY)
            for l in range(sizeX):
    
                if walls[l][i][0] ==  1:
                    turtle.pendown()
                else:
                    turtle.penup()
                turtle.forward(high)
    
    screen.exitonclick() #At the end outside the function
    
    turtle.TurtleScreen._RUNNING = True #Set the _RUNNING variable to true