游戏介绍:
《扫雷》是一款大众类的益智小游戏,于1992年发行。游戏目标是在最短的时间内根据点击格子出现的数字找出所有非雷格子,同时避免踩雷,踩到一个雷即全盘皆输。
扫雷的规则是在避开地雷的前提下标记所有地雷。
棋盘大小:9x9
雷的数量:默认5个(可以自己调)
程序设计思路:
首先是要利用switch语句完成菜单的选择功能。
游戏棋盘我分为外部和内部棋盘,外部棋盘是玩家游戏过程中可以看见的可以操作的棋盘,还有一个是布置雷区的棋盘,这两个棋盘我都用二维的字符数组来模拟。
然后就是两个棋盘的初始化-->打印-->设置雷区-->玩家操作-->判断输赢或者继续-->打印步骤的依次实现。
这里还要注意一点,玩家在输入坐标的时候以及搜索周围雷的数量的时候,可能会出现边界问题。
为了避免这一情况,我这里采用偏移量法,就是把整个棋盘有用的范围往里面整体移一步,这样row加减1,col加减1都不会越界。
当然你也可以用其他的方法,特判一下也可以。
还有就是实现随机布置雷的功能需要随机生成坐标,也就需要使用随机生成数,随机数的使用我在上篇博客里详细解释了,不懂的小伙伴可以去看看哦。
程序展示:
1.开始界面:
2.操作界面:
3.胜利界面:
代码:
分为三个部分:
1.test.c源文件下:
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include"game.h" void menu() { printf("******************\n"); printf("****1 play********\n"); printf("****2 exit********\n"); printf("******************\n"); } void game() { char Mine[ROWS][COLS] = { 0 }; char show[ROWS][COLS] = { 0 }; //初始化 InitBoard(Mine, ROWS, COLS, '0'); InitBoard(show, ROWS, COLS, '*'); //打印 PrintBoard(show, ROW, COL); //设置雷 SetMine(Mine, ROW, COL); //排雷 FindMine(Mine,show,ROW,COL); } int main() { srand((unsigned int)time(NULL)); int input = 0; do { menu(); scanf("%d", &input); switch (input) { case 1: printf("%d\n", 1); game(); break; case 2: printf("退出游戏\n"); break; default: printf("输入有误\n"); break; } } while (input!=2); return 0; }
2.game.c源文件下:
#define _CRT_SECURE_NO_WARNINGS 1 #include"game.h" //初始化棋盘 void InitBoard(char board[ROWS][COLS], int row, int col, char set) { for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { //printf("%d %d\n", i, j); board[i][j] = set; //printf("%c ", set); } } } //打印棋盘 void PrintBoard(char board[ROWS][COLS], int row, int col) { printf("*****排雷*****\n"); for (int i = 0; i <= col; i++) printf(" %d", i); printf("\n"); for (int i = 1; i <= row; i++) { printf(" %d", i); for (int j = 1; j <= col; j++) { printf(" %c", board[i][j]); } printf("\n"); } printf("*****排雷*****\n"); } //设置雷 void SetMine(char Mine[ROWS][COLS], int row ,int col) { int num = 0; while (num < Easy_conut) { int x = rand() % row + 1; int y = rand() % col + 1; if (Mine[x][y] == '0') { Mine[x][y] = '1'; num++; } } } //计算周围有多少个雷 static int FindAround(char Mine[ROWS][COLS], int x, int y) { int dx[8] = { -1,-1,-1,0,0,1,1,1 }; int dy[8] = { -1,0,1,-1,1,-1,0,1 }; int num = 0; for (int i = 0; i < 8; i++) { int a = x + dx[i]; int b = y + dy[i]; if (Mine[a][b] == '1') { num++; } } //printf("num==%d\n", num); return num; } //连带排雷bfs static void bfsfind(int st[ROWS][COLS], char Mine[ROWS][COLS],char show[ROWS][COLS],int row,int col,int x,int y) { int dx[8] = { -1,-1,-1,0,0,1,1,1 }; int dy[8] = { -1,0,1,-1,1,-1,0,1 }; for (int i = 0; i < 8; i++) { int a = x + dx[i]; int b = y + dy[i]; int k = FindAround(Mine, a, b); if (a>=1&&a<=row&&b>=1&&b<=col&&st[a][b] == 0 && k == 0&&show[a][b]=='*'&&Mine[a][b]!='1') { st[a][b] = 1; show[a][b] = '-'; bfsfind(st, Mine, show, row, col, a, b); } else if (a >= 1 && a <= row && b >= 1 && b <= col && st[a][b] == 0 && k > 0 && show[a][b] == '*'&&Mine[a][b]!='1') { st[a][b] = 1; show[a][b] = k + '0'; } } } //判断是否赢了 static int Iswin(char show[ROWS][COLS], int row, int col,int target) { int num = 0; for (int i = 1; i <= row; i++) { for (int j = 1; j <= col; j++) { if (show[i][j] == '*') num++; } } if (num == target)return 1; return 0; } //排雷 void FindMine(char Mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) { int x = 0; int y = 0; int win = 0; int st[ROWS][COLS] = { 0 }; memset(st, 0, sizeof st); while (win<(row*col-Easy_conut)) { printf("请输入排雷的坐标->\n"); scanf("%d %d", &x, &y); //合法 if (x >= 1 && x <= row && y >= 1 && y <= col) { if (show[x][y] != '*') { printf("这个位置已经被排过了\n"); } else { //如果这个位置是雷 if (Mine[x][y] == '1') { printf("你踩到雷了,游戏结束\n"); PrintBoard(Mine, ROW, COL); break; } else { //if (win); //计算周围有多少个雷 int k = FindAround(Mine, ROW, COL); //周围的周围要是都没有雷 show[x][y] = '-'; //搜索过就置1 st[x][y] = 1; bfsfind(st, Mine, show, row, col, x, y); if (Iswin(show, ROW, COL, Easy_conut) == 1) { printf("恭喜你把所有雷都排成功了\n"); PrintBoard(Mine, ROW, COL); win = 0; break; } PrintBoard(show, ROW, COL); } } } else { printf("输入不合法\n"); } } //胜利 if (win == (row * col - Easy_conut)) { printf("恭喜你把所有雷都排成功了\n"); } }
3.game.h头文件下:
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<time.h> #define ROWS 11 #define COLS 11 #define ROW 9 #define COL 9 #define Easy_conut 5 void InitBoard(char board[ROWS][COLS], int row, int col, char set);//初始化棋盘 void PrintBoard(char board[ROWS][COLS], int row, int col);//打印棋盘 void SetMine(char Mine[ROWS][COLS], int row, int col);//设置雷 void FindMine(char Mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);//排雷