经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C++ » 查看文章
迷宫自动生成以及基于DFS的自动寻路算法
来源:cnblogs  作者:秋叶落  时间:2018/11/23 10:16:45  对本文有异议

直接贴代码

  1. #include<ctime>
  2. #include<conio.h>
  3. #include<iostream>
  4. #include<windows.h>
  5. #include<deque>
  6. #include<queue>
  7. #include<list>
  8. #include<vector>
  9. #include<algorithm>
  10. #include <ctime>
  11. #include <cstdlib>
  12. #include <stack>
  13. using namespace std;
  14. #define MAX 50
  15. #define X_MAX MAX
  16. #define Y_MAX MAX
  17.  
  18. int Map[X_MAX][Y_MAX];
  19. #define MA 10 //迷宫的规模不能过小
  20.  
  21. //挖洞法造迷宫,为了包围,只能为奇数行列,过小的地图无法生成迷宫
  22. #if MA<5
  23. #undef MA
  24. #define MA 6
  25. #endif
  26. #if !(MA%2)
  27. #define M (MA+1)
  28. #else
  29. #define M MA
  30. #endif
  31.  
  32. using namespace std;
  33. //迷宫格子类型,记录了是否被挖过
  34. class Grid {
  35. public:
  36. //是否访问 是否为空
  37. bool cell, dig;
  38. int em;
  39. };
  40. struct Node
  41. {
  42. int X, Y;
  43. bool operator==(const Node& n)
  44. {
  45. return (this->X == n.X) && (this->Y == n.Y);
  46. }
  47. };
  48. Grid maze[M][M];
  49. #pragma region 网上抄的一段挖洞法造迷宫,懒得自己弄
  50.  
  51.  
  52. //用来存放路径的栈
  53. stack<int> row_s, col_s;
  54. //初始化迷宫格子
  55. void Init() {
  56. for (int i = 0; i < M; i++) {
  57. for (int j = 0; j < M; j++) {
  58. maze[i][j].dig = false;
  59. if (i % 2 != 0 && j % 2 != 0)
  60. maze[i][j].cell = true;
  61. }
  62. }
  63. row_s.push(1); col_s.push(1);
  64. srand(static_cast<unsigned int> (time(0)));
  65. maze[1][0].cell = true;
  66. maze[M - 2][M - 1].cell = true;
  67. }
  68. //判断周围情况,没有可挖的格子时返回-1
  69. int DirRand() {
  70. vector <int> dirlist; //用来记录可选择的方向
  71.  
  72. int result = 0;
  73. int row = row_s.top(), col = col_s.top();
  74. //0 up, 1 down, 2 left, 3 right
  75. if (row - 2 > 0 && !maze[row - 2][col].dig)
  76. dirlist.push_back(0);
  77. if (row + 2 < M - 1 && !maze[row + 2][col].dig)
  78. dirlist.push_back(1);
  79. if (col - 2 > 0 && !maze[row][col - 2].dig)
  80. dirlist.push_back(2);
  81. if (col + 2 < M - 1 && !maze[row][col + 2].dig)
  82. dirlist.push_back(3);
  83. if (dirlist.size() == 0)
  84. result = -1;
  85. else
  86. result = dirlist[rand() % ((int)dirlist.size())];
  87. return
  88. result;
  89. }
  90. //制造迷宫
  91. void GenMaze() {
  92. while (!row_s.empty() && !col_s.empty()) {
  93. int dir = DirRand();
  94. int row = row_s.top(), col = col_s.top();
  95. if (dir != -1) { //前进
  96.  
  97. if (dir == 0) {
  98. maze[row - 2][col].dig = maze[row - 1][col].dig = true;
  99. row_s.push(row - 2);
  100. col_s.push(col);
  101. }
  102. else if (dir == 1) {
  103. maze[row + 2][col].dig = maze[row + 1][col].dig = true;
  104. row_s.push(row + 2);
  105. col_s.push(col);
  106. }
  107. else if (dir == 2) {
  108. maze[row][col - 2].dig = maze[row][col - 1].dig = true;
  109. row_s.push(row);
  110. col_s.push(col - 2);
  111. }
  112. else if (dir == 3) {
  113. maze[row][col + 2].dig = maze[row][col + 1].dig = true;
  114. row_s.push(row);
  115. col_s.push(col + 2);
  116. }
  117. }
  118. else {
  119. row_s.pop();
  120. col_s.pop(); //后退
  121. }
  122. }
  123. }
  124. //输出迷宫
  125. void OutMaze() { //输出迷宫
  126.  
  127. for (int i = 0; i < M; i++) {
  128. for (int j = 0; j < M; j++) {
  129. if (maze[i][j].em == 3) {
  130. printf("%2c", '*');
  131. continue;
  132. }
  133. if (maze[i][j].cell || maze[i][j].dig) {
  134. printf("%2c", ' ');
  135. if (maze[i][j].em != 3)
  136. maze[i][j].em = true;
  137. }
  138. else {
  139. //为了保证对齐,墙壁和道路宽都是2个字符
  140. cout << "";
  141. if (maze[i][j].em != 3)
  142. maze[i][j].em = false;
  143. }
  144. }
  145. cout << endl;
  146. }
  147. }
  148. //保存迷宫路径
  149. stack<Node> path;
  150. //已经查找的点
  151. vector<Node> closelist;
  152. //查看该点是否查找过 返回1在 返回0不在
  153. bool FindCloseList(Node n)
  154. {
  155. auto var = find(closelist.begin(), closelist.end(), n);
  156. return !(var == closelist.end());
  157. }
  158. #pragma endregion
  159.  
  160. //该函数可以抠出来放在自己程序,需要地图地图数组 起始坐标(beginX,beginY)终点坐标(endX,endY),结果保留在一个栈中
  161. //有待优化 在迷宫有环的时候,找到的路径不一定是最短的,问题先放在这,以后有时间再想办法
  162. //返回>1为找到 返回0为没找到
  163. int FindMaze(int beginX, int beginY, int endX, int endY) {
  164. int kbz = 1;
  165. //待查找的节点
  166. stack<Node> lopenlist;
  167. //节点不在地图范围
  168. if (beginX < 0 || beginY < 0 || beginX >= M || beginY >= M)
  169. return 0;
  170. //起始点加入寻找列表
  171. closelist.push_back({ beginX,beginY });
  172. //找到节点
  173. if ((beginX == endX) && (beginY == endY)) {
  174. //将该节点添加到路径
  175. path.push({ beginX,beginY });
  176. return 1;
  177. }
  178. #pragma region 查找目标节点周围四个节点,如果要增加斜线功能,可以在此添加
  179.  
  180. //检查(beginX,beginY+1)节点
  181. if (beginY + 1 < M && maze[beginX][beginY + 1].em == 1) {
  182. //该节点没找过 加入待查找节点列表
  183. if (!FindCloseList({ beginX,beginY + 1 })) {
  184. lopenlist.push({ beginX,beginY + 1 });
  185. }
  186. }
  187. //检查(beginX,beginY-1)节点
  188. if (beginY - 1 >= 0 && maze[beginX][beginY - 1].em == 1)
  189. {
  190. if (!FindCloseList({ beginX,beginY - 1 })) {
  191. lopenlist.push({ beginX,beginY - 1 });
  192. }
  193. }
  194. //检查(beginX-1,beginY)节点
  195. if (beginX - 1 >= 0 && maze[beginX - 1][beginY].em == 1) {
  196. if (!FindCloseList({ beginX - 1,beginY })) {
  197. lopenlist.push({ beginX - 1,beginY });
  198. }
  199. }
  200. //检查(beginX+1,beginY)节点
  201. if (beginX + 1 < M &&maze[beginX + 1][beginY].em == 1) {
  202. if (!FindCloseList({ beginX + 1,beginY })) {
  203. lopenlist.push({ beginX + 1,beginY });
  204. }
  205. }
  206. #pragma endregion
  207.  
  208. //遍历每一个待查找的节点
  209. while (!lopenlist.empty())
  210. {
  211. //取出一个节点
  212. int x = lopenlist.top().X;
  213. int y = lopenlist.top().Y;
  214. lopenlist.pop();
  215. //递归查找
  216. auto k = FindMaze(x, y, endX, endY);
  217. //找到就证明该节点为路径点,加入路径栈中
  218. if (k)
  219. {
  220. path.push({ beginX,beginY });
  221. return kbz + k;
  222. }
  223. }
  224. return 0;
  225. }
  226. int main() {
  227. //初始化
  228. Init();
  229. //制造迷宫
  230. GenMaze();
  231. //输出迷宫
  232. OutMaze();
  233. //寻找路径
  234. if (!FindMaze(1, 0, M - 2, M - 1))
  235. {
  236. cout << "没找到出口";
  237. return -1;
  238. }
  239. //依次从栈中取出每一个路径
  240. while (!path.empty())
  241. {
  242. cout << "(" << path.top().X << "," << path.top().Y << ")";
  243. maze[path.top().X][path.top().Y].em = 3;
  244. path.pop();
  245. if (!path.empty())
  246. cout << ",";
  247. }
  248. cout << endl;
  249. cout << "--------------------------------------------" << endl;
  250. OutMaze();
  251. system("pause");
  252. return 0;
  253. }

 

 

 

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号