C++实现迷宫小游戏

时间:2022-06-01 18:12:39

介绍

本程序是根据广度优先遍历算法的思想设计的一款迷宫游戏,游戏设计了两种模式一种自动游戏模式,一种手动模式。因为项目在 Linux 开发,需要在 Windows 开发的,请查看源代码中需要修改地方的备注。

截图

C++实现迷宫小游戏

C++实现迷宫小游戏

C++实现迷宫小游戏

代码

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

原文链接:https://blog.csdn.net/weixin_43675051/article/details/85262289