迷宫自动生成以及基于DFS的自动寻路算法
直接贴代码
#include<ctime>
#include<conio.h>
#include<iostream>
#include<windows.h>
#include<deque>
#include<queue>
#include<list>
#include<vector>
#include<algorithm>
#include <ctime>
#include <cstdlib>
#include <stack>
using namespace std; #define MAX 50
#define X_MAX MAX
#define Y_MAX MAX int Map[X_MAX][Y_MAX]; #define MA 10 //迷宫的规模不能过小 //挖洞法造迷宫,为了包围,只能为奇数行列,过小的地图无法生成迷宫
#if MA<5
#undef MA
#define MA 6
#endif
#if !(MA%2)
#define M (MA+1)
#else
#define M MA
#endif using namespace std; //迷宫格子类型,记录了是否被挖过
class Grid { public:
//是否访问 是否为空
bool cell, dig;
int em; };
struct Node
{
int X, Y; bool operator==(const Node& n)
{
return (this->X == n.X) && (this->Y == n.Y);
} }; Grid maze[M][M]; #pragma region 网上抄的一段挖洞法造迷宫,懒得自己弄 //用来存放路径的栈
stack<int> row_s, col_s; //初始化迷宫格子
void Init() { for (int i = ; i < M; i++) { for (int j = ; j < M; j++) { maze[i][j].dig = false; if (i % != && j % != ) maze[i][j].cell = true;
} } row_s.push(); col_s.push(); srand(static_cast<unsigned int> (time())); maze[][].cell = true; maze[M - ][M - ].cell = true; } //判断周围情况,没有可挖的格子时返回-1
int DirRand() { vector <int> dirlist; //用来记录可选择的方向 int result = ;
int row = row_s.top(), col = col_s.top(); //0 up, 1 down, 2 left, 3 right
if (row - > && !maze[row - ][col].dig)
dirlist.push_back(); if (row + < M - && !maze[row + ][col].dig)
dirlist.push_back(); if (col - > && !maze[row][col - ].dig)
dirlist.push_back(); if (col + < M - && !maze[row][col + ].dig)
dirlist.push_back(); if (dirlist.size() == )
result = -;
else
result = dirlist[rand() % ((int)dirlist.size())];
return
result; }
//制造迷宫
void GenMaze() { while (!row_s.empty() && !col_s.empty()) {
int dir = DirRand();
int row = row_s.top(), col = col_s.top(); if (dir != -) { //前进 if (dir == ) { maze[row - ][col].dig = maze[row - ][col].dig = true; row_s.push(row - );
col_s.push(col); }
else if (dir == ) { maze[row + ][col].dig = maze[row + ][col].dig = true; row_s.push(row + );
col_s.push(col); }
else if (dir == ) { maze[row][col - ].dig = maze[row][col - ].dig = true; row_s.push(row);
col_s.push(col - ); }
else if (dir == ) { maze[row][col + ].dig = maze[row][col + ].dig = true; row_s.push(row); col_s.push(col + );
}
}
else { row_s.pop();
col_s.pop(); //后退 } } }
//输出迷宫
void OutMaze() { //输出迷宫 for (int i = ; i < M; i++) { for (int j = ; j < M; j++) {
if (maze[i][j].em == ) {
printf("%2c", '*');
continue;
}
if (maze[i][j].cell || maze[i][j].dig) {
printf("%2c", ' ');
if (maze[i][j].em != )
maze[i][j].em = true;
}
else { //为了保证对齐,墙壁和道路宽都是2个字符
cout << "■";
if (maze[i][j].em != )
maze[i][j].em = false;
}
}
cout << endl;
}
} //保存迷宫路径
stack<Node> path; //已经查找的点
vector<Node> closelist; //查看该点是否查找过 返回1在 返回0不在
bool FindCloseList(Node n)
{
auto var = find(closelist.begin(), closelist.end(), n);
return !(var == closelist.end());
} #pragma endregion //该函数可以抠出来放在自己程序,需要地图地图数组 起始坐标(beginX,beginY)终点坐标(endX,endY),结果保留在一个栈中
//有待优化 在迷宫有环的时候,找到的路径不一定是最短的,问题先放在这,以后有时间再想办法
//返回>1为找到 返回0为没找到
int FindMaze(int beginX, int beginY, int endX, int endY) { int kbz = ;
//待查找的节点
stack<Node> lopenlist;
//节点不在地图范围
if (beginX < || beginY < || beginX >= M || beginY >= M)
return ;
//起始点加入寻找列表
closelist.push_back({ beginX,beginY }); //找到节点
if ((beginX == endX) && (beginY == endY)) {
//将该节点添加到路径
path.push({ beginX,beginY });
return ;
}
#pragma region 查找目标节点周围四个节点,如果要增加斜线功能,可以在此添加 //检查(beginX,beginY+1)节点
if (beginY + < M && maze[beginX][beginY + ].em == ) {
//该节点没找过 加入待查找节点列表
if (!FindCloseList({ beginX,beginY + })) { lopenlist.push({ beginX,beginY + });
}
}
//检查(beginX,beginY-1)节点
if (beginY - >= && maze[beginX][beginY - ].em == )
{
if (!FindCloseList({ beginX,beginY - })) { lopenlist.push({ beginX,beginY - });
}
}
//检查(beginX-1,beginY)节点
if (beginX - >= && maze[beginX - ][beginY].em == ) { if (!FindCloseList({ beginX - ,beginY })) { lopenlist.push({ beginX - ,beginY });
}
}
//检查(beginX+1,beginY)节点
if (beginX + < M &&maze[beginX + ][beginY].em == ) {
if (!FindCloseList({ beginX + ,beginY })) { lopenlist.push({ beginX + ,beginY }); }
}
#pragma endregion //遍历每一个待查找的节点
while (!lopenlist.empty())
{
//取出一个节点
int x = lopenlist.top().X;
int y = lopenlist.top().Y;
lopenlist.pop();
//递归查找
auto k = FindMaze(x, y, endX, endY);
//找到就证明该节点为路径点,加入路径栈中
if (k)
{
path.push({ beginX,beginY });
return kbz + k;
}
}
return ;
} int main() {
//初始化
Init();
//制造迷宫
GenMaze();
//输出迷宫
OutMaze();
//寻找路径
if (!FindMaze(, , M - , M - ))
{
cout << "没找到出口";
return -;
}
//依次从栈中取出每一个路径
while (!path.empty())
{
cout << "(" << path.top().X << "," << path.top().Y << ")";
maze[path.top().X][path.top().Y].em = ;
path.pop();
if (!path.empty())
cout << ",";
}
cout << endl;
cout << "--------------------------------------------" << endl; OutMaze();
system("pause");
return ; }
迷宫自动生成以及基于DFS的自动寻路算法的更多相关文章
- 用 Python 为接口测试自动生成用例
用Python为接口自动生成测试用例 基于属性的测试会产生大量的.随机的参数,特别适合为单元测试和接口测试生成测试用例 尽管早在2006年haskell语言就有了QuickCheck来进行" ...
- 基于上三角变换或基于DFS的行(列)展开的n阶行列式求值算法分析及性能评估
进入大一新学期,看完<线性代数>前几节后,笔者有了用计算机实现行列式运算的想法.这样做的目的,一是巩固自己对相关概念的理解,二是通过独立设计算法练手,三是希望通过图表直观地展现涉及的两种算 ...
- 基于MVC4+EasyUI的Web开发框架经验总结(14)--自动生成图标样式文件和图标的选择操作
在很多Web系统中,一般都可能提供一些图标的选择,方便配置按钮,菜单等界面元素的图标,从而是Web系统界面看起来更加美观和协调.但是在系统中一般内置的图标样式相对比较有限,而且硬编码写到样式表里面,这 ...
- 基于OCILIB的oracle数据库操作总结及自动生成Model和Dao的工具
基于OCILIB的oracle数据库操作总结 1. 类图 2. 基类BaseOCIDao的设计与实现 BaseOCIDao.h头文件 #pragma once /* ----- ...
- 基于eclipse的mybatis映射代码自动生成的插件
基于eclipse的mybatis映射代码自动生成的插件 分类: JAVA 数据库 工具相关2012-04-29 00:15 2157人阅读 评论(9) 收藏 举报 eclipsegeneratori ...
- 基于eclipse的mybatis映射代码自动生成的插件http://blog.csdn.net/fu9958/article/details/7521681
基于eclipse的mybatis映射代码自动生成的插件 分类: JAVA 数据库 工具相关2012-04-29 00:15 2157人阅读 评论(9) 收藏 举报 eclipsegeneratori ...
- 基于数据库的自动化生成工具,自动生成JavaBean、自动生成数据库文档等(v4.1.2版)
目录: 第1版:http://blog.csdn.net/vipbooks/article/details/51912143 第2版:htt ...
- API的文档自动生成——基于CDIF的SOA基本能力
当前,作为大部分移动app和云服务后台之间的标准连接方式,REST API已经得到了绝大部分开发者的认可和广泛的应用.近年来,在新兴API经济模式逐渐兴起,许多厂商纷纷将自己的后台业务能力作为REST ...
- 基于MATLAB2016b图形化设计自动生成Verilog语言的积分模块及其应用
在电力电子变流器设备中,常常需要计算发电量,由于电力电子变流器设备一般是高频变流设备,所以发电量的计算几乎时实时功率的积分,此时就会用到一个积分模块.发电量计算的公式如下:Q=∫P. FPGA由于其并 ...
随机推荐
- 定时删除clientmqueue
* * */1 * * cd /var/spool; cp -r clientmqueue /home/data/xl_project/var_spool_clientmqueue_$(date + ...
- NTFS文件系统的单个文件最大到底有多大?
于NTFS文件系统的单个文件最大到底有多大? 闲来无事突然想到这个问题,到网上搜索了一下也没有一个固定的解释. 于是到微软官方知识库去寻找答案: 注意:基础硬件限制可能会对任何文件系统施加额外的分区大 ...
- 预载入和javascript对象
请参见 http://www.west263.com/info/html/wangyezhizuo/Javascript/20080225/34168.html
- 深度学习——无监督,自动编码器——尽管自动编码器与 PCA 很相似,but自动编码器既能表征线性变换,也能表征非线性变换;而 PCA 只能执行线性变换
自动编码器是一种有三层的神经网络:输入层.隐藏层(编码层)和解码层.该网络的目的是重构其输入,使其隐藏层学习到该输入的良好表征. 自动编码器神经网络是一种无监督机器学习算法,其应用了反向传播,可将目标 ...
- windows7 RDP修改
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\TerminalServer\WinStations\RDP Tcp\PortNumber”.
- 利用XStream实现对象XML话
使用Java原生的序列化的方式来表示一个对象.总结一下这种对象表示方式的优缺点: 1.纯粹的Java环境下这种方式可以很好地工作,因为它是Java自带的,也不需要第三方的Jar包的支持 2.多语言环境 ...
- ngCordova插件说明
转载自 http://my.oschina.net/u/1416844/blog/495026 参 考http://blog.csdn.net/superjunjin/article/details/ ...
- [Swift]Array数组的swapAt函数
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
- May Challenge 2019 Division 2 水题讲解
Reduce to One 这题其实蛮水的? 题意就是说: 给定一个 1~n 的序列,每次挑两个数 x y 合并,合并值为 \(x+y+xy\) ,然后求不断合并最后剩下的一个的最大值 随便搞搞发现答 ...
- [转]c 语言中 %d,%lu等区别
转载至:http://blog.sina.com.cn/s/blog_7d94c35c01019f96.html %d 有符号10进制整数 %ld 长整型 %hd短整型 %hu 无符号短整形 %u无符 ...