代码需要在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个函数都是规定其前进的函数。回溯算法也在其中得到了体现,将正确的路径记录到一个栈中,如果走到了错误的路径上,则将错误的路径出栈,回溯到正确的路径上,并让程序将错误的路径记录下来,让以后不再犯错误。