直接贴代码

#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的自动寻路算法的更多相关文章

  1. 用 Python 为接口测试自动生成用例

    用Python为接口自动生成测试用例 基于属性的测试会产生大量的.随机的参数,特别适合为单元测试和接口测试生成测试用例 尽管早在2006年haskell语言就有了QuickCheck来进行" ...

  2. 基于上三角变换或基于DFS的行(列)展开的n阶行列式求值算法分析及性能评估

    进入大一新学期,看完<线性代数>前几节后,笔者有了用计算机实现行列式运算的想法.这样做的目的,一是巩固自己对相关概念的理解,二是通过独立设计算法练手,三是希望通过图表直观地展现涉及的两种算 ...

  3. 基于MVC4+EasyUI的Web开发框架经验总结(14)--自动生成图标样式文件和图标的选择操作

    在很多Web系统中,一般都可能提供一些图标的选择,方便配置按钮,菜单等界面元素的图标,从而是Web系统界面看起来更加美观和协调.但是在系统中一般内置的图标样式相对比较有限,而且硬编码写到样式表里面,这 ...

  4. 基于OCILIB的oracle数据库操作总结及自动生成Model和Dao的工具

    基于OCILIB的oracle数据库操作总结 1.       类图 2.       基类BaseOCIDao的设计与实现 BaseOCIDao.h头文件 #pragma once /* ----- ...

  5. 基于eclipse的mybatis映射代码自动生成的插件

    基于eclipse的mybatis映射代码自动生成的插件 分类: JAVA 数据库 工具相关2012-04-29 00:15 2157人阅读 评论(9) 收藏 举报 eclipsegeneratori ...

  6. 基于eclipse的mybatis映射代码自动生成的插件http://blog.csdn.net/fu9958/article/details/7521681

    基于eclipse的mybatis映射代码自动生成的插件 分类: JAVA 数据库 工具相关2012-04-29 00:15 2157人阅读 评论(9) 收藏 举报 eclipsegeneratori ...

  7. 基于数据库的自动化生成工具,自动生成JavaBean、自动生成数据库文档等(v4.1.2版)

            目录:            第1版:http://blog.csdn.net/vipbooks/article/details/51912143            第2版:htt ...

  8. API的文档自动生成——基于CDIF的SOA基本能力

    当前,作为大部分移动app和云服务后台之间的标准连接方式,REST API已经得到了绝大部分开发者的认可和广泛的应用.近年来,在新兴API经济模式逐渐兴起,许多厂商纷纷将自己的后台业务能力作为REST ...

  9. 基于MATLAB2016b图形化设计自动生成Verilog语言的积分模块及其应用

    在电力电子变流器设备中,常常需要计算发电量,由于电力电子变流器设备一般是高频变流设备,所以发电量的计算几乎时实时功率的积分,此时就会用到一个积分模块.发电量计算的公式如下:Q=∫P. FPGA由于其并 ...

随机推荐

  1. 使用Oracle Sql Developer将SQL SERVER 2008数据库移植到Oracle 11g

    ORACLE官方提供的Sql Developer自带的Oracle Migration Workbench. 什么是Oracle SQL Developer?在官方页面上,是这样介绍它的: Oracl ...

  2. bzoj1509

    树的直径 我先开始以为是个图,想想并不知道什么求图的直径的方法,结果是棵树 那么直觉告诉我们是在直径上面,实际上就是直径+min(i->u,i->v),扫一遍就行了 #include< ...

  3. Spring Theme简单应用

    Spring MVC特性里由一个是关于Spring Theme主题的应用,所以写了个Demo 1.这里先看项目结构(Meven项目) 2.所需的POM依赖 <dependency> < ...

  4. (数论)51NOD 1079 中国剩余定理

    一个正整数K,给出K Mod 一些质数的结果,求符合条件的最小的K.例如,K % 2 = 1, K % 3 = 2, K % 5 = 3.符合条件的最小的K = 23.   Input 第1行:1个数 ...

  5. c++ string函数合集

    s.substr(x,len) 在s中取出从x位置开始,长度为len的字符串,并返回string类型的字符串. s.find(a) 在s中查找字符串a,并返回起始下标(从0开始),若不存在,返回184 ...

  6. Linux环境下卸载、安装及配置MySQL5.1

    Linux环境下卸载原有MySQL5.1数据库,并重新安装MySQL数据库的示例记录. 一.卸载MySQL 查看主机中是否安装了MySQL数据库: [root@RD-viPORTAL- ~]# rpm ...

  7. 全面学习ORACLE Scheduler特性(4)创建和管理Schedule

    三.使用Schedules 10g 中新推出的SCHEDULER可能确实会让很多初接触的朋友感觉晕头晕脑,相比之前的jobs,SCHEDULER中新增的概念太多.比如说jobs,仍然可以理解成之前版本 ...

  8. java 分解整数 【个 十 百】(数组案例)

    求一个数两位数的个位数,十位数,百位数及千位: int num = 53; int g = (num / 1) % 10;  //个位 int s = (num / 10) % 10; //十位 in ...

  9. PHP安装yaf在ubuntu下面的问题解决

    1.在执行make的时候出现如下错误: In file included from /root/yaf-2.1.2/yaf_router.c:28: /usr/include/php/ext/pcre ...

  10. Javascript的一些技巧(《Javascript DOM编程艺术》、Javascript语言精粹)

    1.什么时候用布尔变量当变量 假设你需要一个这样的变量:我在睡觉——存为一个值:我没在睡觉——存为另一个值. 一般的做法: var stateOne="睡觉",stateTwo=& ...