maze.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  1. #include <stdio.h> //getchar()
  2. #include <termios.h> //终端设置
  3. #include <unistd.h> //延时函数
  4. #include <cstdlib> //标准库
  5. #include <ctime> //时间函数
  6. #include <iostream> //输入输出流
  7. using namespace std; //命名空间
  8. #define MAX_X 20
  9. #define MAX_Y 30
  10. bool flag = false;
  11. bool slow = false;
  12. bool autogame = true;
  13. int maze[MAX_X][MAX_Y]; //迷宫地图
  14. class stack_of_maze {
  15. private:
  16. //记录迷宫坐标
  17. struct node {
  18. int x;
  19. int y;
  20. char direction; //上一步路径(如何来的)
  21. node* next;
  22. };
  23. node* head;
  24. public:
  25. stack_of_maze() {
  26. //初始化
  27. head = NULL;
  28. }
  29. ~stack_of_maze() {
  30. node* p = head;
  31. //逐个删除
  32. while (head != NULL) {
  33. head = head->next;
  34. delete p;
  35. p = head;
  36. }
  37. }
  38. void push(int xx, int yy, char ddirection) {
  39. //定义一个新节点
  40. node* new_node = new node;
  41. //赋值
  42. if (new_node != NULL) {
  43. new_node->x = xx;
  44. new_node->y = yy;
  45. new_node->direction = ddirection;
  46. new_node->next = NULL;
  47. //判断栈是否为空,如果为空则直接把新节点赋值给栈,否则添加到栈顶
  48. if (head == NULL)
  49. head = new_node;
  50. else {
  51. new_node->next = head;
  52. head = new_node;
  53. }
  54. } else
  55. cout << "内存分配失败" << endl;
  56. }
  57. node* pop(int& xx, int& yy) {
  58. if (head != NULL) {
  59. node* p = head;
  60. head = head->next;
  61. xx = p->x;
  62. yy = p->y;
  63. delete p;
  64. }
  65. return head;
  66. }
  67. void print() {
  68. if (head != NULL) {
  69. node* p = head;
  70. while (p != NULL) {
  71. cout << " " << p->x << " " << p->y << " " << p->direction << endl;
  72. p = p->next;
  73. }
  74. } else
  75. cout << "栈为空,打印失败" << endl;
  76. }
  77. };
  78. void createMaze() {
  79. int maxway = MAX_X * MAX_Y; //最大通路
  80. int x, y;
  81. //先填充迷宫
  82. for (x = 0; x < MAX_X; x++)
  83. for (y = 0; y < MAX_Y; y++) maze[x][y] = 1;
  84. //随机函数种子,以时间为参数
  85. srand((unsigned)time(NULL));
  86. //随机构建迷宫通路
  87. for (int i = 0; i < maxway; i++) {
  88. x = rand() % (MAX_X - 2) + 1;
  89. y = rand() % (MAX_Y - 2) + 1;
  90. maze[x][y] = 0;
  91. }
  92. maze[1][1] = 0; //入口
  93. maze[MAX_X - 2][MAX_Y - 2] = 0; //出口
  94. maze[0][1] = 3;
  95. maze[MAX_X - 1][MAX_Y - 2] = 0;
  96. }
  97. void printMaze() {
  98. int x, y;
  99. //清屏,如果是windows环境使用system("cls")
  100. system("clear");
  101. //打印地图
  102. for (x = 0; x < MAX_X; x++) {
  103. for (y = 0; y < MAX_Y; y++) {
  104. if (maze[x][y] == 0) {
  105. cout << " ";
  106. continue;
  107. } //通路
  108. if (maze[x][y] == 1) {
  109. cout << "■ ";
  110. continue;
  111. } //墙
  112. if (maze[x][y] == 2) {
  113. cout << "× ";
  114. continue;
  115. } //死胡同
  116. if (maze[x][y] == 3) {
  117. cout << "↓ ";
  118. continue;
  119. } //向下走
  120. if (maze[x][y] == 4) {
  121. cout << "→ ";
  122. continue;
  123. }
  124. if (maze[x][y] == 5) {
  125. cout << "← ";
  126. continue;
  127. }
  128. if (maze[x][y] == 6) {
  129. cout << "↑ ";
  130. continue;
  131. }
  132. if (maze[x][y] == 7) {
  133. cout << "※ ";
  134. continue;
  135. } //当前站立位置
  136. }
  137. cout << endl;
  138. }
  139. //是否慢速游戏
  140. if (slow) {
  141. sleep(1); //延时函数
  142. }
  143. }
  144. void check(stack_of_maze& s) {
  145. //备份地图
  146. int temp[MAX_X][MAX_Y];
  147. for (int x = 0; x < MAX_X; x++)
  148. for (int y = 0; y < MAX_Y; y++) temp[x][y] = maze[x][y];
  149. int x = 1, y = 1; //出发点
  150. while (1) {
  151. temp[x][y] = 2;
  152. //向下
  153. if (temp[x + 1][y] == 0) {
  154. s.push(x, y, 'D');
  155. //在当前位置做一个向下的标志
  156. temp[x][y] = 3;
  157. x = x + 1;
  158. temp[x][y] = 7; //当前位置
  159. //判断是否到达出口,如果到达出口则flag标记为true,下同
  160. if ((x == MAX_X - 1) && (y == MAX_Y - 2)) {
  161. flag = true;
  162. return;
  163. } else
  164. continue;
  165. }
  166. //向右
  167. if (temp[x][y + 1] == 0) {
  168. s.push(x, y, 'R');
  169. //在当前位置做一个向右的标志
  170. temp[x][y] = 4;
  171. y = y + 1;
  172. temp[x][y] = 7;
  173. if ((x == MAX_X - 1) && (y == MAX_Y - 2)) {
  174. flag = true;
  175. return;
  176. } else
  177. continue;
  178. }
  179. //向上
  180. if (temp[x - 1][y] == 0) {
  181. s.push(x, y, 'U');
  182. //在当前位置做一个向上的标志
  183. temp[x][y] = 6;
  184. x = x - 1;
  185. temp[x][y] = 7;
  186. if ((x == MAX_X - 1) && (y == MAX_Y - 2)) {
  187. flag = true;
  188. return;
  189. } else
  190. continue;
  191. }
  192. //向左
  193. if (temp[x][y - 1] == 0) {
  194. s.push(x, y, 'L');
  195. //在当前位置做一个向右的标志
  196. temp[x][y] = 5;
  197. y = y - 1;
  198. temp[x][y] = 7;
  199. if ((x == MAX_X - 1) && (y == MAX_Y - 2)) {
  200. flag = true;
  201. return;
  202. } else
  203. continue;
  204. }
  205. //上下左右不通,则回退到起点
  206. if (s.pop(x, y) == NULL && temp[x - 1][y] != 0 && temp[x][y - 1] != 0 &&
  207. temp[x][y + 1] != 0 && temp[x + 1][y] != 0) {
  208. temp[0][1] = 7;
  209. if (temp[1][1] != 1) temp[1][1] = 2;
  210. return;
  211. }
  212. }
  213. }
  214. char getch() {
  215. char ch;
  216. //保存原有终端属性和新设置的终端属性
  217. static struct termios oldt, newt;
  218. //获得终端原有属性并保存在结构体oldt
  219. tcgetattr(STDIN_FILENO, &oldt);
  220. //设置新的终端属性
  221. newt = oldt;
  222. newt.c_lflag &= ~(ICANON);
  223. tcsetattr(STDIN_FILENO, TCSANOW, &newt);
  224. //取消回显
  225. system("stty -echo");
  226. ch = getchar();
  227. system("stty echo");
  228. //让终端恢复为原有的属性
  229. tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
  230. return ch;
  231. }
  232. void move() {
  233. int x = 1, y = 1; //出发点
  234. //一直游戏,直到走出
  235. while (1) {
  236. //判断输入的命令
  237. switch (getch()) {
  238. case 's':
  239. if (maze[x + 1][y] == 0) {
  240. maze[x][y] = 0;
  241. x = x + 1;
  242. maze[x][y] = 7; //当前位置
  243. printMaze();
  244. if ((x == MAX_X - 1) && (y == MAX_Y - 2)) {
  245. cout << "\n\n 成功走出" << endl;
  246. return;
  247. }
  248. }
  249. break;
  250. case 'd':
  251. if (maze[x][y + 1] == 0) {
  252. if (maze[x][y + 1] == 0) {
  253. maze[x][y] = 0;
  254. y = y + 1;
  255. maze[x][y] = 7;
  256. printMaze();
  257. if ((x == MAX_X - 1) && (y == MAX_Y - 2)) {
  258. cout << "\n\n 成功走出" << endl;
  259. return;
  260. }
  261. }
  262. }
  263. break;
  264. case 'w':
  265. if (maze[x - 1][y] == 0) {
  266. maze[x][y] = 0;
  267. x = x - 1;
  268. maze[x][y] = 7;
  269. printMaze();
  270. if ((x == MAX_X - 1) && (y == MAX_Y - 2)) {
  271. cout << "\n\n 成功走出" << endl;
  272. return;
  273. }
  274. }
  275. break;
  276. case 'a':
  277. if (maze[x][y - 1] == 0) {
  278. maze[x][y] = 0;
  279. y = y - 1;
  280. maze[x][y] = 7;
  281. printMaze();
  282. if ((x == MAX_X - 1) && (y == MAX_Y - 2)) {
  283. cout << "\n\n 成功走出" << endl;
  284. return;
  285. }
  286. }
  287. break;
  288. }
  289. }
  290. }
  291. void autoMove(stack_of_maze& s) {
  292. int x = 1, y = 1; //出发点
  293. while (1) {
  294. maze[x][y] = 2;
  295. //向下
  296. if (maze[x + 1][y] == 0) {
  297. s.push(x, y, 'D');
  298. maze[x][y] = 3; //在当前位置做一个向下的标志
  299. x = x + 1;
  300. maze[x][y] = 7; //当前位置
  301. if (slow) printMaze();
  302. if ((x == MAX_X - 1) && (y == MAX_Y - 2)) {
  303. s.push(x, y, '*');
  304. cout << "\n\n 成功走出" << endl;
  305. return;
  306. } else
  307. continue;
  308. }
  309. //向右
  310. if (maze[x][y + 1] == 0) {
  311. s.push(x, y, 'R');
  312. maze[x][y] = 4; //在当前位置做一个向右的标志
  313. y = y + 1;
  314. maze[x][y] = 7;
  315. if (slow) printMaze();
  316. if ((x == MAX_X - 1) && (y == MAX_Y - 2)) {
  317. s.push(x, y, '*');
  318. cout << "\n\n 成功走出" << endl;
  319. return;
  320. } else
  321. continue;
  322. }
  323. //向上
  324. if (maze[x - 1][y] == 0) {
  325. s.push(x, y, 'U');
  326. maze[x][y] = 6; //在当前位置做一个向上的标志
  327. x = x - 1;
  328. maze[x][y] = 7;
  329. if (slow) printMaze();
  330. if ((x == MAX_X - 1) && (y == MAX_Y - 2)) {
  331. s.push(x, y, '*');
  332. cout << "\n\n 成功走出" << endl;
  333. return;
  334. } else
  335. continue;
  336. }
  337. //向左
  338. if (maze[x][y - 1] == 0) {
  339. s.push(x, y, 'L');
  340. maze[x][y] = 5; //在当前位置做一个向右的标志
  341. y = y - 1;
  342. maze[x][y] = 7;
  343. if (slow) printMaze();
  344. if ((x == MAX_X - 1) && (y == MAX_Y - 2)) {
  345. s.push(x, y, '*');
  346. cout << "\n\n 成功走出" << endl;
  347. return;
  348. } else
  349. continue;
  350. }
  351. //上下左右不通,则回退
  352. if (s.pop(x, y) == NULL && maze[x - 1][y] != 0 && maze[x][y - 1] != 0 &&
  353. maze[x][y + 1] != 0 && maze[x + 1][y] != 0) {
  354. cout << "\n\n 没有找到合适的路径" << endl;
  355. maze[0][1] = 7;
  356. if (maze[1][1] != 1) maze[1][1] = 2;
  357. return;
  358. }
  359. }
  360. }
  361. void menu();
  362. void gamestart() {
  363. //初始化地图
  364. flag = false;
  365. while (!flag) {
  366. stack_of_maze stack;
  367. //创建地图
  368. createMaze();
  369. //检查地图是否创建成功
  370. check(stack);
  371. //模仿进度条
  372. system("clear");
  373. cout << "\t* loading. *" << endl;
  374. system("clear");
  375. cout << "\t* loading.. *" << endl;
  376. system("clear");
  377. cout << "\t* loading... *" << endl;
  378. }
  379. //输出当前迷宫的初始状态
  380. printMaze();
  381. cout << "\n\n 输入enter键继续" << endl;
  382. getchar();
  383. //自行游戏
  384. if (!autogame) {
  385. move();
  386. cout << "\n\n 输入enter键继续" << endl;
  387. getchar();
  388. menu();
  389. }
  390. //自动游戏
  391. else {
  392. stack_of_maze stack1;
  393. autoMove(stack1); //行走中……
  394. }
  395. printMaze(); //输出迷宫的最终状态
  396. cout << "\n\n 输入enter键继续" << endl;
  397. getchar();
  398. menu();
  399. }
  400. void menu() {
  401. system("clear");
  402. int num;
  403. cout << "\t****************************************" << endl;
  404. cout << "\t* *" << endl;
  405. cout << "\t* 1.查看路径 *" << endl;
  406. cout << "\t* *" << endl;
  407. cout << "\t* 2.自动进行 *" << endl;
  408. cout << "\t* *" << endl;
  409. cout << "\t* 3.自行游戏 *" << endl;
  410. cout << "\t* *" << endl;
  411. cout << "\t* 4.退出游戏 *" << endl;
  412. cout << "\t* *" << endl;
  413. cout << "\t****************************************" << endl;
  414. slow = false;
  415. //选择模式
  416. switch (getch()) {
  417. case '1':
  418. autogame = true;
  419. gamestart();
  420. break;
  421. case '2':
  422. autogame = true;
  423. slow = true;
  424. gamestart();
  425. break;
  426. case '3':
  427. autogame = false;
  428. gamestart();
  429. break;
  430. case '4':
  431. exit(1);
  432. break;
  433. default:
  434. cout << "\n\n 错误操作,输入enter返回!" << endl;
  435. getchar();
  436. menu();
  437. }
  438. getchar();
  439. }
  440. int main(int argc, char** argv) {
  441. menu();
  442. return 0;
  443. }