> 文档中心 > 学会了C语言,不来自己写个【扫雷】小项目吗?

学会了C语言,不来自己写个【扫雷】小项目吗?


💟作者简介:大家好,我是Ceylan_,可以叫我CC ❣️    
📝个人主页:Ceylan_的博客
🏆博主信息:平凡的大一学生,有着不平凡的梦

        专栏

  • 【备战蓝桥,冲击省一】

⚡希望大家多多支持😘一起进步~❤️
🌈若有帮助,还请关注点赞收藏,不行的话我再努努力💪

🌟什么是扫雷

这款游戏的玩法是在一个9*9的方块矩阵中随机布置10个地雷。由玩家逐个翻开方块,以找出所有地雷为最终游戏目标。如果玩家翻开的方块有地雷,则游戏结束。游戏目标是在最短的时间内根据点击格子出现的数字找出所有非雷格子,同时避免踩雷。

下面我们就用尝试用C语言实现这个游戏。

🌟菜单界面

⭐️游戏菜单

游戏总需要一个界面吧,不然不知道应该干什么,通过【printf】函数实现菜单界面,打开游戏自动跳出 1.开始游戏 0.退出游戏。

void menu(){printf("****************************\n");printf("*******  1.开始游戏  *******\n");printf("*******  0.退出游戏  *******\n");printf("****************************\n");}

⭐️实现选择 

有了菜单,下一步就是选择选项了,这里需要考虑一下输入错误的情况偶。

void choice(){int num;do{menu();printf("请输入您的选项:");scanf("%d",&num);switch (num){case(1):game(); break;case(0):printf("退出游戏\n"); break;default:printf("输入错误,小笨蛋~~\n");break;}}while(num);}

🌟棋盘界面

⭐️创建雷盘

菜单界面,选择都完成了。扫雷最重要的扫雷界面还没有建立。我们需要两个二维数组来存储扫雷信息,第一个用来存放雷,也就是用来埋雷的。第二个用来显示扫雷界面,及显示玩家扫雷位置的。

为了更好的计算我们要扫的位置处周围有多少雷,我们把数组长度定义为11。

#define ROW 9  #define COL 9char mine[ROW+2][COL+2] = { 0 };//存放雷char show[ROW+2][COL+2] = { 0 };//扫雷界面

⭐️初始化雷盘

拥有了棋盘还不够,棋盘里面没有东西呀,我们将布雷棋盘内填满 0 ,在显示棋盘内填满 *

void Init(char board[ROWS][COLS], int row, int col, char set){int i = 0 ;int j = 0 ;for (i = 0; i < row + 2; i++){for (j = 0; j < col + 2; j++){board[i][j] = set;}}}Init(mine, ROW, COL, '0');Init(show, ROW, COL, '*');

 ⭐️打印雷盘

打印时我们可以多输出一次坐标,方便游玩时查找坐标

void Display(char board[ROWS][COLS], int row, int col){int i = 0;int j = 0;printf("******扫雷游戏*******\n");for (i = 0; i < row + 1; i++){printf("%d ", i);for (j = 1; j < col + 1; j++){if (i == 0)printf("%d ", j);elseprintf("%c ", board[i][j]);}printf("\n");}}

🌟扫雷界面

⭐️布置雷

我们实现了玩家下棋的逻辑之后,就要实现电脑下棋的逻辑了,电脑的逻辑就是生成两个随机数,分别%3,得到的就是符合三子棋二维数组坐标要求的两个数。

⚡️随机数函数

在这里我们需要两个随机数,可以使用【 rand() 】函数

使用rand()函数需要引用【#include】头文件

默认情况下【 rand() 】函数并不是一个真随机函数,而是一个假随机函数。在使用时侯还需调用【srand()】函数,【srand()】函数会设置供【 rand() 】函数使用的随机数种子,每一个种子对应一组根据算法预先生成的随机数;

    srand((unsigned) time(NULL));//产生种子

void Set_Mine(char mine[ROWS][COLS], int row, int col, int count){while (count){int x = rand() % row + 1;int y = rand() % col + 1;if (mine[x][y] == '0'){mine[x][y] = '1';count--;}}}

 🌟扫雷

⭐️选择位置

void Sweep(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int count){int x = 0;int y = 0;int judge = 0;while (judge < row*col - count){ judge = 0;printf("请输入要扫除的坐标: \n");scanf("%d %d", &x, &y);if (x < 0 || y  row || y > col)printf("输入错误,小笨蛋~~\n");else if (show[x][y] != '*')printf("该坐标已被扫了偶\n"); if(judge == 0)No_mine(mine, show, x, y, row, col); if (mine[x][y] != '1') { Spread(x, y, mine, show, row, col); Display(show, row, col); } else { printf("你被炸死了\n"); break; } Stat_judge(show, &judge, row, col);}

⭐️第一次不为雷

void No_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int i, int j, int row, int col){if (mine[i][j] == '1'){while (1){int x = rand() % row + 1;int y = rand() % col + 1;if (mine[x][y] == '0'){mine[x][y] = '1';break;}}mine[i][j] = '0';}}

 ⭐️落子周围雷数

int Count_Mine(int x, int y, char mine[ROWS][COLS]){return mine[x - 1][y - 1]+ mine[x - 1][y]+ mine[x - 1][y + 1]+ mine[x][y - 1]+ mine[x][y + 1]+ mine[x + 1][y - 1]+ mine[x + 1][y]+ mine[x + 1][y + 1] - 8 * '0';}

⭐️落子周围无雷

void Spread(int x, int y, char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col){char count = Count_Mine(x, y, mine) + '0';if (count != '0')show[x][y] = count;else{show[x][y] = ' ';if (x - 1 > 0 && show[x - 1][y] == '*')Spread(x - 1, y, mine, show, row, col);if (y - 1 > 0 && show[x][y - 1] == '*')Spread(x, y - 1, mine, show, row, col);if (y + 1 < col + 1 && show[x][y + 1] == '*')Spread(x, y + 1, mine, show, row, show);if (x + 1 < row + 1 && show[x + 1][y] == '*')Spread(x + 1, y, mine, show, row, col);}}

 🌟判断胜利

void Stat_judge(char show[ROWS][COLS], int* judge, int row, int col){int i = 0;int j = 0;for (i = 1; i < row + 1; i++){for (j = 1; j < col + 1; j++){if (show[i][j] != '*')(*judge)++;}}}

🌟游戏函数

void game(){srand((unsigned long)time(NULL)); //生成随机数种子char mine[ROWS][COLS] = { 0 };char show[ROWS][COLS] = { 0 };Init_board(mine, ROWS, COLS, '0');//初始化雷盘Init_board(show, ROWS, COLS, '*');//初始化展示的雷盘Set_Mine(mine,ROW,COL,10);Sweep(mine,show,ROW,COL,10);}

🌟代码详细

下面是完整代码,可以试一试自己完整的写一遍。

#include#include#include#define ROW 9  #define COL 9#define ROWS ROW + 2#define COLS ROW + 2void game();void Sweep(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int count);void No_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int i, int j, int row, int col);void Spread(int x, int y, char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);void Stat_judge(char show[ROWS][COLS], int* judge, int row, int col);void menu(){printf("****************************\n");printf("*******  1.开始游戏  *******\n");printf("*******  0.退出游戏  *******\n");printf("****************************\n");}void choice(){int num;do{menu();printf("请输入您的选项:");scanf("%d",&num);switch (num){case(1):game(); break;case(0):printf("退出游戏\n"); break;default:printf("输入错误,小笨蛋~~\n");break;}}while(num);}void Init_board(char board[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++){board[i][j] = set;}}}void Set_Mine(char mine[ROWS][COLS], int row, int col, int count){while (count){int x = rand() % row + 1;int y = rand() % col + 1;if (mine[x][y] == '0'){mine[x][y] = '1';count--;}}}void Display(char board[ROWS][COLS], int row, int col){int i = 0;int j = 0;printf("******扫雷游戏*******\n");for (i = 0; i < row + 1; i++){printf("%d ", i);for (j = 1; j < col + 1; j++){if (i == 0)printf("%d ", j);elseprintf("%c ", board[i][j]);}printf("\n");}}void Sweep(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int count){int x = 0;int y = 0;int judge = 0;while (judge < row*col - count){judge = 0;printf("请输入要扫除的坐标: \n");scanf("%d %d", &x, &y);if (x < 0 || y  row || y > col)printf("输入错误,小笨蛋~~\n");else if (show[x][y] != '*')printf("该坐标已被扫除了偶:\n"); if(judge == 0)No_mine(mine, show, x, y, row, col); if (mine[x][y] != '1') { Spread(x, y, mine, show, row, col); Display(show, row, col); } else { printf("你被炸死了\n"); break; } Stat_judge(show, &judge, row, col);}if (judge == row * col - count){printf("恭喜你排雷成功\n");}}void No_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int i, int j, int row, int col){if (mine[i][j] == '1'){while (1){int x = rand() % row + 1;int y = rand() % col + 1;if (mine[x][y] == '0'){mine[x][y] = '1';break;}}mine[i][j] = '0';}}int Count_Mine(int x, int y, char mine[ROWS][COLS]){return mine[x - 1][y - 1]+ mine[x - 1][y]+ mine[x - 1][y + 1]+ mine[x][y - 1]+ mine[x][y + 1]+ mine[x + 1][y - 1]+ mine[x + 1][y]+ mine[x + 1][y + 1] - 8 * '0';}void Spread(int x, int y, char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col){char count = Count_Mine(x, y, mine) + '0';if (count != '0')show[x][y] = count;else{show[x][y] = ' ';if (x - 1 > 0 && show[x - 1][y] == '*')Spread(x - 1, y, mine, show, row, col);if (y - 1 > 0 && show[x][y - 1] == '*')Spread(x, y - 1, mine, show, row, col);if (y + 1 < col + 1 && show[x][y + 1] == '*')Spread(x, y + 1, mine, show, row, col);if (x + 1 < row + 1 && show[x + 1][y] == '*')Spread(x + 1, y, mine, show, row, col);}}void Stat_judge(char show[ROWS][COLS], int* judge, int row, int col){int i = 0;int j = 0;for (i = 1; i < row + 1; i++){for (j = 1; j < col + 1; j++){if (show[i][j] != '*')(*judge)++;}}}void game(){srand((unsigned long)time(NULL)); //生成随机数种子char mine[ROWS][COLS] = { 0 };char show[ROWS][COLS] = { 0 };Init_board(mine, ROWS, COLS, '0');//初始化雷盘Init_board(show, ROWS, COLS, '*');//初始化展示的雷盘Set_Mine(mine,ROW,COL,10);Sweep(mine,show,ROW,COL,10);}int main(){choice();return 0;}

🌺结束语

        本人不才,如有错误,欢迎各位大佬在评论区讨论。有帮助的话还请【关注点赞收藏】,不行的话我再努努力💪💪💪

3783c370bbfc4de9988e2631eaf0ff14.png

字库吧