【Python脚本】递归回溯法解迷宫

输入

控制台输入,一个迷宫,0表示此处不通,1表示是通路,这里拿一个21x11迷宫的来作为样例

000000000000000000000
011101110101111101010
000101000101000001010
011101110101011111110
000101000101010101000
011101111111110101110
000101000000000000000
011111111111111111010
010001000101000000010
010111011101111111110
000000000000000000000

迷宫大小,入口和出口的坐标在脚本中2~6行均可自行修改
迷宫宽高均从1开始算,出入口坐标均从0开始算

脚本

# 迷宫属性
MAZE_X = 21  # 宽度
MAZE_Y = 11  # 高度
start = (1, 1)  # 入口坐标(宽,高)
end = (19, 9)  # 出口坐标(宽,高)
MAZE = [[0 for i in range(MAZE_X)]for i in range(MAZE_Y)]

# 判断坐标的有效性
def isValid(maze, x, y):
    if (x >= 0 and x < len(maze) and y >= 0 and y < len(maze[0]) and maze[x][y] == 1):
        return True
    else:
        return False

def getPath(maze, start, end):
    ex = end[1]
    ey = end[0]
    x = start[1]
    y = start[0]
    ans = ""
    last = ""
    while 1:
        if x == ex and y == ey:
            return ans
        if maze[x][y+1] == 2 and last != 'a':  # d
            # print("d",end="")
            y = y+1
            last = "d"
            ans += "d"
        elif maze[x][y-1] == 2 and last != 'd':  # a
            # print("a",end="")
            y = y-1
            last = "a"
            ans += "a"
        elif maze[x+1][y] == 2 and last != 'w':  # s
            # print("s",end="")
            x = x+1
            last = "s"
            ans += "s"
        elif maze[x-1][y] == 2 and last != 's':  # w
            # print("w",end="")
            x = x-1
            last = "w"
            ans += "w"

def find(maze, x, y, ex, ey, successFlag):
    # 如果位置是迷宫的出口,说明成功走出迷宫
    if(x == ex and y == ey):
        maze[x][y] = 2
        successFlag = True
        return True
    if isValid(maze, x, y):
        maze[x][y] = 2  # 做标记,防止折回
        # 针对四个方向依次试探
        if find(maze, x-1, y, ex, ey, successFlag):  # 上
            pass
        elif find(maze, x, y-1, ex, ey, successFlag):  # 左
            pass
        elif find(maze, x+1, y, ex, ey, successFlag):  # 下
            pass
        elif find(maze, x, y+1, ex, ey, successFlag):  # 右
            pass
        else:
            # 走到这一步,要么是因为四周都没找路,需要撤销一步,要么是成功到达终点之后完成递归的返回
            if not successFlag:
                # 所以此处引入了successFlag变量,到达终点之后就会把successFlag设为True,如果此时还不是True说明四周无路可走
                maze[x][y] = 1  # 撤回这一步
                return False  # 无路可走,返回False
    else:
        return False
    return True


# 从控制台输入迷宫
for i in range(MAZE_Y):
    strIn = input()
    currentJ = 0
    for ss in strIn:
        MAZE[i][currentJ] = int(ss)
        currentJ = currentJ+1

if find(MAZE, start[1], start[0], end[1], end[0], False):
    # 反着传x,y的原因是,MAZE建立的时候第一个维度是Y(这样调试的时候看着方便)
    ans = getPath(MAZE, start, end)
    print(ans)
else:
    print("No Way")

输出

一行字符串,用wasd来表示上左下右的通路
上面那个迷宫的解法为:

ddssssssddddddddssdddddddd

如果找不到通路,则会输出

No Way

最后

此脚本暂只适用于路宽为1的迷宫,如果路宽不为1,会出现绕弯路的情况
如果使用时出现了错误,也欢迎留言及时纠正算法问题

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值