设计要求:
1.第一次不会被雷炸死。
2.点开如果不是雷显示周围雷的个数。
3.周围没有雷,则展开一片。
实现思路:
1.首先需要设计两个雷阵,一个是设计者用来存储布置雷场数据的雷阵,另一个是玩家用来扫雷的雷阵
2.布雷:我们需要设计一个A*A(A代表雷阵大小,根据设计者需要自行设计)的雷阵,布有X(X代表雷的个数,根据设计者与玩家需求自己设计)个雷,那我们可以用二维数组来实现雷阵,用字符‘1’表示有雷,字符‘0’表示没有雷(如果使用数字0和1表示是否有雷,那么将会产生这个数字代表的是雷还是雷的个数的歧义,所以不采用这种方式),所以将雷阵初始化为字符‘0’,进而用%c来打印。还有一个问题就是我们是否就要将雷阵设计成A*A的呢,答案是否定的,如果你在计算一个坐标周围雷的个数,就要遍历周围的A-1个坐标,如果设计成A*A的雷阵,那么最外围的坐标周围是没有8个位置的,所以我们应将雷阵设计成(A+2)*(A+2),但是布雷与扫雷仅在中间的A*A中进行,这样这个问题就得以解决了。
3.扫雷:与布雷一样,也要将雷阵设计成(A+2)*(A+2);因为此雷阵为玩家雷阵,为了增加神秘性,应将其初始化为字符‘ * ’,或是其他字符。
4.判断输赢:当雷阵中的字符‘ * ’还有10个或者排雷次数达到A*A-X次即获得胜利。
具体函数实现:
1.进入菜单:选择是否进行游戏
void mune() { printf("****************************\n"); printf("***** 1. play
*****\n"); printf("***** 0. exit *****\n");
printf("****************************\n"); }
2.进入游戏,初始化两个雷阵.
void InitBoard(char arr[ROWS][COLS], int rows, int cols,char set) //初始化雷阵 {
int i = 0; int j = 0; for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) {
arr[i][j] = set; } } }
3.在雷阵中布置雷
void SetMine(char mine1[ROWS][COLS], int row, int col) //设置雷阵分布 { int count =
EASY_COUNT; while (count) { int x = rand()%row+1; int y = rand()%col+1; if
(mine1[x][y] == '0') { mine1[x][y] = '1'; count--; } } }
4.打印雷阵
void DisplayBoard(char mine1[ROWS][COLS], int row, int col) //打印雷阵 { int i =
0; int j = 0; for (i = 0; i <= row; i++) { printf("%d ", i); } printf("\n");
for (i = 1; i <= row; i++) { printf("%d ", i); for (j = 1; j <= col; j++) {
printf("%c ", mine1[i][j]); } printf("\n"); } }
5.如果该坐标不是雷,统计周围雷的个数
int GetMineCount(char mine1[ROWS][COLS], int x, int y) //统计雷的个数 { return
mine1[x - 1][y] + mine1[x - 1][y - 1] + mine1[x][y - 1] + mine1[x + 1][y - 1] +
mine1[x + 1][y] + mine1[x + 1][y + 1] + mine1[x][y + 1] + mine1[x - 1][y + 1] -
8 * '0'; }
6.避免第一次被雷炸死
void MoveMine(char mine1[ROWS][COLS], char mine2[ROWS][COLS], int row, int
col)//避免第一次被雷炸死 { int x = 0; int y = 0; char ch = 0; int count = 0; int ret =
1; printf("输入坐标扫雷:>"); while (1) { scanf("%d%d", &x, &y); if (x >= 1 && x <=
row&&y >= 1 && y <= col) { if (mine1[x][y] == '1') { mine1[x][y] = '0'; char ch
= GetMineCount(mine1,x, y); mine2[x][y] = ch + '0'; OpenMine(mine1,mine2, x,
y); while (ret) { int x = rand() % row + 1; int y = rand() % col + 1; if
(mine1[x][y] == '0') { mine1[x][y] = '1'; ret--; break; } } break; } if
(mine1[x][y] == '0') { char ch = GetMineCount(mine1, x, y); mine2[x][y] = ch +
'0'; OpenMine(mine1,mine2, x, y); break; } } else { printf("坐标错误,请重新输入!\n"); }
} }
7.坐标周围没有雷,展开
void OpenMine(char mine1[ROWS][COLS], char mine2[ROWS][COLS], int x, int
y)//坐标周围没雷,可以实现展开 { if (mine1[x - 1][y - 1] == '0') { mine2[x - 1][y - 1] =
GetMineCount(mine1,x - 1, y - 1) + '0';//显示该坐标周围雷数 } if (mine1[x - 1][y] ==
'0') { mine2[x - 1][y] = GetMineCount(mine1, x - 1, y) + '0';//显示该坐标周围雷数 } if
(mine1[x - 1][y + 1] == '0') { mine2[x - 1][y + 1] = GetMineCount(mine1, x - 1,
y + 1) + '0';//显示该坐标周围雷数 } if (mine1[x][y - 1] == '0') { mine2[x][y - 1] =
GetMineCount(mine1, x, y - 1) + '0';//显示该坐标周围雷数 } if (mine1[x][y + 1] == '0') {
mine2[x][y + 1] = GetMineCount(mine1, x, y + 1) + '0';//显示该坐标周围雷数 } if (mine1[x
+ 1][y - 1] == '0') { mine2[x + 1][y - 1] = GetMineCount(mine1, x + 1, y - 1) +
'0';//显示该坐标周围雷数 } if (mine1[x + 1][y] == '0') { mine2[x + 1][y] =
GetMineCount(mine1, x + 1, y) + '0';//显示该坐标周围雷数 } if (mine1[x + 1][y + 1] ==
'0') { mine2[x + 1][y + 1] = GetMineCount(mine1, x + 1, y + 1) +
'0';//显示该坐标周围雷数 } }
8.扫雷以及判断输赢
void FindMine(char mine1[ROWS][COLS], char mine2[ROWS][COLS], int row, int
col) //扫雷 { int x = 0; int y = 0; int win = 0; while (win<row*col-EASY_COUNT) {
printf("请输入要排查的坐标:>"); scanf("%d%d", &x, &y); if (x >= 1 && x <= row&&y >= 1 &&
y <= col) { if (mine1[x][y] == '1') { printf("很遗憾,你被炸死了!\n");
DisplayBoard(mine1, row, col); break; } else { int count = GetMineCount(mine1,
x, y); mine2[x][y] = count + '0'; DisplayBoard(mine2, row, col); } } else {
printf("坐标非法,请重新输入!\n"); } } if (win == row*col - EASY_COUNT) {
printf("恭喜你,排雷成功!\n"); } }
附上源码:
game.h(头文件)
#include<stdio.h> #include<stdlib.h> #include<time.h> #define EASY_COUNT 10
//设置雷的个数 #define ROW 9 #define COL 9 #define ROWS ROW+2 #define COLS COL+2 void
InitBoard(char arr[ROWS][COLS], int rows, int cols, char set); //初始化雷阵 void
SetMine(char mine1[ROWS][COLS], int row, int col);//设置雷的及分布 void
DisplayBoard(char mine1[ROWS][COLS], int row, int col);//打印雷阵 void
MoveMine(char mine1[ROWS][COLS], char mine2[ROWS][COLS], int row, int
col);//避免第一次被雷炸死 void OpenMine(char mine1[ROWS][COLS], char mine2[ROWS][COLS],
int row, int col);//坐标周围没雷,实现展开 void FindMine(char mine1[ROWS][COLS], char
mine2[ROWS][COLS], int row, int col);//扫雷
game.c(函数实现)
#define _CRT_SECURE_NO_WARNINGS 1 #include"game.h" void InitBoard(char
arr[ROWS][COLS], int rows, int cols,char set) //初始化雷阵 { int i = 0; int j = 0;
for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) { arr[i][j] = set; } }
} void SetMine(char mine1[ROWS][COLS], int row, int col) //设置雷阵分布 { int count =
EASY_COUNT; while (count) { int x = rand()%row+1; int y = rand()%col+1; if
(mine1[x][y] == '0') { mine1[x][y] = '1'; count--; } } } void DisplayBoard(char
mine1[ROWS][COLS], int row, int col) //打印雷阵 { int i = 0; int j = 0; for (i = 0;
i <= row; i++) { printf("%d ", i); } printf("\n"); for (i = 1; i <= row; i++) {
printf("%d ", i); for (j = 1; j <= col; j++) { printf("%c ", mine1[i][j]); }
printf("\n"); } } int GetMineCount(char mine1[ROWS][COLS], int x, int y)
//统计雷的个数 { return mine1[x - 1][y] + mine1[x - 1][y - 1] + mine1[x][y - 1] +
mine1[x + 1][y - 1] + mine1[x + 1][y] + mine1[x + 1][y + 1] + mine1[x][y + 1] +
mine1[x - 1][y + 1] - 8 * '0'; } void MoveMine(char mine1[ROWS][COLS], char
mine2[ROWS][COLS], int row, int col)//避免第一次被雷炸死 { int x = 0; int y = 0; char ch
= 0; int count = 0; int ret = 1; printf("输入坐标扫雷:>"); while (1) { scanf("%d%d",
&x, &y); if (x >= 1 && x <= row&&y >= 1 && y <= col) { if (mine1[x][y] == '1')
{ mine1[x][y] = '0'; char ch = GetMineCount(mine1,x, y); mine2[x][y] = ch +
'0'; OpenMine(mine1,mine2, x, y); while (ret) { int x = rand() % row + 1; int y
= rand() % col + 1; if (mine1[x][y] == '0') { mine1[x][y] = '1'; ret--; break;
} } break; } if (mine1[x][y] == '0') { char ch = GetMineCount(mine1, x, y);
mine2[x][y] = ch + '0'; OpenMine(mine1,mine2, x, y); break; } } else {
printf("坐标错误,请重新输入!\n"); } } } void OpenMine(char mine1[ROWS][COLS], char
mine2[ROWS][COLS], int x, int y)//坐标周围没雷,可以实现展开 { if (mine1[x - 1][y - 1] ==
'0') { mine2[x - 1][y - 1] = GetMineCount(mine1,x - 1, y - 1) + '0';//显示该坐标周围雷数
} if (mine1[x - 1][y] == '0') { mine2[x - 1][y] = GetMineCount(mine1, x - 1, y)
+ '0';//显示该坐标周围雷数 } if (mine1[x - 1][y + 1] == '0') { mine2[x - 1][y + 1] =
GetMineCount(mine1, x - 1, y + 1) + '0';//显示该坐标周围雷数 } if (mine1[x][y - 1] ==
'0') { mine2[x][y - 1] = GetMineCount(mine1, x, y - 1) + '0';//显示该坐标周围雷数 } if
(mine1[x][y + 1] == '0') { mine2[x][y + 1] = GetMineCount(mine1, x, y + 1) +
'0';//显示该坐标周围雷数 } if (mine1[x + 1][y - 1] == '0') { mine2[x + 1][y - 1] =
GetMineCount(mine1, x + 1, y - 1) + '0';//显示该坐标周围雷数 } if (mine1[x + 1][y] ==
'0') { mine2[x + 1][y] = GetMineCount(mine1, x + 1, y) + '0';//显示该坐标周围雷数 } if
(mine1[x + 1][y + 1] == '0') { mine2[x + 1][y + 1] = GetMineCount(mine1, x + 1,
y + 1) + '0';//显示该坐标周围雷数 } } void FindMine(char mine1[ROWS][COLS], char
mine2[ROWS][COLS], int row, int col) //扫雷 { int x = 0; int y = 0; int win = 0;
while (win<row*col-EASY_COUNT) { printf("请输入要排查的坐标:>"); scanf("%d%d", &x, &y);
if (x >= 1 && x <= row&&y >= 1 && y <= col) { if (mine1[x][y] == '1') {
printf("很遗憾,你被炸死了!\n"); DisplayBoard(mine1, row, col); break; } else { int
count = GetMineCount(mine1, x, y); mine2[x][y] = count + '0';
DisplayBoard(mine2, row, col); } } else { printf("坐标非法,请重新输入!\n"); } } if (win
== row*col - EASY_COUNT) { printf("恭喜你,排雷成功!\n"); } }
test.c(测试)
#define _CRT_SECURE_NO_WARNINGS 1 #include"game.h" void mune() {
printf("****************************\n"); printf("***** 1. play *****\n");
printf("***** 0. exit *****\n"); printf("****************************\n"); }
void game() { char mine1[ROWS][COLS] = { 0 }; //布雷数组 char mine2[ROWS][COLS] = {
0 }; //展示数组 //初始化 InitBoard(mine1, ROWS, COLS, '0'); //初始化布雷数组 InitBoard(mine2,
ROWS, COLS, '*'); //初始化展示数组 //1.设置雷 SetMine(mine1, ROW, COL);//设置雷阵分布
//DisplayBoard(mine1, ROW, COL);//打印布雷数组 DisplayBoard(mine2, ROW, COL);//打印展示数组
//2.扫雷 MoveMine(mine1, mine2, ROW, COL);//避免第一次被雷炸死 //DisplayBoard(mine1, ROW,
COL); //打印布雷数组 DisplayBoard(mine2, ROW, COL); //打印展示数组
FindMine(mine1,mine2,ROW,COL);//扫雷 } void test() { int inupt = 0;
srand((unsigned int)time(NULL)); do { mune(); printf("请选择:>"); scanf("%d",
&inupt); switch (inupt) { case 1: game(); break; case 0: printf("退出游戏。\n");
break; default: printf("输入错误,请重新选择。\n"); break; } } while (inupt); } int main()
{ test(); return 0; }
结果展示:
选择是否进入游戏:
进入游戏,开始扫雷
输入坐标,并展示周围雷的个数,并且展开。
扫到雷,游戏失败
总结:再写任何一个程序之前首先要做的就是分析清楚它的逻辑思路,逻辑搞清楚,接下来就是使用语法实现目的,而且需要注意细节上的问题,错了一个细节调试很久都很难发现,还要注意时间和空间上的优化;在写的过程中细心谨慎,注意参数的传递以及函数的调用,还需要注意括号的使用,保证可读性。