算法自动生成迷宫地图

article/2025/3/11 11:08:43

文章目录

  • 前言
  • 一、什么是(DFS)深度优先算法?
    • 深度优先算法实现步骤
      • 1.引入库
      • 2.初始化参数
      • 3.Turtle画方格函数
      • 4.开始生成数组并调用Turtle画图
  • 二、什么是(BFS)广度优先算法?
    • 广度优先算法实现步骤
      • 1.引入库
      • 2.初始化参数
      • 3.Turtle画方格函数
      • 4.开始生成数组并调用Turtle画图
  • 总结


前言

最近学习了随机生成迷宫的算法, 分享学习经验以及碰到的问题点。目前学习两个算法 生成随机地图, 深度优先算法和广度优先算法来生成迷宫。比较下他们的不同点。

在程序中,我们用数组M表示所有的单元格子的属性,并用turtle 库来画图。用红色单元格来表示当前遍历到单元格。

一、什么是(DFS)深度优先算法?

简单来说它是一头扎到底的玩法。我们选择一条支路,尽可能不断地深入,如果遇到死路就往回退,回退过程中如果遇到没探索过的支路,就进入该支路继续深入。如此循环反复直到把所有的单元格都遍历了。

深度优先算法实现步骤

1.引入库

代码如下:

import random
import numpy as np
from turtle import *
import time

2.初始化参数

代码如下:

#初始化参数
num_rows = 20 # 生成迷宫的行数
num_cols = 20 # 生成迷宫的列数M = np.zeros((num_rows, num_cols, 5), dtype=np.uint8)
# 阵列M将保存每个单元的阵列信息。
# 前四个坐标告诉墙壁在那些边上是否存在
# 和第五个指示在搜索中是否已访问该单元格。
# M【上,右,下,左,是否被访问】# 我们先把第一个单元格最和后一个墙打开。
M[0, 0, 0] = 1
M[num_rows-1, num_cols-1, 2] = 1#如下是turtle模块的初始化
tracer(0)# 最快生成图
ht()# 隐藏画笔
pensize(1)#画笔大小设为1

3.Turtle画方格函数

代码如下:

def pengoto(x, y):up()goto(x, y)down()def drawing(r, c, M):x = 20*c-200y = 200-20*rpengoto(x, y)for i in range(4):if M[i] == 1:pencolor('blue')fd(1)pencolor('white')fd(19)right(90)else:pencolor('blue')fd(20)right(90)

4.开始生成数组并调用Turtle画图

# 设置开始的行和列
r = 0
c = 0
history = [(r, c)]  # 这个是历史访问的单元格列表。
n = 0  # 砸墙的数量。
# 从初始单元个一路开墙并进入下一个单元格,如果无路可走则返回。
# 我们使用while循环来执行此操作,重复该循环直到n=所有的单元格数-1.说明所有的单元格都是通的了。
while history:M[r, c, 4] = 1  #将此位置指定为已访问#检查相邻单元格是否可移动去,注意上下左右的边界。 check = []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])n += 1move = random.choice(check)#随机打开一堵墙# 注意数组[上, 右,下,左,1]if move == 'L':  M[r, c, 3] = 1c = c-1M[r, c, 1] = 1if move == 'U':M[r, c, 0] = 1r = r-1M[r, c, 2] = 1if move == 'R':M[r, c, 1] = 1c = c+1M[r, c, 3] = 1if move == 'D':M[r, c, 2] = 1r = r+1M[r, c, 0] = 1else:  #如果发现没有下个单元格可以去,我们要回溯。r, c = history.pop()# 红色显示当前单元格子clear()#清理下,不然内存会被占用fillcolor("red")begin_fill()drawing(r, c, M[r, c])end_fill()# 调用turtle画图显示当前整个地图状态。for i in range(num_rows): for j in range(num_cols):drawing(i, j, M[i, j])update()#更新下,不然turtle会卡死time.sleep(0.5)if n == num_cols*num_rows-1:  # 当砸墙的数量等于单元格子的数量-1时结束循环。breakdone()

二、什么是(BFS)广度优先算法?

广度优先搜索是按层来处理顶点,距离开始点最近的那些顶点首先被访问,而最远的那些顶点则最后被访问,这个和树的层序变量很像,BFS的代码使用了一个队列。Prim

广度优先算法实现步骤

1.引入库

代码如下:

import random
import numpy as np
from turtle import *
import timet

2.初始化参数

代码如下:

#初始化参数
num_rows = 20 # 生成迷宫的行数
num_cols = 20 # 生成迷宫的列数M = np.zeros((num_rows, num_cols, 5), dtype=np.uint8)
# 阵列M将保存每个单元的阵列信息。
# 前四个坐标告诉墙壁在那些边上是否存在
# 和第五个指示在搜索中是否已访问该单元格。
# M【上,右,下,左,是否被访问】# 我们先把第一个单元格最和后一个墙打开。
M[0, 0, 0] = 1
M[num_rows-1, num_cols-1, 2] = 1#如下是turtle模块的初始化
tracer(0)# 最快生成图
ht()# 隐藏画笔
pensize(1)#画笔大小设为1

3.Turtle画方格函数

代码如下:

def pengoto(x, y):up()goto(x, y)down()def drawing(r, c, M):x = 20*c-200y = 200-20*rpengoto(x, y)for i in range(4):if M[i] == 1:pencolor('blue')fd(1)pencolor('white')fd(19)right(90)else:pencolor('blue')fd(20)right(90)

4.开始生成数组并调用Turtle画图

# 设置开始的行和列
r = 0
c = 0
history = [(r, c)]  # 这个是历史访问的单元格列表。
n = 0  # 砸墙的数量。
while history:# 随机选择一个可以敲墙的单元格r, c = random.choice(history)M[r, c, 4] = 1  # 把单元设成以访问history.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] = 2
# 随机前往一个边界墙.if len(check):n+=1move = random.choice(check)if move == 'L':  # [上,右,下,左,1]M[r, c, 3] = 1c = c-1M[r, c, 1] = 1if move == 'U':M[r, c, 0] = 1r = r-1M[r, c, 2] = 1if move == 'R':M[r, c, 1] = 1c = c+1M[r, c, 3] = 1if move == 'D':M[r, c, 2] = 1r = r+1M[r, c, 0] = 1# 红色方格显示当前单元格子位置clear()#清理下,不然内存会一直被占用。fillcolor("red")begin_fill()drawing(r, c, M[r, c])end_fill()# 调用turtle画图显示当前整个地图状态。for i in range(num_rows): for j in range(num_cols):drawing(i, j, M[i, j])update()#需要跟新下,不然会卡死time.sleep(0.5)if n == num_cols*num_rows-1:  # 当砸墙的数量等于单元格子的数量-1时结束循环。breakdone()

总结

1、深度优先算法:是对每一个可能的分支路径深入到不能再深入为止,深度优先法生成的迷宫扭曲,有着一条明显的主路。
2、广度优先算法:系统地展开并检查图中的所有节点,直到遍历完成。

程序生产的图片如下:
在这里插入图片描述
视频如下:

深度优先算法和广度优先算法的生成迷宫


http://chatgpt.dhexx.cn/article/aO4Jr5sp.shtml

相关文章

【工具篇】Unity迷宫地图生成器MazeSpawner随机迷宫信手拈来

目录 一.迷宫生成效果 二.使用流程 三.使用场景 四.源码地址 一.迷宫生成效果 二.使用流程 1.导入后结构目录如下,打开prefab文件夹找到MazeSpawner放进场景里面

C++实现随机生成迷宫地图自动完成寻径

#include<iostream> #include<stack> #include<vector> using namespace std;template<class T> class Maze { public:Maze( //默认参数值pair<int, int> initSize make_pair(15, 17),pair<string, string> initStyle m…

Python 制作迷宫游戏(一)——地图

Python 制作迷宫游戏&#xff08;一&#xff09;——地图 序 作为一个迷宫类的游戏&#xff0c;其最重要的是什么&#xff1f;当然是它的地图啦♪(∇*) 那么我们又该如何制作一张迷宫地图呢⊙(・◇・)&#xff1f; 很显然&#xff0c;我们不可能一张张自己画吧 网络上常见的迷…

三套简单的迷宫地图生成方案

地图基础 地图的形式很多&#xff0c;这里我使用的地图是以tile块为单位分割的地图&#xff0c;地图上的tile块形式很多&#xff0c;但主要分成三种&#xff1a; A&#xff1a;陆地&#xff0c;可以在上面分布一些角色啦物件啦&#xff1b; B&#xff1a;过渡&#xff0c;根据物…

SenticNet情感词典介绍

在进行情感分析时&#xff0c;一个好的情感词典能够让我们的工作事半功倍&#xff0c;较为出名的情感词典有SentiWordNet&#xff0c;General Inquirer等&#xff0c;这篇博客将介绍另外一个出色情感词典&#xff0c;SenticNet。 简介 当谈论SenticNet时&#xff0c;我们正在…

中文金融领域情感词典构建

2019年10月4日-6日 Python爬虫与文本分析工作坊 & 课题申报高级研修班 这篇文章是公众号关注者郝童鞋今早发给我的&#xff0c;在此谢谢郝童鞋。 文章基于简单算法和人工判断&#xff0c;使用多阶段剔除法&#xff0c;构建了 中文金融情感词典CFSD&#xff08;ChineseFinan…

《学术小白的学习之路 02》情感分析02 之基于大连理工情感词典的情感分析和情绪计算

本文主要是学习参考杨秀璋老师的博客,笔记总结。 原文链接 文章目录 书山有路勤为径&#xff0c;学海无涯苦作舟原文链接一.大连理工情感词典二、七种情绪的计算2.1 pandas读取数据2.2 导入大连理工大学中文情感词典2.3 统计七种情绪的分布情况2.4 增加中文分词词典和自定义的停…

中文情感词典的构建

首先&#xff0c;国外英文的情感分析已经取得了很好的效果&#xff0c;得益于英文单词自身分析的便捷性与英文大量的数据集 WordNet。但由于中文的多变性&#xff0c;语义的多重性与数据集的缺乏&#xff0c;使得国内的情感分析暂落后于国外。本文将记录博主在项目中构建情感词…

基于情感词典的网络文本情感倾向分类模型

目录 前言一、模型构建1.归类2.判定3.输出 二、代码实现三、结果展示 前言 文本情感倾向性分析&#xff08;也称为意见挖掘&#xff09;是指识别和提取原素材中的主观信息&#xff0c;并对带有感情色彩的文本进行分析处理和归纳推理的过程。主要用于实时社交媒体的内容&#xf…

使用SO-PMI算法构建行业/专业情感词典

文章目录 1. 情感词典内容2. 情感倾向点互信息算法&#xff08;SO-PMI&#xff09;算法点互信息算法 PMI情感倾向点互信息算法 SO-PMI 3. 构建情感词典1. 导入项目2. 构建情感种子词3. 使用TF-IDF方便构建情感种子词4. 构建专业词典的效果与使用方法5. 其他说明 1. 情感词典内容…

在微雕中使用的电脑设计

需求是我们要在铜器上复刻很小的凹印,可以选用的技术方案还是很多:激光雕刻,篆刻、钢印。 激光雕刻有利有弊,前期复制是最方便的,激光雕刻有专门的设计软件,可以很轻松的把自己的图案运用到机器上去。制作和时间的成本都非常的低,但是激光对金属的雕刻有一个大大的缺点…

闲人闲谈PS之四十二——顾问的“禁忌之地”—制造能力计划

惯例闲话&#xff1a;上个月有幸成为乐老师乐谈IT系列培训课程的讲师&#xff0c;分享主题是&#xff0c;PS在装备制造和工程行业的应用。虽然培训规模不是很大&#xff0c;但是闲人很有信心&#xff0c;至少在小范围之内&#xff0c;参与培训的听友人来说&#xff0c;PS一直以…

ibm x201 怎么清理内部_ThinkPad X201拆解,联想Thinkpad X201拆机图解

1.jpg (25.79 KB, 下载次数: 2552) 2010-6-1 20:13 上传 ThinkPad X201掌托&#xff0c;没有防滚架&#xff0c;这个掌托就显得很软。电磁屏蔽做得很用心。 2.jpg (39.16 KB, 下载次数: 2556) 2010-6-1 20:13 上传 ThinkPad X201掌托特写&#xff0c;可以看到掌托塑料件是MITSU…

学习opencv:PS滤镜—浮雕

实现浮雕效果的算子有很多&#xff0c;效果大同小异&#xff0c;不同算子的处理结果在细节上会有所差异。事实上&#xff0c;任何一阶差分算子都可用于实现浮雕效果&#xff0c;简单起见&#xff0c;这里使用算子[-1,1]。 代码如下 #include<iostream> #include <…

ps给图片加钢印方法

给图片加一个钢印其实很简单 这样的效果只能类似钢印 简单可以按照下面的方法 准备资料 &#xff1a;一个要加钢印的图片 一个透明印章即可实现 方法&#xff1a;斜面和浮雕 一、打开图片 二、打开透明印章 三、将透明印章移动到图片中 四、进行图层设置 右击印章图层---混合…

PS钢印效果制作

PS制作钢印效果一法 转载教程:严禁做假.... 附件 1.jpg (37.05 KB) 2008-6-10 22:39 2.jpg (33.59 KB) 2008-6-10 22:39 3.jpg (38.57 KB) 2008-6-10 22:39 4.jpg (42.49 KB) 2008-6-10 22:39 5.jpg (39.2 KB) 2008-6-10 22:39 6.jpg (44.63 KB) 2008-6-10 22:39 7.jpg…

Oracle中extract()函数

oracle中extract()函数从oracle 9i中引入的,主要作用于一个date或者interval类型中截取特定的部分 extract()语法如下&#xff1a; extract ( { year | month | day | hour | minute | second | 某一时区 } from { date类型值 | interval类型值} ) 要点一&#xff1a;extract()…

oracle ora-01652:无法通过1024(在表空间SYSTEM中)拓展temp段

1.报错 2.查询拓展表空间 2.1查看表空间使用情况 SELECT UPPER(F.TABLESPACE_NAME) "表空间名",D.TOT_GROOTTE_MB "表空间大小(M)",D.TOT_GROOTTE_MB - F.TOTAL_BYTES "已使用空间(M)",TO_CHAR(ROUND((D.TOT_GROOTTE_MB - F.TOTAL_BYTES) / D.…

hpux oracle10.2.0.4下报ORA-1652 unable to extend temp segment by 128 in tablespace CARDTS

hpux oracle10.2.0.4 rac 下报ORA-1652 unable to extend temp segment by 128 in tablespace CARDTS hpux 11.31 oracle10.2.0.4 rac ,2 nodes 值得注意的是&#xff0c;报的是不能在CARDTS表空间中扩展temp段。。。 后来查询metalink 文章&#xff0c; Troubleshooting ORA-1…

原创:oracle中单行函数介绍 lt;五gt;

在SQL中有两种函数一种是单行函数&#xff0c;一种是多行函数.在sql与pl/sql中都自带了很多类型的函数,比如有字符、数字、日期、转换和混合型等多种函数用于处理单行数据,因此这些都被称为单行函数.这些函数都可以被用于select、where和oder by等子句中.下面我们就来分析单行函…