不要脸的放到了Github上面,嘿嘿。
Github:https://github.com/Radium1209/Maze
先看一下动态效果图(慢放):
所需要的库:
matplotlib
# for Linux
# python 3+
$ sudo apt-get install python3-matplotlib# python 2+
$ sudo apt-get install python-matplotlib
numpy
# for Linux
# python 3+
$ sudo pip3 install numpy# python 2+
$ sudo pip install numpy
首先生成迷宫:
主要用了两个算法:Prim和dfs
总结:DFS生成的比较像真正的迷宫,所以默认用了DFS生成迷宫
具体参考:https://blog.csdn.net/juzihongle1/article/details/73135920
先输入n,m,会生成一个迷宫(prim生成),然后会动态的走完整个迷宫。
走迷宫用的是bfs(dfs)算法,具体不多说了,关键难点在于记录路径:
我是用一个path二维数组来记录路径的,每一个位置存的是这个位置的上一个位置,在输出的时候倒着从最后一个点回溯到第一个点存入一个栈,最后正常出栈就是路径了。
画路径:有上,下,左,右,上左,上右,下左,下右,左下,左上,右上,右下12中情况分类讨论(实在是太麻烦了)。
最后用pyinstaller生成exe
教程:https://blog.csdn.net/Radium_1209/article/details/82939368
全部代码(已更新,添加了DFS寻路):
import random
import numpy as np
from matplotlib import pyplot as plt
import matplotlib.cm as cm
from collections import dequedef show_maze(Maze):plt.imshow(Maze, cmap=cm.Wistia_r, interpolation='none')# plt.ion()plt.show()def find_path_bfs(image, M):path = np.zeros((num_rows, num_cols, 2))vis = np.zeros((num_rows, num_cols))vis[0][0] = 1Queue = deque()Queue.append((0, 0))while(Queue):temp = Queue.popleft()nr = temp[0]nc = temp[1]if (nc == num_cols - 1) and (nr == num_rows - 1):show_path(image, path)breakif (nc > 0) and (not vis[nr][nc - 1]) and (M[nr][nc][0]):vis[nr][nc] = 1Queue.append((nr, nc - 1))path[nr][nc - 1][0] = nrpath[nr][nc - 1][1] = ncif (nr > 0) and (not vis[nr - 1][nc]) and (M[nr][nc][1]):vis[nr][nc] = 1Queue.append((nr - 1, nc))path[nr - 1][nc][0] = nrpath[nr - 1][nc][1] = ncif (nc < num_cols - 1) and (not vis[nr][nc + 1]) and (M[nr][nc][2]):vis[nr][nc] = 1Queue.append((nr, nc + 1))path[nr][nc + 1][0] = nrpath[nr][nc + 1][1] = ncif (nr < num_rows - 1) and (not vis[nr + 1][nc]) and (M[nr][nc][3]):vis[nr][nc] = 1Queue.append((nr + 1, nc))path[nr + 1][nc][0] = nrpath[nr + 1][nc][1] = ncdef find_path_dfs(image, M):path = np.zeros((num_rows, num_cols, 2))vis = np.zeros((num_rows, num_cols))vis[0][0] = 1def dfs(pos):nr = pos[0];nc = pos[1];if (nc == num_cols - 1) and (nr == num_rows - 1):show_path(image, path)returnif (nc > 0) and (not vis[nr][nc - 1]) and (M[nr][nc][0]):vis[nr][nc] = 1path[nr][nc - 1][0] = nrpath[nr][nc - 1][1] = ncdfs((nr, nc - 1))vis[nr][nc] = 0if (nr > 0) and (not vis[nr - 1][nc]) and (M[nr][nc][1]):vis[nr][nc] = 1path[nr - 1][nc][0] = nrpath[nr - 1][nc][1] = ncdfs((nr - 1, nc))vis[nr][nc] = 0if (nc < num_cols - 1) and (not vis[nr][nc + 1]) and (M[nr][nc][2]):vis[nr][nc] = 1path[nr][nc + 1][0] = nrpath[nr][nc + 1][1] = ncdfs((nr, nc + 1))vis[nr][nc] = 0if (nr < num_rows - 1) and (not vis[nr + 1][nc]) and (M[nr][nc][3]):path[nr + 1][nc][0] = nrpath[nr + 1][nc][1] = ncvis[nr][nc] = 1dfs((nr + 1, nc))vis[nr][nc] = 0dfs((0,0))def Create_maze_dfs():M = np.zeros((num_rows, num_cols, 5))image = np.zeros((num_rows * 10, num_cols * 10))r = 0c = 0history = [(r, c)]while history:M[r, c, 4] = 1check = []if c > 0 and M[r, c - 1, 4] == 0:check.append('L')if r > 0 and M[r - 1, c, 4] == 0:check.append('U')if c < num_cols - 1 and M[r, c + 1, 4] == 0:check.append('R')if r < num_rows - 1 and M[r + 1, c, 4] == 0:check.append('D')if len(check):history.append([r, c])move_direction = random.choice(check)if move_direction == 'L':M[r, c, 0] = 1c = c - 1M[r, c, 2] = 1if move_direction == 'U':M[r, c, 1] = 1r = r - 1M[r, c, 3] = 1if move_direction == 'R':M[r, c, 2] = 1c = c + 1M[r, c, 0] = 1if move_direction == 'D':M[r, c, 3] = 1r = r + 1M[r, c, 1] = 1else:r, c = history.pop()M[0, 0, 0] = 1M[num_rows - 1, num_cols - 1, 2] = 1for row in range(0, num_rows):for col in range(0, num_cols):cell_data = M[row, col]for i in range(10 * row + 2, 10 * row + 8):image[i, range(10 * col + 2, 10 * col + 8)] = 255if cell_data[0] == 1:image[range(10 * row + 2, 10 * row + 8), 10 * col] = 255image[range(10 * row + 2, 10 * row + 8), 10 * col + 1] = 255if cell_data[1] == 1:image[10 * row, range(10 * col + 2, 10 * col + 8)] = 255image[10 * row + 1, range(10 * col + 2, 10 * col + 8)] = 255if cell_data[2] == 1:image[range(10 * row + 2, 10 * row + 8), 10 * col + 9] = 255image[range(10 * row + 2, 10 * row + 8), 10 * col + 8] = 255if cell_data[3] == 1:image[10 * row + 9, range(10 * col + 2, 10 * col + 8)] = 255image[10 * row + 8, range(10 * col + 2, 10 * col + 8)] = 255return M, imagedef Create_maze_prim():M = np.zeros((num_rows, num_cols, 5))image = np.zeros((num_rows * 10, num_cols * 10))r = 0c = 0history = [(r, c)]while history:r, c = random.choice(history)M[r, c, 4] = 1history.remove((r, c))check = []if c > 0:if M[r, c - 1, 4] == 1:check.append('L')elif M[r, c - 1, 4] == 0:history.append((r, c - 1))M[r, c - 1, 4] = 2if r > 0:if M[r - 1, c, 4] == 1:check.append('U')elif M[r - 1, c, 4] == 0:history.append((r - 1, c))M[r - 1, c, 4] = 2if c < num_cols - 1:if M[r, c + 1, 4] == 1:check.append('R')elif M[r, c + 1, 4] == 0:history.append((r, c + 1))M[r, c + 1, 4] = 2if r < num_rows - 1:if M[r + 1, c, 4] == 1:check.append('D')elif M[r + 1, c, 4] == 0:history.append((r + 1, c))M[r + 1, c, 4] = 2if len(check):move_direction = random.choice(check)if move_direction == 'L':M[r, c, 0] = 1c = c - 1M[r, c, 2] = 1if move_direction == 'U':M[r, c, 1] = 1r = r - 1M[r, c, 3] = 1if move_direction == 'R':M[r, c, 2] = 1c = c + 1M[r, c, 0] = 1if move_direction == 'D':M[r, c, 3] = 1r = r + 1M[r, c, 1] = 1M[0, 0, 0] = 1M[num_rows - 1, num_cols - 1, 2] = 1for row in range(0, num_rows):for col in range(0, num_cols):cell_data = M[row, col]for i in range(10 * row + 2, 10 * row + 8):image[i, range(10 * col + 2, 10 * col + 8)] = 255if cell_data[0] == 1:image[range(10 * row + 2, 10 * row + 8), 10 * col] = 255image[range(10 * row + 2, 10 * row + 8), 10 * col + 1] = 255if cell_data[1] == 1:image[10 * row, range(10 * col + 2, 10 * col + 8)] = 255image[10 * row + 1, range(10 * col + 2, 10 * col + 8)] = 255if cell_data[2] == 1:image[range(10 * row + 2, 10 * row + 8), 10 * col + 9] = 255image[range(10 * row + 2, 10 * row + 8), 10 * col + 8] = 255if cell_data[3] == 1:image[10 * row + 9, range(10 * col + 2, 10 * col + 8)] = 255image[10 * row + 8, range(10 * col + 2, 10 * col + 8)] = 255return M, imagedef show_path(image, path):plt.imshow(image, cmap=cm.Wistia_r, interpolation='none')plt.ion()plt.pause(2)str = ""stack = []nr = num_rows - 1nc = num_cols - 1stack.append((nr, nc + 1))stack.append((nr, nc))while nr or nc:tr = nrtc = ncnr = (int)(path[tr][tc][0])nc = (int)(path[tr][tc][1])stack.append((nr, nc))# stack.append((num_rows, num_cols))pr = 0pc = 0dir = 2color_num = 150while(stack):temp = stack.pop()nr = temp[0]nc = temp[1]if nr or nc:if (nr == pr):if (nc > pc):# print("R")if (dir == 2):image[10 * pr + 4,range(10 * pc + 0, 10 * pc + 10)] = color_numimage[10 * pr + 5,range(10 * pc + 0, 10 * pc + 10)] = color_numelif (dir == 1):image[10 * pr + 4,range(10 * pc + 4, 10 * pc + 10)] = color_numimage[10 * pr + 5,range(10 * pc + 4, 10 * pc + 10)] = color_numimage[range(10 * pr + 4, 10 * pr + 10),10 * pc + 4] = color_numimage[range(10 * pr + 4, 10 * pr + 10),10 * pc + 5] = color_numelif (dir == 3):image[10 * pr + 4,range(10 * pc + 4, 10 * pc + 10)] = color_numimage[10 * pr + 5,range(10 * pc + 4, 10 * pc + 10)] = color_numimage[range(10 * pr + 0, 10 * pr + 6),10 * pc + 4] = color_numimage[range(10 * pr + 0, 10 * pr + 6),10 * pc + 5] = color_numdir = 2else:# print("L")if (dir == 0):image[10 * pr + 4,range(10 * pc + 0, 10 * pc + 10)] = color_numimage[10 * pr + 5,range(10 * pc + 0, 10 * pc + 10)] = color_numelif (dir == 1):image[10 * pr + 4,range(10 * pc + 0, 10 * pc + 6)] = color_numimage[10 * pr + 5,range(10 * pc + 0, 10 * pc + 6)] = color_numimage[range(10 * pr + 4, 10 * pr + 10),10 * pc + 4] = color_numimage[range(10 * pr + 4, 10 * pr + 10),10 * pc + 5] = color_numelif (dir == 3):image[10 * pr + 4,range(10 * pc + 0, 10 * pc + 6)] = color_numimage[10 * pr + 5,range(10 * pc + 0, 10 * pc + 6)] = color_numimage[range(10 * pr + 0, 10 * pr + 6),10 * pc + 4] = color_numimage[range(10 * pr + 0, 10 * pr + 6),10 * pc + 5] = color_numdir = 0elif (nc == pc):if (nr > pr):# print("D")if (dir == 3):image[range(10 * pr + 0, 10 * pr + 10),10 * pc + 4] = color_numimage[range(10 * pr + 0, 10 * pr + 10),10 * pc + 5] = color_numelif (dir == 0):image[10 * pr + 4,range(10 * pc + 4, 10 * pc + 10)] = color_numimage[10 * pr + 5,range(10 * pc + 4, 10 * pc + 10)] = color_numimage[range(10 * pr + 4, 10 * pr + 10),10 * pc + 4] = color_numimage[range(10 * pr + 4, 10 * pr + 10),10 * pc + 5] = color_numelif (dir == 2):image[10 * pr + 4,range(10 * pc + 0, 10 * pc + 6)] = color_numimage[10 * pr + 5,range(10 * pc + 0, 10 * pc + 6)] = color_numimage[range(10 * pr + 4, 10 * pr + 10),10 * pc + 4] = color_numimage[range(10 * pr + 4, 10 * pr + 10),10 * pc + 5] = color_numdir = 3else:# print("U")if (dir == 1):image[range(10 * pr + 0, 10 * pr + 10),10 * pc + 4] = color_numimage[range(10 * pr + 0, 10 * pr + 10),10 * pc + 5] = color_numelif (dir == 0):image[10 * pr + 4,range(10 * pc + 4, 10 * pc + 10)] = color_numimage[10 * pr + 5,range(10 * pc + 4, 10 * pc + 10)] = color_numimage[range(10 * pr + 0, 10 * pr + 6),10 * pc + 4] = color_numimage[range(10 * pr + 0, 10 * pr + 6),10 * pc + 5] = color_numelif (dir == 2):image[10 * pr + 4,range(10 * pc + 0, 10 * pc + 6)] = color_numimage[10 * pr + 5,range(10 * pc + 0, 10 * pc + 6)] = color_numimage[range(10 * pr + 0, 10 * pr + 6),10 * pc + 4] = color_numimage[range(10 * pr + 0, 10 * pr + 6),10 * pc + 5] = color_numdir = 1pr = nrpc = ncplt.clf()plt.imshow(image, cmap=cm.Wistia_r, interpolation='none')# plt.ion()if (stack):plt.ion()plt.pause(0.03 / (num_cols * num_rows / 100))else:plt.ioff()plt.show()# plt.pause(1000)if __name__ == '__main__':num_rows = int(input("Please input rows: "))num_cols = int(input("Please input columns: "))path = np.zeros((num_rows, num_cols, 2))M = np.zeros((num_rows, num_cols, 5))image = np.zeros((num_rows * 10, num_cols * 10))# row_image = np.zeros((num_rows * 10, num_cols * 10))# M, image = Create_maze_prim()M, image = Create_maze_dfs()# show_maze(image)# find_path_bfs(image, M)find_path_dfs(image, M)# show_path(image, path)