使用 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,以及 getitemsetitem 采用索引元组的方法。根据 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]