问题是我做了一个简短的算法,发现它穿过迷宫,并用蓝色标记了它访问过的所有正方形。核心程序工作正常,但问题是在整个过程完成后,GUI仅显示迷宫及其访问的方块。通常这不是问题,但是我必须能够清楚地看到算法在迷宫中移动。问题在于,当我在搜索算法的每次迭代中调用UpdateMaze
函数时,它似乎都不会生效,直到整个遍历完成为止。
import tkinter as tk
from tkinter import *
import time
class MazeGUI():
def __init__(self):
self.maze =[
[4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4],
[4, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 4],
[4, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 4],
[4, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 4],
[4, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 4],
[4, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 4],
[4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 4],
[4, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 4],
[4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 4],
[4, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 4],
[4, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 4],
[4, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 4],
[4, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 4],
[4, 0, 1, 2, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 4],
[4, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 4],
[4, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 4],
[4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4]
]
self.wall = tk.PhotoImage(file = "MazePiece_Wall.gif")
self.space = tk.PhotoImage(file = "MazePiece_Space.gif")
self.edge = tk.PhotoImage(file = "MazePiece_Outer.gif")
self.visited = tk.PhotoImage(file = "MazePiece_Visited.gif")
self.finish = tk.PhotoImage(file = "MazePiece_Finish.gif")
def UpdateMaze(self):
for y in range(len(self.maze)):
for x in range(len(self.maze[y])):
if self.maze[y][x] == 0:
label = Label(root, image=self.space,
width=20, height=20).grid(row=y, column=x)
elif self.maze[y][x] == 1:
label = Label(root, image=self.wall,
width=20, height=20).grid(row=y, column=x)
elif self.maze[y][x] == 2:
label = Label(root, image=self.finish,
width=20, height=20).grid(row=y, column=x)
elif self.maze[y][x] == 3:
label = Label(root, image=self.visited,
width=20, height=20).grid(row=y, column=x)
elif self.maze[y][x] == 4:
label = Label(root, image=self.edge,
width=20, height=20).grid(row=y, column=x)
def Move(Maze,x,y):
if Maze.maze[y][x] == 2:
return True
elif Maze.maze[y][x] == 1:
return False
elif Maze.maze[y][x] == 3:
return False
elif Maze.maze[y][x] == 4:
return False
Maze.maze[y][x] = 3
if ((x < len(Maze.maze)-1 and Move(Maze,x+1, y))
or (y > 0 and Move(Maze,x, y-1))
or (x > 0 and Move(Maze,x-1, y))
or (y < len(Maze.maze)-1 and Move(Maze,x, y+1))):
return True
return False
root = Tk()
Maze = MazeGUI()
root.lift()
StartPosX = 1
StartPosY = 1
Move(Maze,StartPosX,StartPosY)
Maze.UpdateMaze()
root.mainloop()
答案 0 :(得分:0)
我认为以下内容显示了如何做所需的基础知识。它使用tkinter
通用after()
方法来周期性地调用make_move()
方法,该方法最终会在每次移动后调用update_maze()
以重新显示迷宫。
看起来好像没有发生任何事情,但是过一会儿您应该会看到显示的迷宫发生了变化。由于使用了我介绍的random
模块来生成下一步操作,因此确切需要花费多长时间,因为我真的不了解在Move()
函数中执行此操作的逻辑在您的示例代码中。这正是可能需要“修复”以使其完全符合您要完成的目标的目的。
注意:我还更改了代码,以便在代码格式设置以及类,函数,变量等的命名方面更紧密地遵循PEP 8 - Style Guide for Python Code,以使其更具可读性(IMO)。
from random import randint
import tkinter as tk
from tkinter import *
import time
MOVE_DELAY = 1000 # Time delay between moves in millisec.
class MazeGUI():
SPACE = 0
WALL = 1
FINISH = 2
VISITED = 3
EDGE = 4
def __init__(self):
self.maze = [
[4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4],
[4, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 4],
[4, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 4],
[4, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 4],
[4, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 4],
[4, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 4],
[4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 4],
[4, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 4],
[4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 4],
[4, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 4],
[4, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 4],
[4, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 4],
[4, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 4],
[4, 0, 1, 2, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 4],
[4, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 4],
[4, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 4],
[4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4]
]
self.wall = tk.PhotoImage(file="MazePiece_Wall.gif") # black
self.space = tk.PhotoImage(file="MazePiece_Space.gif") # white
self.edge = tk.PhotoImage(file="MazePiece_Outer.gif") # red
self.finish = tk.PhotoImage(file="MazePiece_Finish.gif") # green
self.visited = tk.PhotoImage(file="MazePiece_Visited.gif") # blue
self.create_maze()
def create_maze(self):
global root
self.maze_frame = tk.Frame(root)
self.create_maze_labels()
self.maze_frame.pack()
def update_maze(self):
global root
self.maze_frame.grid_forget() # Remove all the existing Labels.
self.create_maze_labels()
self.maze_frame.update_idletasks() # Update display.
def create_maze_labels(self):
for y in range(len(self.maze)):
for x in range(len(self.maze[y])):
if self.maze[y][x] == self.SPACE:
Label(self.maze_frame, image=self.space,
width=20, height=20).grid(row=y, column=x)
elif self.maze[y][x] == self.WALL:
Label(self.maze_frame, image=self.wall,
width=20, height=20).grid(row=y, column=x)
elif self.maze[y][x] == self.FINISH:
Label(self.maze_frame, image=self.finish,
width=20, height=20).grid(row=y, column=x)
elif self.maze[y][x] == self.VISITED:
Label(self.maze_frame, image=self.visited,
width=20, height=20).grid(row=y, column=x)
elif self.maze[y][x] == self.EDGE:
Label(self.maze_frame, image=self.edge,
width=20, height=20).grid(row=y, column=x)
def make_move(self, x, y):
global root
status = self.move(x, y)
# if status: # Not sure what to do with return value...
self.update_maze()
# Select a random adjoining cell (dx & dy both +/-1).
dx, dy = randint(0, 2) - 1, randint(0, 2) - 1
x, y = x+dx, y+dy # Next position.
root.after(MOVE_DELAY, self.make_move, x, y) # Repeat...
def move(self, x, y):
if self.maze[y][x] == self.FINISH:
return True
elif self.maze[y][x] == self.WALL:
return False
elif self.maze[y][x] == self.VISITED:
return False
elif self.maze[y][x] == self.EDGE:
return False
# Spot is empty (self.SPACE).
self.maze[y][x] = self.VISITED
if ((x < len(self.maze)-1 and self.move(x+1, y))
or (y > 0 and self.move(x, y-1))
or (x > 0 and self.move(x-1, y))
or (y < len(self.maze)-1 and self.move(x, y+1))):
return True
return False
root = Tk()
maze = MazeGUI()
start_posx, start_posy = 1, 1
maze.make_move(start_posx, start_posy)
maze.update_maze()
root.mainloop()
P.S。对于感兴趣的人,以下是我制作并用于测试的.gif
图像(因此您可以下载它们以运行代码):
MazePiece_Finish.gif
MazePiece_Outer.gif
! MazePiece_Space.gif
MazePiece_Visited.gif
MazePiece_Wall.gif