python可视化迷宫求解_如何用 Python 制作一个迷宫游戏

相信大家都玩过迷宫的游戏,对于简单的迷宫,我们可以一眼就看出通路,但是对于复杂的迷宫,可能要仔细寻找好久,甚至耗费数天,然后可能还要分别从入口和出口两头寻找才能找的到通路,甚至也可能找不到通路。

虽然走迷宫问题对于我们人类来讲比较复杂,但对于计算机来说却是很简单的问题。为什么这样说呢,因为看似复杂实则是有规可循的。

我们可以这么做,携带一根很长的绳子,从入口出发一直走,如果有岔路口就走最左边的岔口,直到走到死胡同或者找到出路。如果是死胡同则退回上一个岔路口,我们称之为岔口 A,

这时进入左边第二个岔口,进入第二个岔口后重复第一个岔口的步骤,直到找到出路或者死胡同退回来。当把该岔路口所有的岔口都走了一遍,还未找到出路就沿着绳子往回走,走到岔口 A 的前一个路口 B,重复上面的步骤。

不知道你有没有发现,这其实就是一个不断递归的过程,而这正是计算机所擅长的。

上面这种走迷宫的算法就是我们常说的深度优先遍历算法,与之相对的是广度优先遍历算法。有了理论基础,下面我们就来试着用 程序来实现一个走迷宫的小程序。

生成迷宫

生成迷宫有很多种算法,常用的有递归回溯法、递归分割法和随机 Prim 算法,我们今天是用的最后一种算法。

该算法的主要步骤如下:

1、迷宫行和列必须为奇数

2、奇数行和奇数列的交叉点为路,其余点为墙,迷宫四周全是墙

3、选定一个为路的单元格(本例选 [1,1]),然后把它的邻墙放入列表 wall

4、当列表 wall 里还有墙时:

4.1、从列表里随机选一面墙,如果这面墙分隔的两个单元格只有一个单元格被访问过

4.1.1、那就从列表里移除这面墙,同时把墙打通

4.1.2、将单元格标记为已访问

4.1.3、将未访问的单元格的邻墙加入列表 wall

4.2、如果这面墙两面的单元格都已经被访问过,那就从列表里移除这面墙

我们定义一个 Maze 类,用二维数组表示迷宫地图,其中 1 表示墙壁,0 表示路,然后初始化左上角为入口,右下角为出口,最后定义下方向向量。

class Maze:

def __init__(self, width, height):

self.width = width

self.height = height

self.map = [[0 if x % 2 == 1 and y % 2 == 1 else 1 for x in range(width)] for y in range(height)]

self.map[1][0] = 0 # 入口

self.map[height - 2][width - 1] = 0 # 出口

self.visited = []

# right up left down

self.dx = [1, 0, -1, 0]

self.dy = [0, -1, 0, 1]

接下来就是生成迷宫的主函数了。

def generate(self):

start = [1, 1]

self.visited.append(start)

wall_list = self.get_neighbor_wall

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的Python迷宫小游戏代码,包括迷宫生成、解决和可视化。 ```python import random # 定义迷宫类 class Maze: def __init__(self, width=10, height=10): self.width = width self.height = height self.grid = self.prepare_grid() self.configure_cells() def prepare_grid(self): return [[Cell(x, y) for y in range(self.height)] for x in range(self.width)] def configure_cells(self): for row in self.grid: for cell in row: x, y = cell.x, cell.y cell.north = self.get_cell(x, y-1) cell.east = self.get_cell(x+1, y) cell.south = self.get_cell(x, y+1) cell.west = self.get_cell(x-1, y) def get_cell(self, x, y): if x < 0 or y < 0 or x >= self.width or y >= self.height: return None return self.grid[x][y] def __str__(self): output = "+" + "---+" * self.width + "\n" for row in self.grid: top = "|" bottom = "+" for cell in row: if cell is None: cell = Cell(-1, -1) body = " " east_boundary = " " if cell.linked(cell.east) else "|" top += body + east_boundary south_boundary = " " if cell.linked(cell.south) else "---" corner = "+" bottom += south_boundary + corner output += top + "\n" output += bottom + "\n" return output # 定义细胞类 class Cell: def __init__(self, x, y): self.x = x self.y = y self.north = None self.east = None self.south = None self.west = None self.links = {} def link(self, cell, bidi=True): self.links[cell] = True if bidi: cell.link(self, False) return self def unlink(self, cell, bidi=True): del self.links[cell] if bidi: cell.unlink(self, False) return self def linked(self, cell): return cell is not None and cell in self.links def neighbors(self): neighbors = [] if self.north: neighbors.append(self.north) if self.east: neighbors.append(self.east) if self.south: neighbors.append(self.south) if self.west: neighbors.append(self.west) return neighbors # 定义深度优先搜索算法 def recursive_backtracker(maze, current=None): if current is None: current = maze.grid[0][0] stack = [current] while stack: current = stack[-1] neighbors = [n for n in current.neighbors() if not current.linked(n)] if not neighbors: stack.pop() else: next_cell = random.choice(neighbors) current.link(next_cell) stack.append(next_cell) # 定义广度优先搜索算法 def bfs(maze, start=None, end=None): if start is None: start = maze.grid[0][0] if end is None: end = maze.grid[maze.width-1][maze.height-1] queue = [(start, [start])] visited = set() while queue: (vertex, path) = queue.pop(0) if vertex == end: return path if vertex not in visited: visited.add(vertex) for neighbor in [n for n in vertex.neighbors() if vertex.linked(n)]: queue.append((neighbor, path + [neighbor])) return None # 定义主函数 def main(): maze = Maze(10, 10) recursive_backtracker(maze) print(maze) path = bfs(maze) if path: for cell in path: maze.grid[cell.x][cell.y] = "P" print(maze) if __name__ == "__main__": main() ``` 运行上面的代码会生成一个10x10的迷宫,然后使用深度优先搜索算法生成迷宫,并使用广度优先搜索算法找到从左上角到右下角的最短路径,并将路径用字母"P"标记在迷宫中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值