0

Currently i am trying to get rid of a while loop in my left hand algorithm. The reason being as to why i wanted to remove it is because i read 2 stack posts here and here. Both are answered by @cdlane, whereby he removed the while loop and reconstruct a new function. I really thank that sir for he helped solve quite a number of problems i previously encountered. I understand that the reasoning behind this is because the while loop prevents the code from reaching till the mainloop() method. I saw that answer in the post as an alternative, but how do i modify it, because in this case, mine is not a turtle onkey event, but functions to be called when i invoke the class, which is subjected to the turtle heading.

Here is my algorithm:

from turtle import * # import the turtle library

# define the tile_size and cursor_size for usage later on
TILE_SIZE = 24 
CURSOR_SIZE = 20

class Wall(Turtle): # create Wall class to plot out the walls
    def __init__(self):
        super().__init__(shape='square') # inherit from Turtle(parent class)
        self.hideturtle() # hide the cursor
        self.shapesize(TILE_SIZE / CURSOR_SIZE) # define the size of the square
        self.pencolor('black') #  define the color that we are going to plot the grids out
        self.penup() # to prevent the pen from leaving a trace
        self.speed('fastest') # get the fastest speed

class Path(Wall): # create Path class to plot out the path
    def __init__(self):
        super().__init__() # inherit from Turtle(parent class)
        self.pencolor('white') #  define the color that we are going to plot the grids out

class Sprite(Turtle): # create Sprite class to define the turtle and its characteristics
    def __init__(self):
        super().__init__(shape='turtle') # inherit from Turtle(parent class)
        self.shapesize((TILE_SIZE / CURSOR_SIZE)-0.4) # define the size of the square
        self.color('orange') #  define the color that we are going to plot the turtle
        self.penup() # to prevent the pen from leaving a trace while shifting to the starting point
        self.goto(start_x, start_y) # move the turtle to the position
        self.speed('fastest') # set speed to slowest to observe the sprite movement


############## algorithms and manual movement here  ######################

class LeftHandAlgorithm(Sprite): # create LeftHandAlgorithm class to define how the sprite moves with LHA
    def __init__(self):
        super().__init__() # inherit from the Sprite class
        # self.hideturtle() # hide the cursor
        self.moves = 0 # create a counter to count the number of steps
        self.goto(start_x, start_y) # move the turtle to the position
        self.pendown()
        
    def spriteUp(self): # create a spriteUp function to control the turtle if it wants to move downwards
        if (self.heading() == 90): # see if sprite is facing downwards
            x_walls = round(self.xcor(), 0) # sprite x coordinates
            y_walls = round(self.ycor(), 0) # sprite y coordinates
            if (x_walls, y_walls) in finish: # check if coordinates is ald at finish point
                print('Finished Left Hand Algorithm!')
                endProgram() # exit the entire program upon clicking anywhere in the turtle window
            if ((x_walls - 24), y_walls) in walls: # check if the walls are on the left
                if (x_walls, (y_walls + 24)) not in walls: # check if the path ahead it is facing is clear
                    self.forward(24) # move forward by 1 step
                else:
                    self.right(90) # if it is blocked, turn 90 clockwise right
            else:
                self.left(90) # turn 90 deg left
                self.forward(24) # move forward by 1 step

    def spriteDown(self): # create a spriteUp function to control the turtle if it wants to move upwards
        if (self.heading() == 270): # see if sprite is facing downwards
            x_walls = round(self.xcor(), 0) # sprite x coordinates
            y_walls = round(self.ycor(), 0) # sprite y coordinates
            if (x_walls, y_walls) in finish: # check if coordinates is ald at finish point
                print('Finished Left Hand Algorithm!')
                endProgram() # exit the entire program upon clicking anywhere in the turtle window
            if ((x_walls + 24), y_walls) in walls: # check if the walls are on the left
                if (x_walls, (y_walls - 24)) not in walls: # check if the path ahead it is facing is clear
                    self.forward(24) # move forward by 1 step
                else:
                    self.right(90) # if it is blocked, turn 90 clockwise right
            else:
                self.left(90) # turn 90 deg left
                self.forward(24) # move forward by 1 step

    def spriteLeft(self): # create a spriteUp function to control the turtle if it wants to move leftwards
        if (self.heading() == 180): # see if sprite is facing downwards
            x_walls = round(self.xcor(), 0) # sprite x coordinates
            y_walls = round(self.ycor(), 0) # sprite y coordinates
            if (x_walls, y_walls) in finish: # check if coordinates is ald at finish point
                print('Finished Left Hand Algorithm!')
                endProgram() # exit the entire program upon clicking anywhere in the turtle window
            if (x_walls, (y_walls - 24)) in walls: # check if the walls are on the left
                if ((x_walls - 24), y_walls) not in walls: # check if the path ahead it is facing is clear
                    self.forward(24) # move forward by 1 step
                else:
                    self.right(90) # if it is blocked, turn 90 clockwise right
            else:
                self.left(90) # turn 90 deg left
                self.forward(24) # move forward by 1 step

    def spriteRight(self): # create a spriteUp function to control the turtle if it wants to move rightside
        if (self.heading() == 0): # see if sprite is facing downwards
            x_walls = round(self.xcor(), 0) # sprite x coordinates
            y_walls = round(self.ycor(), 0) # sprite y coordinates
            if (x_walls, y_walls) in finish: # check if coordinates is ald at finish point
                print('Finished Left Hand Algorithm!')
                endProgram() # exit the entire program upon clicking anywhere in the turtle window
            if (x_walls, (y_walls + 24)) in walls: # check if the walls are on the left
                if ((x_walls + 24), y_walls) not in walls: # check if the path ahead it is facing is clear
                    self.forward(24) # move forward by 1 step
                else:
                    self.right(90) # if it is blocked, turn 90 clockwise right
            else:
                self.left(90) # turn 90 deg left
                self.forward(24) # move forward by 1 step

def setup_maze(level): # create a setup_maze function so that we can plot out the map in turtle

    # declare maze_height and maze_width first as the limits for the entire maze
    maze_height, maze_width = len(level), len(level[0])

    # get the center point for each maze
    center_horizontal_point = (maze_width + 1) / 2
    center_vertical_point = (maze_height + 1) / 2    

    for y in range(maze_height): # for loop to limit the entire maze
        for x in range(maze_width):
            character = level[y][x] # get the character at each x,y coordinate

            # calculate the screen x, y coordinates
            screen_x = int((x - maze_width) * TILE_SIZE) + (center_horizontal_point * TILE_SIZE)
            screen_y = int((maze_height - y) * TILE_SIZE) - (center_vertical_point * TILE_SIZE)

            if character == "X":
                maze.fillcolor('grey')
                maze.goto(screen_x, screen_y)
                maze.stamp()
                walls.append((screen_x, screen_y)) # add coordinates for the wall to the list
            else:
                maze.fillcolor('white')
                maze.goto(screen_x, screen_y)
                maze.stamp()
                paths.append((screen_x, screen_y)) # add coordinates for the path to the list

            if character == "e":
                maze.fillcolor(['white', 'red'][character == 'e'])
                maze.goto(screen_x, screen_y) # proceed on to the coordinates on turtle
                maze.stamp() # stamp out the boxes
                finish.append((screen_x, screen_y)) # add coordinates for the endpoint to the list             

            if character == 's': # if statement to determine if the character is s
                maze.fillcolor('green')
                maze.goto(screen_x, screen_y)
                maze.stamp() # stamp out the boxes
                start.append((screen_x, screen_y)) # add coordinates for the startpoint to the list

def endProgram(): # exit the entire program upon clicking anywhere in the turtle window
    screen.exitonclick()

grid = []                               # create a grid list to store the labels while reading from the txt file
walls = []                              # create walls coordinate list
start = []
finish = []                             # enable the finish array
paths = []

with open("map11.txt") as file:         # open the txt file and read contents and append it to maze
    for line in file:
        grid.append(line.strip())

screen = Screen() # instantiate the Screen class from turtle
screen.setup(700, 700) # determine the size of the turtle pop out window

maze = Wall()                           # enable the Wall class
path = Path()                           # enable the Path class

setup_maze(grid)   
start_x, start_y = int((start[0])[0]), int((start[0])[1])

spriteLHA = LeftHandAlgorithm()                       # enable the Sprite class for Left Hand Algorithm

while True:
            spriteLHA.spriteUp()
            spriteLHA.spriteDown()
            spriteLHA.spriteLeft()
            spriteLHA.spriteRight()

screen.listen()
screen.mainloop()
prodoggy4life
  • 317
  • 1
  • 6
  • 16

1 Answers1

2

I believe I've modified your code along the lines you describe, replacing the while True loop with a timed event. At any point you can click on the window to end the program. I changed your Up, Down, etc. methods to return True or False to indicate if the finish tile has been reached, rather than end the program themselves. That way, the results of these methods can be used to determined whether or not to keep the timed event going:

from turtle import Screen, Turtle  # import the turtle library

# define the tile_size and cursor_size for usage later on
TILE_SIZE = 24
CURSOR_SIZE = 20

class Wall(Turtle):  # create Wall class to plot out the walls
    def __init__(self):
        super().__init__(shape='square')  # inherit from Turtle(parent class)
        self.hideturtle()  # hide the cursor
        self.shapesize(TILE_SIZE / CURSOR_SIZE)  # define the size of the square
        self.pencolor('black')  # define the color that we are going to plot the grids out
        self.penup()  # to prevent the pen from leaving a trace
        self.speed('fastest')  # get the fastest speed

class Path(Wall):  # create Path class to plot out the path
    def __init__(self):
        super().__init__()  # inherit from Turtle(parent class)
        self.pencolor('white')  # define the color that we are going to plot the grids out

class Sprite(Turtle):  # create Sprite class to define the turtle and its characteristics
    def __init__(self):
        super().__init__(shape='turtle')  # inherit from Turtle(parent class)
        self.shapesize((TILE_SIZE / CURSOR_SIZE)-0.4)  # define the size of the square
        self.color('orange')  # define the color that we are going to plot the turtle
        self.penup()  # to prevent the pen from leaving a trace while shifting to the starting point
        self.goto(start_x, start_y)  # move the turtle to the position
        self.speed('fastest')  # set speed to slowest to observe the sprite movement

############## algorithms and manual movement here  ######################

class LeftHandAlgorithm(Sprite):  # create LeftHandAlgorithm class to define how the sprite moves with LHA
    def __init__(self):
        super().__init__()  # inherit from the Sprite class
        # self.hideturtle()  # hide the cursor
        self.moves = 0  # create a counter to count the number of steps
        self.goto(start_x, start_y)  # move the turtle to the position
        self.pendown()

    def spriteUp(self):  # create a spriteUp function to control the turtle if it wants to move downwards
        if self.heading() == 90:
            x_walls = round(self.xcor(), 0)  # sprite x coordinates
            y_walls = round(self.ycor(), 0)  # sprite y coordinates
            if (x_walls, y_walls) in finish:  # check if coordinates is at finish point
                print("Finished Left Hand Algorithm!")
                return False

            if ((x_walls - 24), y_walls) in walls:  # check if the walls are on the left
                if (x_walls, (y_walls + 24)) not in walls:  # check if the path ahead it is facing is clear
                    self.forward(24)  # move forward by 1 step
                else:
                    self.right(90)  # if it is blocked, turn 90 clockwise right
            else:
                self.left(90)  # turn 90 deg left
                self.forward(24)  # move forward by 1 step

        return True

    def spriteDown(self):  # create a spriteUp function to control the turtle if it wants to move upwards
        if self.heading() == 270:
            x_walls = round(self.xcor(), 0)  # sprite x coordinates
            y_walls = round(self.ycor(), 0)  # sprite y coordinates
            if (x_walls, y_walls) in finish:  # check if coordinates is at finish point
                print("Finished Left Hand Algorithm!")
                return False

            if ((x_walls + 24), y_walls) in walls:  # check if the walls are on the left
                if (x_walls, (y_walls - 24)) not in walls:  # check if the path ahead it is facing is clear
                    self.forward(24)  # move forward by 1 step
                else:
                    self.right(90)  # if it is blocked, turn 90 clockwise right
            else:
                self.left(90)  # turn 90 deg left
                self.forward(24)  # move forward by 1 step

        return True

    def spriteLeft(self):  # create a spriteUp function to control the turtle if it wants to move leftwards
        if self.heading() == 180:
            x_walls = round(self.xcor(), 0)  # sprite x coordinates
            y_walls = round(self.ycor(), 0)  # sprite y coordinates
            if (x_walls, y_walls) in finish:  # check if coordinates is at finish point
                print("Finished Left Hand Algorithm!")
                return False

            if (x_walls, (y_walls - 24)) in walls:  # check if the walls are on the left
                if ((x_walls - 24), y_walls) not in walls:  # check if the path ahead it is facing is clear
                    self.forward(24)  # move forward by 1 step
                else:
                    self.right(90)  # if it is blocked, turn 90 clockwise right
            else:
                self.left(90)  # turn 90 deg left
                self.forward(24)  # move forward by 1 step

        return True

    def spriteRight(self):  # create a spriteUp function to control the turtle if it wants to move rightside
        if self.heading() == 0:
            x_walls = round(self.xcor(), 0)  # sprite x coordinates
            y_walls = round(self.ycor(), 0)  # sprite y coordinates
            if (x_walls, y_walls) in finish:  # check if coordinates is at finish point
                print("Finished Left Hand Algorithm!")
                return False

            if (x_walls, (y_walls + 24)) in walls:  # check if the walls are on the left
                if ((x_walls + 24), y_walls) not in walls:  # check if the path ahead it is facing is clear
                    self.forward(24)  # move forward by 1 step
                else:
                    self.right(90)  # if it is blocked, turn 90 clockwise right
            else:
                self.left(90)  # turn 90 deg left
                self.forward(24)  # move forward by 1 step

        return True

def setup_maze(level):  # create a setup_maze function so that we can plot out the map in turtle

    # declare maze_height and maze_width first as the limits for the entire maze
    maze_height, maze_width = len(level), len(level[0])

    # get the center point for each maze
    center_horizontal_point = (maze_width + 1) / 2
    center_vertical_point = (maze_height + 1) / 2

    for y in range(maze_height):  # for loop to limit the entire maze
        for x in range(maze_width):
            character = level[y][x]  # get the character at each x,y coordinate

            # calculate the screen x, y coordinates
            screen_x = int((x - maze_width) * TILE_SIZE) + (center_horizontal_point * TILE_SIZE)
            screen_y = int((maze_height - y) * TILE_SIZE) - (center_vertical_point * TILE_SIZE)

            if character == 'X':
                maze.fillcolor('grey')
                maze.goto(screen_x, screen_y)
                maze.stamp()
                walls.append((screen_x, screen_y))  # add coordinates for the wall to the list
            else:
                maze.fillcolor('white')
                maze.goto(screen_x, screen_y)
                maze.stamp()
                paths.append((screen_x, screen_y))  # add coordinates for the path to the list

            if character == 'e':
                maze.fillcolor(['white', 'red'][character == 'e'])
                maze.goto(screen_x, screen_y)  # proceed on to the coordinates on turtle
                maze.stamp()  # stamp out the boxes
                finish.append((screen_x, screen_y))  # add coordinates for the endpoint to the list

            if character == 's':  # if statement to determine if the character is s
                maze.fillcolor('green')
                maze.goto(screen_x, screen_y)
                maze.stamp()  # stamp out the boxes
                start.append((screen_x, screen_y))  # add coordinates for the startpoint to the list

grid = []  # create a grid list to store the labels while reading from the txt file
walls = []  # create walls coordinate list
start = []
finish = []
paths = []

with open("map11.txt") as file:  # open the txt file and read contents and append it to maze
    for line in file:
        grid.append(line.strip())

screen = Screen()  # instantiate the Screen class from turtle
screen.setup(700, 700)  # determine the size of the turtle pop out window

maze = Wall()
path = Path()

setup_maze(grid)
start_x, start_y = int((start[0])[0]), int((start[0])[1])

spriteLHA = LeftHandAlgorithm()  # enable the Sprite class for Left Hand Algorithm

def run():
    if spriteLHA.spriteUp() and spriteLHA.spriteDown() and spriteLHA.spriteLeft() and spriteLHA.spriteRight():
        screen.ontimer(run)

run()

screen.exitonclick()  # exit the entire program upon clicking anywhere in the turtle window
cdlane
  • 40,441
  • 5
  • 32
  • 81