使用 tkinter 可视化 A Star 搜索算法
Use tkinter to visualize A Star search algorithm
我已经编写了一个 A* 搜索算法,并希望使用 tkinter 以图形方式(实时)可视化搜索,如下图所示,只是一个更简单的版本,没有菜单、单元格中的数字、以前尝试过的路径或对角线路径。
换句话说,我只需要显示一个网格,其中包含 7 种可能的纹理(起点、终点、路径、障碍物、开放节点、封闭节点、未尝试),当基础矩阵发生变化时,它会自动更新。
可以说,这个轮廓或建筑看起来如何?我已经有一个 2x2 矩阵,其中包含每个节点状态的值(开始..障碍物等等),我如何在每次更改时使用 tkinter 来显示该矩阵?
到目前为止,我得到了这个:
def main():
theMap = .. # initial map with start, finish and obstacles
root = Tk()
my_gui = CellGrid(root,n,m,40,theMap)
root.mainloop()
class CellGrid(Canvas):
def __init__(self,master, rowNumber, columnNumber, cellSize, theMap):
Canvas.__init__(self, master, width = cellSize * columnNumber , height = cellSize * rowNumber)
self.cellSize = cellSize
self.grid = []
for row in range(rowNumber):
line = []
for column in range(columnNumber):
line.append(Cell(self, column, row, cellSize, theMap[row][column]))
self.grid.append(line)
print self.grid[0][0].value
self.draw()
def draw(self):
for row in self.grid:
for cell in row:
cell.draw()
class Cell():
START_COLOR = "green"
FINISH_COLOR = "red"
UNTRIED_COLOR = "white"
CLOSED_COLOR = "gray"
OPEN_COLOR = "blue"
OBSTACLE_COLOR = "black"
PATH_COLOR = "orange"
def __init__(self, master, x, y, size, value):
self.master = master
self.abs = x
self.ord = y
self.size= size
self.fill = "white"
self.value = value
def setValue(self, value):
self.value = value
def draw(self):
""" order to the cell to draw its representation on the canvas """
if self.master != None :
if self.value == 0:
self.fill = self.UNTRIED_COLOR
elif self.value == 1:
self.fill = self.OBSTACLE_COLOR
elif self.value == 2:
self.fill = self.START_COLOR
elif self.value == 3:
self.fill = self.FINISH_COLOR
elif self.value == 4:
self.fill = self.OPEN_COLOR
elif self.value == 5:
self.fill = self.CLOSED_COLOR
elif self.value == 6:
self.fill = self.PATH_COLOR
xmin = self.abs * self.size
xmax = xmin + self.size
ymin = self.ord * self.size
ymax = ymin + self.size
self.master.create_rectangle(xmin, ymin, xmax, ymax, fill = self.fill, outline = "black")
想法是绘制初始地图(theMap),它只包含起点、终点和障碍节点。然后,当 A* 更改节点时,它可以使用节点的新值调用 CellGrid 中的方法,然后更新该值并绘制相应的纹理。
但是我做不到那么远。当我 运行 上面的代码时,我什么也没得到,只有一个空的 Tk window。怎么了?
张贴的代码没有运行。它确实(使用 3.x),当它开始时,例如,使用
from tkinter import *
def main():
Map = [
[2, 0, 0, 0, 0],
[0, 1, 1, 1, 1],
[0, 1, 3, 0, 0],
[0, 1, 1, 1, 0],
[0, 0, 0, 0, 0],
]
root = Tk()
my_gui = CellGrid(root, len(Map), len(Map[0]), 40, Map)
root.mainloop()
并在打印语句中添加括号。
print(self.grid[0][0].value) # harmless in 2.7
并以 main()
结尾。使用简单的数据对开发很有帮助
要回答您的直接问题,使 canvas 可见需要在 Canvas 初始化后添加 self.pack
。这样,上面的地图就会按预期显示。
为了回答您的体系结构问题,我建议采用不同的方法。定义一个自定义 Map class,其中包含您当前称为 theMap 的列表列表,一个 Canvas,以及 getitem 和 setitem 采用索引元组的方法。根据 amap[(i,j)] 编写 A* 函数。 setitem 方法将负责设置数组和 canvas.
Python款式注意:以上所有色码都可以替换成
colors = {
0: 'white', # untried
1: 'black', # obstacle
2: 'green', # start
3: 'red', # finish
4: 'blue', # open
5: 'gray', # closed
6: 'orange', # path
}
随后是 create_rectangle 调用中的 fill=colors[self.value]
。
我已经编写了一个 A* 搜索算法,并希望使用 tkinter 以图形方式(实时)可视化搜索,如下图所示,只是一个更简单的版本,没有菜单、单元格中的数字、以前尝试过的路径或对角线路径。
换句话说,我只需要显示一个网格,其中包含 7 种可能的纹理(起点、终点、路径、障碍物、开放节点、封闭节点、未尝试),当基础矩阵发生变化时,它会自动更新。
可以说,这个轮廓或建筑看起来如何?我已经有一个 2x2 矩阵,其中包含每个节点状态的值(开始..障碍物等等),我如何在每次更改时使用 tkinter 来显示该矩阵?
到目前为止,我得到了这个:
def main():
theMap = .. # initial map with start, finish and obstacles
root = Tk()
my_gui = CellGrid(root,n,m,40,theMap)
root.mainloop()
class CellGrid(Canvas):
def __init__(self,master, rowNumber, columnNumber, cellSize, theMap):
Canvas.__init__(self, master, width = cellSize * columnNumber , height = cellSize * rowNumber)
self.cellSize = cellSize
self.grid = []
for row in range(rowNumber):
line = []
for column in range(columnNumber):
line.append(Cell(self, column, row, cellSize, theMap[row][column]))
self.grid.append(line)
print self.grid[0][0].value
self.draw()
def draw(self):
for row in self.grid:
for cell in row:
cell.draw()
class Cell():
START_COLOR = "green"
FINISH_COLOR = "red"
UNTRIED_COLOR = "white"
CLOSED_COLOR = "gray"
OPEN_COLOR = "blue"
OBSTACLE_COLOR = "black"
PATH_COLOR = "orange"
def __init__(self, master, x, y, size, value):
self.master = master
self.abs = x
self.ord = y
self.size= size
self.fill = "white"
self.value = value
def setValue(self, value):
self.value = value
def draw(self):
""" order to the cell to draw its representation on the canvas """
if self.master != None :
if self.value == 0:
self.fill = self.UNTRIED_COLOR
elif self.value == 1:
self.fill = self.OBSTACLE_COLOR
elif self.value == 2:
self.fill = self.START_COLOR
elif self.value == 3:
self.fill = self.FINISH_COLOR
elif self.value == 4:
self.fill = self.OPEN_COLOR
elif self.value == 5:
self.fill = self.CLOSED_COLOR
elif self.value == 6:
self.fill = self.PATH_COLOR
xmin = self.abs * self.size
xmax = xmin + self.size
ymin = self.ord * self.size
ymax = ymin + self.size
self.master.create_rectangle(xmin, ymin, xmax, ymax, fill = self.fill, outline = "black")
想法是绘制初始地图(theMap),它只包含起点、终点和障碍节点。然后,当 A* 更改节点时,它可以使用节点的新值调用 CellGrid 中的方法,然后更新该值并绘制相应的纹理。
但是我做不到那么远。当我 运行 上面的代码时,我什么也没得到,只有一个空的 Tk window。怎么了?
张贴的代码没有运行。它确实(使用 3.x),当它开始时,例如,使用
from tkinter import *
def main():
Map = [
[2, 0, 0, 0, 0],
[0, 1, 1, 1, 1],
[0, 1, 3, 0, 0],
[0, 1, 1, 1, 0],
[0, 0, 0, 0, 0],
]
root = Tk()
my_gui = CellGrid(root, len(Map), len(Map[0]), 40, Map)
root.mainloop()
并在打印语句中添加括号。
print(self.grid[0][0].value) # harmless in 2.7
并以 main()
结尾。使用简单的数据对开发很有帮助
要回答您的直接问题,使 canvas 可见需要在 Canvas 初始化后添加 self.pack
。这样,上面的地图就会按预期显示。
为了回答您的体系结构问题,我建议采用不同的方法。定义一个自定义 Map class,其中包含您当前称为 theMap 的列表列表,一个 Canvas,以及 getitem 和 setitem 采用索引元组的方法。根据 amap[(i,j)] 编写 A* 函数。 setitem 方法将负责设置数组和 canvas.
Python款式注意:以上所有色码都可以替换成
colors = {
0: 'white', # untried
1: 'black', # obstacle
2: 'green', # start
3: 'red', # finish
4: 'blue', # open
5: 'gray', # closed
6: 'orange', # path
}
随后是 create_rectangle 调用中的 fill=colors[self.value]
。