【问题标题】:How to get rid of the while loop for my left hand algorithm如何摆脱我的左手算法的while循环
【发布时间】:2020-11-20 08:11:59
【问题描述】:

目前我正在尝试摆脱左手算法中的 while 循环。之所以要删除它,是因为我阅读了 2 个堆栈帖子 herehere。两者都由@cdlane 回答,他删除了while 循环并重建了一个新函数。我真的很感谢这位先生,他帮助解决了我以前遇到的很多问题。我知道这背后的原因是因为 while 循环阻止代码到达 mainloop() 方法。我在帖子中看到了该答案作为替代,但是我该如何修改它,因为在这种情况下,我的不是乌龟onkey 事件,而是当我调用受乌龟影响的类时要调用的函数标题。

这是我的算法:

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()

【问题讨论】:

    标签: python python-3.x python-turtle


    【解决方案1】:

    我相信我已经按照您描述的方式修改了您的代码,将 while True 循环替换为定时事件。您可以随时单击窗口结束程序。我将您的UpDown 等方法更改为返回TrueFalse 以指示是否已到达完成图块,而不是自行结束程序。这样,这些方法的结果可用于确定是否保持定时事件继续进行:

    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
    

    【讨论】:

    • 看起来你正在解决所有问题。感谢您跟踪并提供帮助。你摇滚!!!
    猜你喜欢
    • 1970-01-01
    • 2022-12-02
    • 2014-09-05
    • 1970-01-01
    • 1970-01-01
    • 2016-09-25
    • 2014-03-28
    • 2022-12-18
    • 1970-01-01
    相关资源
    最近更新 更多