Python实现随机生成迷宫并自动寻路

下面我来详细讲解一下“Python实现随机生成迷宫并自动寻路”的完整攻略。

简介

这个项目旨在使用Python生成随机迷宫并实现自动寻路的功能。具体实现过程如下:

  1. 随机生成迷宫
  2. 使用启发式搜索算法自动找到迷宫的出口

随机生成迷宫

要生成迷宫,我们可以采用深度优先搜索(DFS)和递归回溯算法。具体步骤如下:

  1. 创建一个NxM的矩阵,初始化所有元素为墙
  2. 从任意位置开始递归,选择上下左右四个方向中的一个,并且走两步
  3. 如果所选方向的两步都未超过矩阵边界,那么将中间的点和终点都标记为通路,并递归访问终点;否则回溯到上一个节点,重新选择通路。

下面是一个简化版的实现例子:

import random

def generate_maze(rows, cols):
    maze = []
    for i in range(rows):
        row = []
        for j in range(cols):
            row.append(1)
        maze.append(row)

    def build_wall(x, y):
        maze[x][y] = 0

    def dfs(x, y):
        directions = [(0, 2), (2, 0), (0, -2), (-2, 0)]
        random.shuffle(directions)
        for dx, dy in directions:
            nx, ny = x + dx, y + dy
            if 0 <= nx < rows and 0 <= ny < cols and maze[nx][ny] == 1:
                maze[x + dx // 2][y + dy // 2] = 0
                build_wall(nx, ny)
                dfs(nx, ny)

    start_x, start_y = random.randint(0, rows // 2) * 2, random.randint(0, cols // 2) * 2
    dfs(start_x, start_y)
    maze[start_x][start_y] = 0
    maze[rows - 1][cols - 1] = 0
    return maze

以上代码生成的迷宫矩阵是一个rows * cols大小的列表,其中0代表通路,1代表障碍物。

自动寻路

实现自动寻路,可以采用A算法。A算法是一种启发式搜索算法,在广度优先搜索的基础上,加入了估价函数。具体步骤如下:

  1. 将起点加入open列表
  2. 重复以下步骤直到open列表为空:
    • 取出open列表中f值最小的节点
    • 如果当前节点是终点,返回路径
    • 将当前节点标记为closed,并将其相邻的未访问节点加入open列表
  3. 如果open列表为空,表示无解

下面是一个简化版的实现例子:

import heapq

def a_star(maze):
    rows, cols = len(maze), len(maze[0])
    start = (0, 0)
    end = (rows - 1, cols - 1)

    def get_distance(p1, p2):
        return abs(p1[0] - p2[0]) + abs(p1[1] - p2[1])

    def get_neighbors(point):
        x, y = point
        neighbors = []
        for dx, dy in [(0, 1), (1, 0), (0, -1), (-1, 0)]:
            nx, ny = x + dx, y + dy
            if 0 <= nx < rows and 0 <= ny < cols and maze[nx][ny] == 0:
                neighbors.append((nx, ny))
        return neighbors

    open_heap = [(get_distance(start, end), start)]
    visited = set()

    while open_heap:
        f, point = heapq.heappop(open_heap)
        if point in visited:
            continue
        visited.add(point)
        if point == end:
            path = []
            while point != start:
                path.append(point)
                point = parents[point]
            path.append(start)
            path.reverse()
            return path
        for neighbor in get_neighbors(point):
            g = get_distance(start, point) + 1
            h = get_distance(neighbor, end)
            f = g + h
            heapq.heappush(open_heap, (f, neighbor))
    return []

以上代码实现了A*算法的寻路过程,并返回了一条从起点到终点的路径。

接下来我们将两部分集成在一起,得到完整的代码实现。下面是一个示例:

import random
import heapq

def generate_maze(rows, cols):
    maze = []
    for i in range(rows):
        row = []
        for j in range(cols):
            row.append(1)
        maze.append(row)

    def build_wall(x, y):
        maze[x][y] = 0

    def dfs(x, y):
        directions = [(0, 2), (2, 0), (0, -2), (-2, 0)]
        random.shuffle(directions)
        for dx, dy in directions:
            nx, ny = x + dx, y + dy
            if 0 <= nx < rows and 0 <= ny < cols and maze[nx][ny] == 1:
                maze[x + dx // 2][y + dy // 2] = 0
                build_wall(nx, ny)
                dfs(nx, ny)

    start_x, start_y = random.randint(0, rows // 2) * 2, random.randint(0, cols // 2) * 2
    dfs(start_x, start_y)
    maze[start_x][start_y] = 0
    maze[rows - 1][cols - 1] = 0
    return maze


def a_star(maze):
    rows, cols = len(maze), len(maze[0])
    start = (0, 0)
    end = (rows - 1, cols - 1)

    def get_distance(p1, p2):
        return abs(p1[0] - p2[0]) + abs(p1[1] - p2[1])

    def get_neighbors(point):
        x, y = point
        neighbors = []
        for dx, dy in [(0, 1), (1, 0), (0, -1), (-1, 0)]:
            nx, ny = x + dx, y + dy
            if 0 <= nx < rows and 0 <= ny < cols and maze[nx][ny] == 0:
                neighbors.append((nx, ny))
        return neighbors

    open_heap = [(get_distance(start, end), start)]
    visited = set()
    parents = {}

    while open_heap:
        f, point = heapq.heappop(open_heap)
        if point in visited:
            continue
        visited.add(point)
        if point == end:
            path = []
            while point != start:
                path.append(point)
                point = parents[point]
            path.append(start)
            path.reverse()
            return path
        for neighbor in get_neighbors(point):
            g = get_distance(start, point) + 1
            h = get_distance(neighbor, end)
            f = g + h
            heapq.heappush(open_heap, (f, neighbor))
            parents[neighbor] = point
    return []


if __name__ == "__main__":
    maze = generate_maze(20, 20)
    path = a_star(maze)

    print("迷宫:")
    for row in maze:
        print(" ".join(["#" if x else " " for x in row]))

    print("路径:")
    for i, p in enumerate(path):
        if i == 0:
            print("[S]", end=" ")
        elif i == len(path) - 1:
            print("[E]", end=" ")
        else:
            print("[X]", end=" ")
        print("({},{})".format(p[0], p[1]), end=" ")
    print()

上述代码实现了一个20x20大小的迷宫,并在迷宫中使用A*算法寻找从起点到终点的路径。运行后所生成的结果会输出迷宫和找到的路径。

再以一个更大的迷宫为例,运行结果如下所示:

迷宫:
# # # # # # # # # # # # # # # # # # #
#                                 # #
# # # # # # # # # # # # # # # #   # #
#   # # # # # #             #   # # #
# # #   # # # # # # # # #   # # # # #
#         # #     #     # # # # #   #
# # # # # # # #   # # #     #   # #
#           #   # # # # # #   # # #
# # # # # # # #           # # # # #
#       # #   # # # # #   # #     #
# # # # # # # #     # #           #
#   # # # #   # # # # # # # # # # #
# #   #   # # # # # #   # # # # # #
# # # # #   #         # # #     # #
#                 # # # # # #   # #
# # # # # # # # # # #         # # #
#         #         # # # # # # # #
# # # # # # # # # # # #   #     # #
#             #               #   #
# # # # # # # # # # # # # # # # # #
路径:
[S] (0,0) [X] (2,0) [X] (2,2) [X] (4,2) [X] (4,4) [X] (6,4) [X] (6,6) [X] (8,6) [X] (10,6) [X] (10,8) [X] (10,10) [X] (10,12) [X] (12,12) [X] (12,14) [X] (12,16) [X] (12,18) [X] (14,18) [X] (16,18) [X] (18,18) [X] (19,18) [E] 

可以看到,我们成功用Python实现了随机生成迷宫和自动寻路的功能。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python实现随机生成迷宫并自动寻路 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • Python 3.7 数据类中的类继承

    【问题标题】:Class inheritance in Python 3.7 dataclassesPython 3.7 数据类中的类继承 【发布时间】:2023-04-05 07:29:02 【问题描述】: 我目前正在尝试 Python 3.7 中引入的新数据类结构。我目前坚持尝试对父类进行一些继承。看起来参数的顺序被我当前的方法搞砸了,因此子类中的 bo…

    Python开发 2023年4月5日
    00
  • django python 获取当天日期的方法

    获取当天日期是Web开发中常用的操作之一,Python的Django框架也提供了多个方法来获取当天的日期。以下是详细讲解如何在Django中获取当天日期的方法: 使用Python标准库获取当天日期 Python标准库中有datetime模块可以用于获取当前日期和时间。在Django中可以使用datetime模块获取当天日期的方法如下: import date…

    python 2023年6月2日
    00
  • python3.6 tkinter实现屏保小程序

    Python3.6 Tkinter实现屏保小程序的完整攻略如下: 1. 简介 Python3.6是一门面向对象的编程语言,其标准库中自带有GUI工具包Tkinter,以便开发人员可以轻松地创建用户界面。屏保是一种用于显示屏幕的程序,目的是防止屏幕过度使用而导致的损坏。在本教程中,我们将使用Python3.6和Tkinter来创建一个简单的屏保小程序。 2.实…

    python 2023年5月23日
    00
  • Python 使用list和tuple+条件判断详解

    以下是详细讲解“Python使用list和tuple+条件判断详解”的完整攻略。 使用list和tuple 在Python中,list和tuple是两种常用的序列类型。list是可序列,可以进行增删改查等操作,而tuple是不可变序列,一旦创建就不能修改。下面是一些常见的操作: 创建list和tuple lst = [1, 2, 3, , 5] tup = …

    python 2023年5月13日
    00
  • Python用一个公共列连接两个框架

    【问题标题】:Python join two frames with one common columnPython用一个公共列连接两个框架 【发布时间】:2023-04-05 03:26:01 【问题描述】: 我在 python 框架 A 中有 和框架 B: 如何在框架 A 中添加新列“名称”以显示框架 b 中的列 z 值?两个框架之间的公共列是A[‘b’…

    Python开发 2023年4月6日
    00
  • 详解Python的collections模块中的deque双端队列结构

    下面就详细讲解一下Python的collections模块中的deque双端队列结构。 1. 简介 首先来介绍一下deque,它是Python的collections模块提供的一个双端队列结构。deque支持从两端快速的append和pop操作,时间复杂度都是O(1),因此比传统的list在很多场景下都要更为高效。deque还提供了一些其他基础队列操作,如长…

    python 2023年6月3日
    00
  • python实现人性化显示金额数字实例详解

    Python实现人性化显示金额数字实例详解 在很多的计算机应用场景中,需要对金额数字进行人性化的显示,比如货币、股票等金融领域。Python作为一种经典的开发语言,提供了非常方便的解决方案来实现金额数字的人性化显示。本文将介绍如何用Python实现人性化显示金额数字,以及提供一些示例说明。 实现思路 人性化金额数字的显示,需要满足以下几个条件: 数字需要进行…

    python 2023年6月3日
    00
  • python中argparse模块及action=’store_true’详解

    下面就来详细讲解一下“python中argparse模块及action=’store_true’详解”。 argparse模块介绍 argparse是Python中内置的用于解析命令行选项和参数的模块,它可以让开发者轻松地编写易于使用和维护的命令行工具。argparse解析器允许程序定义它期望接收的命令行参数,并从sys.argv中解析出这些参数。argpa…

    python 2023年6月3日
    00
合作推广
合作推广
分享本页
返回顶部