直接贴代码

#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. HDU2072单词数

    #include<iostream> #include<set> #include<sstream> using namespace std; int main() ...

  2. 00020970-0000-0000-C000-000000000046

    00020970-0000-0000-C000-000000000046 System.InvalidCastException: 无法将类型为“Microsoft.Office.Interop.Wo ...

  3. WinForm里面连接Oracle数据库

    WinForm里面连接Oracle数据库 string oradb = "Data Source=(DESCRIPTION="             + "(ADDRE ...

  4. 上百例Silverlight网站及演示汇总,供友参考

    毁灭2012 博客园 首页 新闻 新随笔 联系 管理 订阅 随笔- 125  文章- 0  评论- 446  上百例Silverlight网站及演示汇总,供友参考   今天我将发现的Silverlig ...

  5. T3 最短路 line

    T3 最短路 line [问题描述] 给定一个 n 个点,m 条边的有向图,每个点有一个权值 a[i],表示这个点要到达多少次,1 为起始点,从 1 到 i 的距离为 d[i],请你输出∑a[i]*d ...

  6. bzoj 3733: [Pa2013]Iloczyn【dfs】

    参考:http://www.cnblogs.com/clrs97/p/5125976.html 瞎搞约数失败...滚去搜索 dfs(x,y,z) 表示当前可选第x到第m个约数,还要选y个约数,已有z的 ...

  7. 关于Anaconda环境变量配置遇到的一些情况说明

    安装和配置环境变量的话就不多说了,大家可以参照这个说的去做就行 https://blog.csdn.net/weixin_42997646/article/details/89414769 验证配置环 ...

  8. 2017西安网络赛B_Coin

    样例输入 2 2 1 1 3 1 2 样例输出 500000004 555555560 思路: n重伯努利实验概率分布题. 设q=1-p,p为事件概率. Y为出现偶数次的概率. 所以  Y=1/2*( ...

  9. 贪心 FZU 2013 A short problem

    题目传送门 /* 题意:取长度不小于m的序列使得和最大 贪心:先来一个前缀和,只要长度不小于m,从m开始,更新起点k最小值和ans最大值 */ #include <cstdio> #inc ...

  10. springmvc中的web.xml配置(包含中文乱码解决)

    <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http:// ...