首先说明一下,迷宫有两种走法:上帝模式和凡人模式
凡人模式就是你是第一人称视角在迷宫里走,并不知道迷宫布局
上帝模式就是从天上看,迷宫布局一目了然
本文实现的是上帝模式,先说说思路:如果遍历整个迷宫所有的路径,你得到的结果只有两种:死胡同和终点
反过来如果把所有死胡同的路径都拿掉,则剩下的就是正解
顺着这个思路看看用python如何实现:将迷宫看成一个矩阵(M),用0代表墙,用1代表路
再生成一个矩阵(N),每个格子(墙/路)的值等于M中横向和纵向相邻的格子的值的和
N中值为2的格子就是死胡同
死胡同回溯到岔路的M所有格子都设置为墙
剩下的就是正解
推荐一个迷宫生成器网站:http://www.mazegenerator.net/www.mazegenerator.net
生成一个200x200的迷宫,可以将生成的迷宫导出png格式到本地
下面的代码仅适配上面网站生成的png图片
import sys
import numpy as np
from PIL import Image, ImageDraw
import math
import re
wallclr = 0, 0, 0, 255
pathclr = 255, 255, 255, 255
soluclr = 25, 121, 202, 255
def automaze(pic):
# solution picture
spic = pic
if spic[0] == '.' and spic[1] == '\\':
spic = "solution_" + spic[2:]
# open and load image pixels
img = Image.open(pic)
px = img.load()
# variable initialization
sp, ep, x, y, mazeD, wallW = None, None, 0, 0, 16, 2
pathW = mazeD - wallW
mazeW = math.floor(img.size[0] / mazeD) * 2 + 1
mazeH = math.floor(img.size[1] / mazeD) * 2 + 1
mx, my = 0, 0
# create a matrix for representing the path and wall
matrix = np.zeros((mazeH, mazeW))
# initialize the matrix - 0: wall, 1: path
for y in range(mazeH):
mx = 0
for x in range(mazeW):
if px[mx, my] == pathclr:
matrix[y, x] = 1
mx = mx + wallW if x % 2 == 0 else mx + pathW
my = my + wallW if y % 2 == 0 else my + pathW
# sum of horizontal and veritcal surrounding nodes
smatrix = np.zeros((mazeH, mazeW))
for r in range(mazeH):
for c in range(mazeW):
if matrix[r, c] == 1:
# got a path
if r == 0 or r == mazeH - 1:
# mark the Entrance and Exit node as 1
smatrix[r, c] = 1
else:
# sum of horizontal and vertical surrounding nodes
smatrix[r, c] = np.sum(matrix[r-1:r+2, c]) + np.sum(matrix[r, c-1:c+2]) - 1
# recusively remove dead end whose value is 2
while True:
deads = np.where(smatrix == 2)
if len(deads[0]) == 0:
# no more dead ends
break
pos = list(zip(deads[0], deads[1]))
for p in pos:
# decreasing value of dead end nodes and their horizontal and vertical adjacent nodes
smatrix[p[0]-1:p[0]+2, p[1]] -= 1
smatrix[p[0], p[1]-1:p[1]+2] -= 1
smatrix[p] += 1
# remove the dead end nodes
matrix[p] = 0
#smatrix[smatrix < 0] = 0
# draw the solution on the maze
mx, my = 0, 0
for y in range(mazeH):
mx = 0
for x in range(mazeW):
if matrix[y, x] == 1:
if x % 2 == 0:
for i in range(2):
for j in range(14):
px[mx + i, my + j] = soluclr
elif y % 2 == 0:
for i in range(14):
for j in range(2):
px[mx + i, my + j] = soluclr
else:
for i in range(14):
for j in range(14):
px[mx + i, my + j] = soluclr
mx = mx + wallW if x % 2 == 0 else mx + pathW
my = my + wallW if y % 2 == 0 else my + pathW
# save solution image
img.save(spic)
img.close()
def main(argv):
automaze(argv[0])
if __name__ == "__main__":
main(sys.argv[1:])
迷宫原图:
解: