|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 就是要努力呀 于 2020-5-21 16:13 编辑
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <time.h>
- void menu(int *map_x, int *map_y); //主菜单
- char **make_map(int map_x, int map_y); //生成地图
- char **make_mine_map(int mine_x, int mine_y, int mine_num); //生成地雷地图
- void print_all_map(char **map, int map_x, int map_y, char **mine_map, int mine_x, int mine_y); //打印地图
- int begin_game(char **map, int map_x, int map_y, char **mine_map, int mine_x, int mine_y, int mine_num); //开始游戏
- int open_place(char **map, int map_x, int map_y, char **mine_map, int mine_x, int mine_y, int x, int y); //打开玩家选择的位置
- void expand(char **map, int map_x, int map_y, char **mine_map, int mine_x, int mine_y, int x, int y); //通过递归方式实现扫雷的扩展功能,游戏最重要的部分
- int check_mine(char **mine_map, int mine_x, int mine_y, int x, int y); //检测一个位置周围8格以内的地雷数
- int check_win(char **map, int mine_x, int mine_y, int mine_num); //检测是否赢得游戏
- void win(char **map, int map_x, int map_y); //赢得游戏,打印所有地雷所在位置
- void win(char **map, int map_x, int map_y)
- {
- int i, j;
- for(i = 0; i < map_x; i++)
- {
- for(j = 0; j < map_y; j++)
- {
- if(map[i][j] == '+')
- {
- map[i][j] = '@';
- }
- printf("%c ", map[i][j]);
- }
- putchar('\n');
- }
- }
- int check_win(char **map, int mine_x, int mine_y, int mine_num)
- {
- int i, j;
- int num = 0;
- for(i = 1; i < mine_x; i++)
- {
- for(j = 1; j < mine_y; j++)
- {
- if(map[i][j] == '+')
- {
- num++;
- }
- }
- }
- if(num == mine_num)
- {
- printf("恭喜你赢了\n");
- return 1;
- }
- return 0;
- }
- int check_mine(char **mine_map, int mine_x, int mine_y, int x, int y)
- {
- int num = 0;
- //判断该位置周围8格的地雷数
- if(x - 1 > 0 && mine_map[x - 1][y] == '@')
- {
- num++;
- }
- if(x + 1 < mine_x && mine_map[x + 1][y] == '@')
- {
- num++;
- }
- if(y - 1 > 0 && mine_map[x][y - 1] == '@')
- {
- num++;
- }
- if(y + 1 < mine_y && mine_map[x][y + 1] == '@')
- {
- num++;
- }
- if(x - 1 > 0 && y - 1 > 0 && mine_map[x - 1][y - 1] == '@')
- {
- num++;
- }
- if(x - 1 > 0 && y + 1 < mine_y && mine_map[x - 1][y + 1] == '@')
- {
- num++;
- }
- if(x + 1 < mine_x && y + 1 < mine_x && mine_map[x + 1][y + 1] == '@')
- {
- num++;
- }
- if(x + 1 < mine_x && y - 1 > 0 && mine_map[x + 1][y - 1] == '@')
- {
- num++;
- }
- return num;
- }
- void expand(char **map, int map_x, int map_y, char **mine_map, int mine_x, int mine_y, int x, int y)
- {
- int num;
-
- if(!(num = check_mine(mine_map, mine_x, mine_y, x, y))) //判断这个位置的周围8格是否有地雷,如果有将该位置设置为地雷数,并停止对该位置后续的展开
- {
- map[x][y] = ' ';
-
- //向该位置的8个方向进行展开
- if(x - 1 > 0 && map[x - 1][y] == '+')
- {
- expand(map, map_x, map_y, mine_map, mine_x, mine_y, x - 1, y);
- }
- if(x + 1 < mine_x && map[x + 1][y] == '+')
- {
- expand(map, map_x, map_y, mine_map, mine_x, mine_y, x + 1, y);
- }
- if(y - 1 > 0 && map[x][y - 1] == '+')
- {
- expand(map, map_x, map_y, mine_map, mine_x, mine_y, x, y - 1);
- }
- if(y + 1 < mine_y && map[x][y + 1] == '+')
- {
- expand(map, map_x, map_y, mine_map, mine_x, mine_y, x, y + 1);
- }
-
- if(x - 1 > 0 && y - 1 > 0 && map[x - 1][y - 1] == '+')
- {
- expand(map, map_x, map_y, mine_map, mine_x, mine_y, x - 1, y - 1);
- }
- if(x - 1 > 0 && y + 1 < mine_y && map[x - 1][y + 1] == '+')
- {
- expand(map, map_x, map_y, mine_map, mine_x, mine_y, x - 1, y + 1);
- }
-
- if(x + 1 < mine_x && y + 1 < mine_y && map[x + 1][y + 1] == '+')
- {
- expand(map, map_x, map_y, mine_map, mine_x, mine_y, x + 1, y + 1);
- }
- if(x + 1 < mine_x && y - 1 > 0 && map[x + 1][y - 1] == '+')
- {
- expand(map, map_x, map_y, mine_map, mine_x, mine_y, x + 1, y - 1);
- }
- }
- else
- {
- map[x][y] = num + 48;
- }
- }
- int open_place(char **map, int map_x, int map_y, char **mine_map, int mine_x, int mine_y, int x, int y)
- {
- if(mine_map[x][y] == '@')
- {
- printf("游戏结束!\n");
- return 0;
- }
- else if(mine_map[x][y] == '+')
- {
- expand(map, map_x, map_y, mine_map, mine_x, mine_y, x, y); //如果玩家选中的位置没有踩雷,就需要展它周围的空位置
- return 1;
- }
- return 1;
- }
- int begin_game(char **map, int map_x, int map_y, char **mine_map, int mine_x, int mine_y, int mine_num)
- {
- char x = ' ', y = ' ';
- char choose;
- static int num = 0;
- do
- {
- printf("总地雷数:%d 当前地雷数:%d\n", mine_num, mine_num - num);
- printf("请输入行和列(qq退出游戏):");
- scanf("%c %c", &x, &y);
- getchar();
- if(x == 'q' && y == 'q')
- {
- exit(0);
- }
- }
- while(x < '0' || y < '0' || x > (char)(map_x - 2 + 48) || y > (char)(map_y - 2 + 48));
- do
- {
- printf("1.打开:2.标记:3.取消标记:4.重新选择\n");
- printf("请选择你要执行的命令:");
- choose = getchar();
- getchar();
- }
- while(choose != '1' && choose != '2' && choose != '3');
- switch(choose)
- {
- case '1':
- {
- return open_place(map, map_x, map_y, mine_map, mine_x, mine_y, (int)x - 48, (int)y - 48); //因为我们的x和y设置的是字符型,要将他强制转换成int型,方便open_place函数定位
- }
- case '2':
- {
- num++;
- map[(int)x - 48][(int)y - 48] = '^';
- break;
- }
- case '3':
- {
- num--;
- map[(int)x - 48][(int)y - 48] = '+';
- break;
- }
- case '4':
- {
- break;
- }
- }
- }
- void print_all_map(char **map, int map_x, int map_y, char **mine_map, int mine_x, int mine_y)
- {
- int i, j;
- for(i = 0; i < map_x; i++)
- {
- for(j = 0; j < map_y; j++)
- {
- printf("%c ", map[i][j]);
- }
- putchar('\n');
- }
-
- /*for(i = 0; i < mine_x; i++)
- {
- for(j = 0; j < mine_y; j++)
- {
- printf("%c ", mine_map[i][j]);
- }
- putchar('\n');
- }*/
- }
- char **make_mine_map(int mine_x, int mine_y, int mine_num)
- {
- char **mine_map;
- int i, j;
- int x, y;
- int num = 0;
- mine_map = (char **)malloc(sizeof(char *) * mine_x);
- for(i = 0; i < mine_x; i++)
- {
- mine_map[i] = (char *)malloc(sizeof(char) * mine_y);
- }
- srand(time(NULL));
- for(i = 0; i < mine_x; i++)
- {
- for(j = 0; j < mine_y; j++)
- {
- mine_map[i][j] = '+';
- }
- }
- while(num < mine_num)
- {
- do
- {
- x = rand()%(mine_x - 1) + 1;
- y = rand()%(mine_y - 1) + 1;
- }
- while(mine_map[x][y] != '+');
- mine_map[x][y] = '@';
- num++;
- }
- return mine_map;
- }
- char **make_map(int map_x, int map_y)
- {
- char **map;
- int i, j, k = 1;
- map = (char **)malloc(sizeof(char *) * map_x);
- for(i = 0; i < map_x; i++)
- {
- map[i] = (char *)malloc(sizeof(char) * map_y);
- }
- for(i = 0; i < map_x - 1; i++)
- {
- map[i][0] = i + 48;
- }
- for(j = 0; j < map_y - 1; j++)
- {
- map[0][j] = j + 48;
- }
- for(i = 1; i < map_x - 1; i++)
- {
- for(j = 1; j < map_y - 1; j++)
- {
- map[i][j] = '+';
- }
- }
-
- return map;
- }
- void menu(int *map_x, int *map_y)
- {
- char choose;
- do
- {
- printf("********************1.开始游戏*******************\n");
- printf("********************2.退出游戏*******************\n");
- printf("请选择:");
- choose = getchar();
- getchar();
- }
- while(choose != '1' && choose != '2');
- if(choose == '1')
- {
- do
- {
- printf("1.初级:2.中级:3.高级:4.自定义");
- printf("请选择:");
- choose = getchar();
- getchar();
- }
- while(choose != '1' && choose != '2' && choose != '3' && choose != '4');
- switch(choose)
- {
- case '1':
- {
- *map_x = 12;
- *map_y = 12;
- break;
- }
- case '2':
- {
- *map_x = 22;
- *map_y = 22;
- break;
- }
- case '3':
- {
- *map_x = 42;
- *map_y = 42;
- break;
- }
- case '4':
- {
- do
- {
- printf("请输入行:");
- scanf("%d", map_x);
- getchar();
- }
- while(*map_x <= 0 || *map_x > 100);
- do
- {
- printf("请输入列:");
- scanf("%d", map_y);
- getchar();
- }
- while(*map_y <= 0 || *map_y > 100);
- *map_x += 2;
- *map_y += 2;
- }
- }
- }
- else exit(0);
- }
- int main(void)
- {
- int map_x, map_y;
- menu(&map_x, &map_y);
- char **map; //设置一个二级指针来接受返回的动态二维数组
- map = make_map(map_x, map_y); //为了使得行列可以自定义,用动态申请二维数组的方法
- char **mine_map; //同样的方法设置一个地雷地图的二级指针
- int mine_x = map_x - 1; //设置地雷地图的行列
- int mine_y = map_y - 1;
- int mine_num = mine_x + mine_y - 4; //设置地雷数
- mine_map = make_mine_map(mine_x, mine_y, mine_num); //动态申请一个二维数组
- do
- {
- print_all_map(map, map_x, map_y, mine_map, mine_x, mine_y); //打印地图
- if(check_win(map, mine_x, mine_y, mine_num)) //玩家每走一步就检测是否赢得比赛
- {
- win(map, map_x, map_y);
- break;
- }
- }
- while(begin_game(map, map_x, map_y, mine_map, mine_x, mine_y, mine_num)); //begin_game该游戏的主要函数
- return 0;
- }
复制代码 |
评分
-
查看全部评分
|