Python 迷宫求解;栈的回溯算法使用

代码需要在ipython解释器的环境下运行,用w代替迷宫的墙壁,o代表‘人物’

	 M M M M M M M M    
 	 M o         M M 
 	 M   M   M   M M 
 	 M     M       M 
 	 M   M     M   M 
 	 M     M   M   M 
 	 M M       M   M 
 	 M M M M M M M M 

比如现在要解决这样一个迷宫,墙壁是玩家给出的,这里给出的墙壁为word = [(1,  6), (2, 2), (2, 4), (2, 6), (3, 3),
        (4, 2), (4, 5), (5, 3), (5, 5), (6, 1), (6, 5)],同时要给出迷宫的范围n = 7 ,然后解迷过程给电脑进行,

'''
文件名:Maze.ipynb
时间:19年3月9号开始设计,尚未完善
作用:一个迷宫小游戏,可以让电脑解出玩家设计的迷宫,并且可以用字符图像的形式向用户展现解密过程
期望:将迷宫的正确路线记录下来,下次解密不用进行尝试。可以用这个迷宫解谜方法自动生成新的迷宫
制作人:peipei12138
'''
from random import randint
from IPython.display import clear_output
import time

# map_home用来给迷宫添加一个边界,返回添加边界后的迷宫
def map_home():
    map_n = list(word)

    for i in [0,n]: # 添加上下边界
        for j in range(n + 1):
            map_n.append((i, j))
    for i in range(1, n): # 添加左右边界
        map_n.append((i, 0))
        map_n.append((i, n))
    
    map_n.sort()
    return map_n

# neigh用来返回当前位置的‘邻居’方向
def neigh(new):
    (x, y) = new
    return [         (x -1, y),
            (x, y -1),         (x, y +1),
                     (x +1, y)]

# next_to用来返回下一步可以走的位置,需要排除有墙和之前走过的地方
def next_to(new):
    
    four_way = neigh(new)
    four_way_now = []; four_way_now_now = []
    
    for i in four_way: # 用来排除墙
        if i not in map_home():
            four_way_now.append(i)
    
    for j in four_way_now: # 用来排除走过的路径
        if j not in all_way:
            four_way_now_now.append(j)

    return four_way_now_now

# return_way函数用来将记录返回正确的路径,可以作为下一步前进错误之后的返回路径
# 这个函数用栈的方式去操作
def return_way(new):
    global turn_pio
    
    turn_pio.append(new)
    return turn_pio

# next_for用来定下前进的规则,并返回下一步到达的地方,作为新的new
def next_for(new):
    global turn_pio
    global all_way
    global fuud

    try:
        all_way.append(next_to(new)[randint(0, len(next_to(new)) -1)])
        fuud += 1
        new = all_way[-1]
        turn_pio = return_way(new)

    except:
        del turn_pio[-1]
        all_way.append(turn_pio[-1])
        fuud += 1
        new = all_way[-1]

    return new

# picture用来将这个迷宫画出来并返回
def picture(new):
    str_map = '\t' # 迷宫开头和每一行空八个字节
    Wall = 'M' # 用M当作迷宫的墙壁
    Where = 'o' # 用o表示当前位置
    LuJ = ' ' # 用 表示路径
    PAD = ' ' # 用 分割

    for i in range(n + 1):
        for j in range(n + 1):
            if (i, j) in map_home() :
                str_map += Wall
            elif (i, j) == new:
                str_map += Where
            else:
                str_map += LuJ 
        str_map += '\n\t'

    return PAD.join(str_map)

# run_self 给迷宫一个起点和一个终点,让这个迷宫自己跑起来
def run_self(new, ben, end):
    if n <= 5: TIME = 1 # 根据地图大小设置每次行走间隔时间
    else: TIME = 0.7

    while True:
        new = next_for(new) # 构成循环
        time.sleep(TIME) # 让图停顿,形成每一帧
        clear_output() # 删除上一个图

        print('现在走到了:', new, f'已经走了:{fuud}步')
        print(picture(new)) # 生成新的图

        if new == end:
            print('''
             WIN!
            *****
        成功到达了终点
             ''', f'\n走过的路径为:\n{all_way}'   )
            break
        if new == ben:
            print('可能这是一个没有终点的迷宫')
            break

 '''想要重新运行这个迷宫,得清空记录下来的数据'''
word = [(1,  6), (2, 2), (2, 4), (2, 6), (3, 3),
        (4, 2), (4, 5), (5, 3), (5, 5), (6, 1), (6, 5)]
n = 7

ben = (1, 1); end = (n -1, n -1) # 起点和终点
fuud = 0 # 记录步数
all_way = [ben] # 记录路径
turn_pio = [ben] # 记录正确\纠错路径

new = all_way[-1] # 初始位置   

run_self(new, ben, end) # 运行迷宫        

    迷宫的默认起点为(1,1),默认终点为(n-1,n-1),人物的前进是按照一定规则随机方向前进的,在上面的neigh(new)函数和其后面的3到4个函数都是规定其前进的函数。回溯算法也在其中得到了体现,将正确的路径记录到一个栈中,如果走到了错误的路径上,则将错误的路径出栈,回溯到正确的路径上,并让程序将错误的路径记录下来,让以后不再犯错误。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值