回溯法解决迷宫问题(加turtle可视化)

前言:好久好久没有更新博客了…今天乍一看竟然还涨了粉 不好意思的出来更新一下博客~
运行界面:

迷宫通过list赋值,采用0,1标记,即 0 表示通路,1表示墙
建立dirs序列,表示上下左右四个方向
可视化部分可以采用不同颜色标记实现路径的呈现
总的来说 功能实现包括三个部分:
  1. 冲突检测【当座标在迷宫范围内且相应值是可通行状态时 返回不冲突】
  2. 主函数部分
  3. 可视化部分
代码实现:
import copy,turtle
# 迷宫(1是墙,0是通路)
maze=\
         [[1,1,1,1,1,1,1,1,1,1,1,1,1,1],\
          [1,0,0,0,1,1,0,0,0,1,0,0,0,1],\
          [1,0,1,0,0,0,0,1,0,1,0,1,0,1],\
          [1,0,1,0,1,1,1,1,0,1,0,1,0,1],\
          [1,0,1,0,0,0,0,0,0,1,1,1,0,1],\
          [1,0,1,1,1,1,1,1,1,1,0,0,0,1],\
          [1,0,1,0,0,0,0,0,0,0,0,1,0,1],\
          [1,0,0,0,1,1,1,0,1,0,1,1,0,1],\
          [1,0,1,0,1,0,1,0,1,0,1,0,0,1],\
          [1,0,1,0,1,0,0,0,1,1,1,1,0,1],\
          [1,0,1,0,0,0,1,0,0,0,0,0,0,1],\
          [1,1,1,1,1,1,1,1,1,1,1,1,0,0]]
row = len(maze)# 行
column = len(maze[0])#列

n = 40  # 画图的每行间隔,小格子边长
x = -300  # x初始值
y = 200  # x初始值

entry = (1,0) #迷宫入口
exit = (row-1,column-1)# 迷宫出口
path = [entry] #一个解路径
paths = [] #一组解

# 移动的方向 上下, 左右
dirs = [(0,1),(0,-1),(1,0),(-1,0)]

# 冲突检测
def conflict(now_x,now_y): # 当前座标x,y
    #如果当前座标在maze范围内,且可通行 返回不冲突
    if 0<= now_x <row and 0<= now_y<column and maze[now_x][now_y] == 0:
        return  False
    return True # 否则 返回冲突

def main(now_x,now_y):
    global maze,path,paths,dirs,entry,row,column
    if (now_x,now_y)==exit:
        paths.append(path[:])
    else:
        for d in dirs:# 遍历四个方向
            new_x,new_y = now_x+d[0] ,now_y+d[1]
            path.append((new_x,new_y))# 新座标入栈
            if not conflict(new_x,new_y):
                maze[new_x][new_y] = 2 # 标记 2
                main(new_x,new_y) # 回溯
                maze[new_x][new_y] = 0 # 回溯 恢复
            path.pop() # 回溯 出栈

#解的可视化
"""
copy.copy 浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对象。
copy.deepcopy 深拷贝 拷贝对象及其子对象
"""
step = []
def show(path):
    global maze
    maze_2 = copy.deepcopy(maze) # 深拷贝
    for p in path:
        maze_2[p[0]][p[1]] = 2 # 通路
    draw(maze_2)
    turtle.done()

def draw_square(length: float, fill_color: str):
    """
    画正方形并填充
    :param length: 边长
    :param fill_color: 填充颜色
    :return: 无
    """
    turtle.pendown()
    turtle.begin_fill()
    turtle.fillcolor(fill_color)
    for index in range(4):
        turtle.forward(length)
        turtle.left(90)
    turtle.end_fill()
    turtle.penup()

def draw(maze_0):
    for i in range(row):
        for j in range(column):
            turtle.goto(x + j * n, y - i * n)
            if maze_0[i][j] == 1:  # 墙
                draw_square(n, "black")
            elif maze_0[i][j] == 0: # 可通行部分
                draw_square(n, "white")
            else:           # 行走部分
                draw_square(n-10,"pink")


if __name__ == '__main__':
    turtle.speed(200)
    turtle.pensize(2)
    turtle.setup(width=0.5, height=0.75, startx=30, starty=100)
    turtle.penup()
    (origin_x,origin_y) = entry
    main(origin_x,origin_y)
    print("一共有 "+str(len(paths))+" 条路径")
    if len(paths)!=0:
        show(paths[-1])# 手动修改查看不同走迷宫方式

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章