迷宫生成算法

news2025/2/12 22:06:12

迷宫生成

① 十字分割 递归版本

② BFS(即广度算法)

十字分割方法生成

要求初始时迷宫内全是通路,然后随机十字建墙,然后随机在三面墙上打洞,使四个子空间连通。

要求:十字点横纵坐标均要求为偶数(即地图行列为奇数),打洞点要求为奇数。

DFS 方法生成:

像一只地鼠打洞一般,迷宫要求初始时全是阻碍(墙),然后随机方向打洞(挖墙)。

要求,待挖墙的通路(打洞方向)只能与访问过的节点处打穿。

实战演练

十字分割

非常简单的一个方法,不过游戏效果不是很好。下面介绍下算法过程:

首先全部围起来,然后做一个十字墙

打通十字墙任意三堵墙

递归生成十字墙,然后打通任意三堵墙

然后就生成了最简单的迷宫(其实没啥卵用的迷宫,就当是温习递归)

DFS 方法

其实就是一种挖墙算法,嗯,我是这样认为的。详细讲解一下这个算法。

先看一下定义地图的Node结构,

#define MAP_ROW 20	
#define MAP_COL 25
Node map[MAP_ROW][MAP_COL] = { 0 };	//每个墙 都没打通的  每个结点 都是没有访问过
struct Node
{
    int flag;	//表示关键结点是否访问过 0:未访问 1:已访问 2:待访问
    // 3:人物 4:目的地
    bool left, right, top, buttom;	//表示这个节点周围的四堵墙 0:不可通过的墙 1:可通过的空地
};

然后就是生成迷宫地图,也就是初始化函数init(),先选中左上角作为迷宫的入口,也是人物所在地

map[0][0].flag = 1;			//这个节点已经访问过

定义辅助数组储存待访问节点

COORD waitForVisit[MAP_COL * MAP_ROW];	//存放待访问的结点
int len = 0;							//map里面的坐标的个数

同时已访问节点周围是待访问节点,将其添加到辅助数组里面去,

waitForVisit[len++] = { 1, 0 };		//下方的结点 可以访问
map[1][0].flag = 2;					//待访问
waitForVisit[len++] = { 0, 1 };		//右边的结点 可以访问
map[0][1].flag = 2;					//待访问

效果如下图:

在绘制地图时设定白色为未访问节点粉红色为访问过的节点,蓝色为待访问节点

if (map[i][j].flag == 0)				//没有访问过这个节点
{
    setfillcolor(WHITE);
}
elseif (map[i][j].flag == 1)			//访问过
{
    setfillcolor(RGB(255, 193, 193));  
}
elseif(map[i][j].flag == 2)			//待访问
{
    setfillcolor(BLUE);
}

然后就是逐个访问待访问节点,务必要求每个节点都访问到,也就是广度优先搜索

len为待访问节点的数量,从中随机选取一个节点进行访问,并将访问后该节点周围的未访问节点初始化为待访问节点

while (len > 0)
{
    //随机选取其中的一个结点  进行访问
    m = rand() % len;	//从可以访问的结点中随机取一个
    /*打通这个节点  把这个节点相邻的结点放到map里面*/
    borderThrough(map, waitForVisit[m]);	//borderThrough作用:打通waitForVisit[m]节点的任意一面(上下左右任意一面)
    map[waitForVisit[m].X][waitForVisit[m].Y].flag = 1;		/*标记已访问*/
}

打通节点函数borderThrough()的作用就是将第二个传入参数所在节点的任意一面(上下左右任意一面)打通,打通的要求是该面相邻的节点是已经访问过了的节点

void borderThrough(Node map[][MAP_COL], const COORD node)///函数原型

打通条件:

(node.X + 1 < MAP_ROW) && map[node.X + 1][node.Y].flag == 1//向下打通
(node.Y - 1 >= 0) && map[node.X][node.Y - 1].flag == 1//向左打通

打通之后该节点设置为已访问节点(flag==1),然后周围的四个节点(未访问节点,如果有的话)设置成待访问节点。

m为随机选取的待访问节点下标

/*周围的四个节点(如果有) 全部放到map里面*/
if (waitForVisit[m].X - 1 >= 0 && map[waitForVisit[m].X - 1][waitForVisit[m].Y].flag == 0)
{
    //如果上方的结点没有访问过   设置为待访问 并且把这个位置放到map里面
    map[waitForVisit[m].X - 1][waitForVisit[m].Y].flag = 2;	/*标记待访问*/
    waitForVisit[len++] = { waitForVisit[m].X - 1, waitForVisit[m].Y };/*添加进待访问节点辅助数组里面*/
}
if (waitForVisit[m].X + 1 < MAP_ROW && map[waitForVisit[m].X + 1][waitForVisit[m].Y].flag == 0)
{
    //下
    map[waitForVisit[m].X + 1][waitForVisit[m].Y].flag = 2; /*标记待访问*/
    waitForVisit[len++] = { waitForVisit[m].X + 1, waitForVisit[m].Y };/*添加进待访问节点辅助数组里面*/
}

已经被标记为访问的节点将其从待访问节点数组里面删除

//map[m]已经访问过  从map里面删掉就可以
if (m == len - 1)
    len--;
else
{
    waitForVisit[m] = waitForVisit[len - 1];
    len--;
}

整个过程慢动作回放如下:

迷宫生成过程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/645664.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【unity】URP的shader开发中支持多光源,_ADDITIONAL_LIGHTS_VERTEX 和 _ADDITIONAL_LIGHTS 区别

项目里有一个其他同事实现的shader&#xff0c;美术那边希望能支持多个光源&#xff0c; 我一看代码里面&#xff0c; frag 函数里已经实现了 #ifdef _ADDITIONAL_LIGHTSuint pixelLightCount GetAdditionalLightsCount();for (uint lightIndex 0u; lightIndex < pixelL…

什么决定了我们的命运?

一、什么决定了我们的命运&#xff1f; 一个学生时代看起来特别优秀的人&#xff0c; 后来成了特别平凡的人&#xff1b; 而那时候看起来平淡无奇的一些人&#xff0c; 后来做出了一些似乎超越了他水平的事情。 不禁想问&#xff0c;到底是什么决定了我们的命运&#xff1f; 关…

Transformer在CV领域有可能替代CNN吗?

目前已经有基于Transformer在三大图像问题上的应用&#xff1a;分类&#xff08;ViT&#xff09;&#xff0c;检测&#xff08;DETR&#xff09;和分割&#xff08;SETR&#xff09;&#xff0c;并且都取得了不错的效果。那么未来&#xff0c;Transformer有可能替换CNN吗&#…

uniapp创建vue3项目(持续更新)

一.项目全局配置 1. 创建项目 使用Hbuilderx工具创建项目, 使用Hbuilderx工具创建项目&#xff0c;选择uni-ui项目模版&#xff0c;VUE3 2.底部菜单栏配置tabBar uniapp官网&#xff1a; 全局文件--pages.json页面路由 -- tabBar 项目文件&#xff1a;pages.json--文件底部…

MM32F3273G8P火龙果开发板MindSDK开发教程18 -sfud库的移植

MM32F3273G8P火龙果开发板MindSDK开发教程18 -sfud库的移植 1、sfud简介 SFUD (Serial Flash Universal Driver) 串行 Flash 通用驱动库 推荐查看官方文档&#xff1a;一款使用 JEDEC SFDP 标准的串行 (SPI) Flash 通用驱动库 2、实验设备 主控&#xff1a;MM32F3273G8P火龙…

Matlab与ROS---深度学习(九)

0. 简介 在了解完上面8讲内容后&#xff0c;基本上ROS和Matlab最关键的部分已经介绍完毕。我们最后一讲就来简单的讲述一下如何在Matlab中结合ROS来完成障碍物的识别与检测。 1. 在Matlab中使用CUDA 配置SimulinkCoder以从Simulink模型生成和构建的CUDA的ROS节点是我们这一小…

如何选择接口测试工具?

目录 前言&#xff1a; 一、易用性 二、灵活性 三、可靠性 四、成本 如何正确选择接口测试工具 测试用例 接口测试数据 自动化测试 测试报告 总结 前言&#xff1a; 接口测试是一种重要的测试类型&#xff0c;常用于Web应用程序和服务的测试。选择一个合适的接口测…

一分钟了解物联存储柜的特点和功能

物联存储柜是一种智能存储柜&#xff0c;具有多种传感器和通信技术&#xff0c;集成物联网和云计算技术&#xff0c;通过自动化、智能化、网络化将传统存储柜与智能设备相结合&#xff0c;自动识别、存取物品&#xff0c;通过网络进行数据交互&#xff0c;实现远程监测和管理功…

矿业变革进行中,北斗技术赋能智慧矿山

近年来&#xff0c;在国家政策支持和技术创新驱动下&#xff0c;国内矿山一直致力于向智能化、数字化方向发展&#xff0c;智慧矿山建设正在加速推进中。 我国自主研发的北斗导航系统&#xff0c;不断与千行百业融合&#xff0c;广泛应用于生产生活的各个领域。“北斗矿业”也成…

怎么自学网安?过程中遇到问题怎么解决

趁着今天下班&#xff0c;我花了几个小时整理了下&#xff0c;非常不易&#xff0c;希望大家可以点赞收藏支持一波&#xff0c;谢谢。 我的经历&#xff1a; 我 19 年毕业&#xff0c;大学专业是物联网工程&#xff0c;我相信很多人在象牙塔里都很迷茫&#xff0c;到了大三大…

JavaScript数学对象-数字进制转换

关注“大前端私房菜”微信公众号&#xff0c;输入暗号【面试宝典】即可免费领取107页前端面试题。 什么是进制 进制就是达到指定位置时候进一位 常见的进制 十进制: 0 1 2 3 4 5 6 7 8 9 10 11 12 ... 99 100 101 二进制: 0 1 10 11 100 101 110 111 1000 八进制: 0 1 2 3 4 …

在thinkBook16的win11基础上安装ubuntu22.04

简介 背景&#xff1a;联想ThinkBook16 pro 32G/512G&#xff0c;系统盘已安装Win11&#xff0c;加装一条M.2-2T固态&#xff0c;想在2T上分一个300GB的EXT4分区&#xff0c;然后把ubuntu22.04安装在该分区上&#xff0c;并实现Win11Linux多系统共存。 目标&#xff1a;实现多…

【C++】STL基本介绍

目录 1、什么是STL 2、STL六大组件 2.1容器 2.2算法 2.3迭代器 1、什么是STL 概念: STL (standard template libaray - 标准模板库)&#xff1a;是 C 标准库的重要组成部分&#xff0c;不仅是一个可复用的组件库&#xff0c;而且是一个包罗数据结构与算法的软件框架。 …

重回游戏公平,向游戏打金工作室宣战!

什么是打金工作室&#xff1f; 近几年中国游戏市场持续发展&#xff0c;国产自研精品游戏层出不穷&#xff0c;游戏产业精品化、高质量健康发展趋势稳定。根据中国音数协游戏工委&#xff08;GPC&#xff09;与中国游戏产业研究院发布的《2022年中国游戏产业报告》显示&#xf…

总结2023开放原子全球开源峰会,中兴国产操作系统的开源贡献

近年来&#xff0c;随着信息技术的不断发展&#xff0c;催生出越来越多的智能场景&#xff0c;作为信息产业的底层技术&#xff0c;国产操作系统所面临的问题也变得越来越复杂。面对新技术和新场景对国产操作系统提出的新挑战、新要求&#xff0c;如何凝聚生态合作伙伴的优势力…

看了这几个C语言例子,你一定和我一样连说5个卧槽,声音一次比一次大

曾经我一直以为自己C语言学的还挺好的&#xff0c;直到看到这几个例子。 例1 首先来看一下&#xff0c;大师是如何求圆周率的&#xff0c;一口君实在词穷&#xff0c;first卧槽。 #include <stdio.h>long a10000,b0,c10000,d,e,f[10001],g;void main(){for(;b ! c; f[…

Rust 基础语法

Rust 基础语法 变量&#xff0c;基本类型&#xff0c;函数&#xff0c;注释和控制流&#xff0c;这些几乎是每种编程语言都具有的编程概念。 这些基础概念将存在于每个 Rust 程序中&#xff0c;及早学习它们将使你以最快的速度学习 Rust 的使用。 变量 首先必须说明&#x…

AIAgent来了!AutoGPT的新对手

AutoGPT 和 AgentGPT遇到了更强的对手&#xff0c;我来介绍一下 http://AIAgent.app 这个网站。 http://AIAgent.app 是一个可以让你使用人工智能代理来完成各种任务的网站。你只需要设置一个目标&#xff0c;然后选择一个合适的代理&#xff0c;它就会自动为你执行任务&#…

LED显示屏薄膜类型有哪些

LED显示屏薄膜是指应用在LED显示屏的薄膜材料&#xff0c;用于保护LED模块和增强显示效果。以下是LED显示屏薄膜知识的详细说明&#xff1a; 防护膜&#xff08;Protective Film&#xff09;&#xff1a;防护膜是一层透明的薄膜材料&#xff0c;常用于覆盖在LED显示屏的正面&am…

Android 手机自动化测试工具有哪几种?

文章大纲&#xff1a; 1、Android手机自动化测试工具&#xff0c;常用的有这7种 2、化繁为简&#xff0c;补充移动端自动化测试工具 3、这么多工具&#xff0c;工作中该如何选择 4、掌握自动化测试工具的学习建议 一、Android手机自动化测试工具&#xff0c;常用的有这7中&…