直接贴代码

#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. [整理]EABI和OABI【转】

    本文转载自:https://www.crifan.com/order_eabi_and_oabi/ 1.什么是ABIABI,application binary interface (ABI),应用程 ...

  2. python-----获取ip的两种方法

    方法一: 通常使用socket.gethostbyname()方法即可获取本机IP地址,但有时候获取不到(比如没有正确设置主机名称),示例代码如下: import socket # 获取本机计算机名称 ...

  3. JSP-Runoob:JSP 结构

    ylbtech-JSP-Runoob:JSP 结构 1.返回顶部 1. JSP 结构 网络服务器需要一个 JSP 引擎,也就是一个容器来处理 JSP 页面.容器负责截获对 JSP 页面的请求.本教程使 ...

  4. Java序列化系列教程(下)

    一引言 将 Java 对象序列化为二进制文件的 Java 序列化技术是 Java 系列技术中一个较为重要的技术点,在大部分情况下,开发人员只需要了解被序列化的类需要实现 Serializable 接口 ...

  5. Linux 下安装配置 JDK7(转载)

    转自:http://dawndiy.com/archives/155/ 自从从Oracle收购Sun近三年来,已经有很多变化.早在8月,甲骨文将“Operating System Distributo ...

  6. [Swift通天遁地]一、超级工具-(12)使用Toaster制作简短提示语的吐司窗口

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  7. AutoCAD2013 以上利用AccoreConsole+ c# NetApi 批量处理图纸

    AccoreConsole听起来有点拗口,其中文名可以叫做AutoCAD控制台或者无头AutoCAD.一句话概括,它是快速启动AutoCAD运行微环境,高效的处理图纸.你可以如同DOS命令行一样操作命 ...

  8. 使用nginx加zuul配置

    配置文件 $ ls -lrt -rw-r--r-- 1 root root 826 May 10 10:56 nginx.conf $ pwd /etc/nginx 增加配置 在http {}里 up ...

  9. httpd 安装ssl证书

    1) 安装ssl模块 # yum install mod_ssl -y Ps:安装完成后,会在/etc/httpd/conf.d/下生成一个ssl.conf配置文件. 2) 先建一个目录用来放ssl证 ...

  10. 371 Sum of Two Integers 两整数之和

    不使用运算符 + 和-,计算两整数a .b之和.示例:若 a = 1 ,b = 2,返回 3. 详见:https://leetcode.com/problems/sum-of-two-integers ...