1 #include
2 #include
3 #include
4 #include
5 #include
6
7 //地图边长L,包括迷宫主体20,外侧的包围的墙体2,最外侧包围路径2(之后会解释)8 //可根据需要修改,有上限
9 #define L 24
10
11 #define WALL 0 //墙
12 #define ROUTE 1 //路径
13 #define PLAYER 2//玩家
14
15 //控制迷宫的复杂度,数值越大复杂度越低,最小值为016 //默认为简单难度,可根据需要在degree函数里调整不同难度的复杂度
17 int Rank = 6;18
19 void menu(); //主菜单界面
20 void start(); //开始游戏
21 void degree(); //游戏难度
22 void explain();//游戏说明
23 int init(int** Maze); //初始化迷宫
24 void print(int** Maze);//画迷宫
25 void CreateMaze(int **maze, int x, int y); //创建迷宫
26 void move(int** Maze, char t, int *x, int *y);//移动角色
27
28 intmain() {29 menu();30 return 0;31 }32
33 void menu() { //主菜单
34 while(1) {35 system("cls"); //清屏
36 chart;37 printf("*******(走迷宫)*******");38 printf("\n======================\n");39 printf("\n|| 1. 开始 游戏 ||\n");40 printf("\n|| 2. 游戏 说明 ||\n");41 printf("\n|| 3. 游戏 难度 ||\n");42 printf("\n|| 4. 关闭 游戏 ||\n");43 printf("======================\n");44 t=getch(); //不回显函数
45 switch(t) {46 case '1':47 start();48 break; //开始一局游戏
49 case '2':50 explain();51 break; //进入游戏说明界面
52 case '3':53 degree();54 break; //调整游戏难度
55 case '4':56 printf("\n欢迎下次再玩,再见( ̄︶ ̄)↗");57 Sleep(1500);58 exit(0);59 break; //结束程序
60 default:61 break;62 }63 }64 }65
66 void CreateMaze(int **maze, int x, int y) {//构建迷宫
67 maze[x][y] =ROUTE;68 //确保四个方向随机,而不再是固定的上下左右这种排列
69 int direction[4][2] = { { 1,0 },{ -1,0 },{ 0,-1 },{ 0,1} };70 inti, j;71 for (i = 0; i < 4; i++) {72 int r = rand() % 4;73 int temp = direction[0][0];74 direction[0][0] = direction[r][0];75 direction[r][0] =temp;76 temp = direction[0][1];77 direction[0][1] = direction[r][1];78 direction[r][1] =temp;79 }80 //向四个方向开挖
81 for (i = 0; i < 4; i++) {82 int dx =x;83 int dy =y;84 //控制挖的距离,由Rank来调整大小
85 int range = 1 + (Rank == 0 ? 0 : rand() %Rank);86 while (range > 0) {87 //计算出将要访问到的坐标
88 dx += direction[i][0];89 dy += direction[i][1];90 //排除掉回头路
91 if (maze[dx][dy] ==ROUTE) {92 break;93 }94 //判断是否挖穿路径
95 int count = 0, k;96 for (j = dx - 1; j < dx + 2; j++) {97 for (k = dy - 1; k < dy + 2; k++) {98 //abs(j - dx) + abs(k - dy) == 1 确保只判断九宫格的四个特定位置
99 if (abs(j - dx) + abs(k - dy) == 1 && maze[j][k] ==ROUTE) {100 count++;101 }102 }103 }104 //count大于1表明墙体会被挖穿,停止
105 if (count > 1)106 break;107 //确保不会挖穿时,前进
108 range -= 1;109 maze[dx][dy] =ROUTE;110 }111 //没有挖穿危险,以此为节点递归
112 if (range <= 0) {113 CreateMaze(maze, dx, dy);114 }115 }116 }117
118 int init(int** Maze) {//初始化迷宫
119 inti;120 //最外围层设为路径的原因,为了防止挖路时挖出边界,同时为了保护迷宫主体外的一圈墙体被挖穿
121 for (i = 0; i < L; i++) {122 Maze[i][0] =ROUTE;123 Maze[0][i] =ROUTE;124 Maze[i][L - 1] =ROUTE;125 Maze[L - 1][i] =ROUTE;126 }127 //创造迷宫,(2,2)为起点
128 CreateMaze(Maze, 2, 2);129 //画迷宫的入口和出口,给出玩家初始位置
130 Maze[2][1] =PLAYER;131 //由于算法随机性,出口有一定概率不在(L-3,L-2)处,此时需要寻找出口
132 for (i = L - 3; i >= 0; i--) {133 if (Maze[i][L - 3] ==ROUTE) {134 Maze[i][L - 2] =ROUTE;135 //返回出口所在的纵坐标
136 returni;137 }138 }139 }140
141 void print(int** Maze) {//画迷宫
142 inti, j;143 for (i = 0; i < L; i++) {144 for (j = 0; j < L; j++) {145 if (Maze[i][j] ==ROUTE)146 printf(" ");//表示道路
147 else if(Maze[i][j] ==WALL)148 printf("回");//表示墙体
149 else
150 printf("十");//表示玩家
151 }152 printf("\n");153 }154 }155 //将原先的引用int &x,更改为现在的指针指向int *x
156 void move(int** Maze, char t, int *x, int *y) {//移动角色
157 int i = *x, j = *y;//记录原始位置
158 switch(t) {159 case 'w': //向上移动
160 *x -= 1;161 break;162 case 's': //向下移动
163 *x += 1;164 break;165 case 'a': //向左移动
166 *y -= 1;167 break;168 case 'd': //向右移动
169 *y += 1;170 break;171 default:172 break;173 }174 if(*x>=0 && *x=0 && *y
175 Maze[i][j] = 1;176 Maze[*x][*y] = 2;177 } else {//保持位置不变
178 *x =i;179 *y =j;180 }181 }182
183 void start() { //开始一局游戏
184 chart;185 //y,x表示角色横纵坐标, out表示出口的纵坐标
186 int *p, *q;187 int x = 2, y = 1, out = 0, i = 0;188 p = &x;189 q = &y;190 //随机数发生器初始化函数
191 srand((unsigned)time(NULL));192 //申请数组空间
193 int **Maze = (int**)malloc(L * sizeof(int *));194 for (i = 0; i < L; i++) {195 Maze[i] = (int*)calloc(L, sizeof(int));196 }197 //得到出口纵坐标
198 out =init(Maze);199 //游戏开始
200 system("cls");201 print(Maze);202 while(t =getch()) {203 if(t == 27) //如果输入为ESC键,结束游戏回到主菜单
204 break;205 system("cls");//清屏
206 move(Maze, t, p, q);//根据输入t进行移动
207 print(Maze);//重新绘制迷宫
208 if(x == out && y == L-2) {//已经到出口,游戏结束
209 system("cls");210 printf("=============\n");211 printf("游 戏 胜 利!\n");212 printf("=============\n");213 printf("即将后返回主菜单……");214 Sleep(1500);//执行挂起一段时间,暂停1.5秒后打印
215 break;216 }217 }218 //一局游戏结束,释放内存
219 for (i = 0; i < L; i++) free(Maze[i]);220 free(Maze);221 }222
223 void explain() { //操作说明
224 while(1) {225 chart;226 system("cls");227 printf("=================================================\n");228 printf("感谢您体验本游戏,游戏的操作如下:\n");229 printf("\n1.将输入法调整为英文(小写)\n");230 printf("\n2.通过w,s,a,d四个键控制角色上下左右移动\n");231 printf("\n3.在任意界面均可按“ESC”键返回到主菜单\n");232 printf("\n胜利条件:移动角色到出口处,加油各位( ̄▽ ̄)\"!\n");233 printf("=================================================\n");234 t=getch(); //不回显函数
235 switch(t) {236 //ESC键的ASCII码值
237 case 27:238 //返回主菜单
239 menu();240 break;241 default:242 break;243 }244 }245 }246
247 void degree() { //调整游戏难度
248 while(1) {249 chart;250 system("cls");251 printf("=======================\n");252 printf("输入1,2,3进行难度调整:\n");253 printf("\n|| 1.简 单 ||\n");254 printf("\n|| 2.中 等 ||\n");255 printf("\n|| 3.困 难 ||\n");256 printf("=======================\n");257 t=getch(); //不回显函数
258 switch(t) {259 case '1':260 Rank = 6;261 printf("\n当前难度:简单,即将返回主菜单……");262 Sleep(1500);263 menu();//返回主菜单
264 break;265 case '2':266 Rank = 3;267 printf("\n当前难度:中等,即将返回主菜单……");268 Sleep(1500);269 menu();//返回主菜单
270 break;271 case '3':272 Rank = 0;273 printf("\n当前难度:困难,即将返回主菜单……");274 Sleep(1500);275 menu();//返回主菜单
276 break;277 case 27:278 menu();279 break;280 default:281 break;282 }283 }284 }