🚀前言
大家好啊!今天咱们来整一个有意思的小游戏扫雷,相信大家对扫雷并不陌生,那接下来就跟着阿辉把它拿捏了😉
🚀实现扫雷游戏的逻辑
1.实现一个函数打印菜单选择玩游戏和退出游戏
2.创建两个二维数组,一个布置雷,一个打印扫雷的游戏的展示棋盘
3.布置雷
4.打印棋盘
5.玩家输入坐标排雷
6.判断坐标是否是雷,是雷game over,不是雷显示周围有几个雷,展开一片
7.判断玩家是否赢了
🚀扫雷游戏实现的过程/步骤
采用模块化设计,分为game.c
,game.h
,test.c
三部分
- game.c:存放实现扫雷游戏的函数
- game.h:存放各种库函数头文件和函数声明
- test.c:用于代码逻辑测试
下面具体步骤我直接上代码,注释有讲解
✈️game.h
#include<stdio.h> #include<stdlib.h> #include<time.h> //当排雷时判断周围有几个雷,为防止边缘的坐标判断时越界访问,9*9的棋盘实际上用的11*11的数组 #define ROWS 11 //行 #define COLS 11 //列 //虽然用的是11*11的数组,但实际上仅操作里面9*9的部分 #define ROW 9 //行 #define COL 9 //列 //布置雷的数目 #define Easy_mine 10 //初始化棋盘 void Initboard(char show[ROWS][COLS], int row, int col, char set); //布置雷 void Set_mine(char mine[ROWS][COLS],int row, int col); //打印棋盘 void Display_show(char show[ROWS][COLS], int row, int col); //玩家排雷 void Find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col); //展开一片 void unfold(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col,int *p);
✈️test.c
#define _CRT_SECURE_NO_WARNINGS 1 #include"game.h" void menu()//打印菜单,选择进入游戏还是退出 { printf("*********************************\n"); printf("************ play:> 1 **********\n"); printf("************ exit:> 0 **********\n"); printf("*********************************\n"); } void game()//扫雷游戏实现 { char mine[ROWS][COLS] = {0};//存放布置雷的信息 char show[ROWS][COLS] = {0};//存放排查出雷的信息,在屏幕上打印展示 //初始化 //给存mine数组初始化,给数组全都存放'0' Initboard(mine, ROWS, COLS, '0'); //给show数组初始化,给数组全都存放'*' Initboard(show, ROWS, COLS, '*'); //给初始化后的mine数组中布置雷,仅仅在要显示的9*9的范围里布置雷 Set_mine(mine, ROW, COL); //打印棋盘 Display_show(show, ROW, COL); //Display_show(mine, ROW, COL); //排查雷 Find_mine(mine,show,ROW,COL); } int main() { srand((unsigned int)time(NULL)); menu(); int input = 0; do { printf("请选择:>"); scanf("%d", &input); switch (input) { case 1: game(); break; case 0: printf("退出游戏!\n"); break; default: printf("选择错误,请重新选择!\n"); } } while (input); //根据玩家输入的值,实现重复游戏和退出游戏 return 0; }
✈️game.c
扫雷游戏逻辑的具体实现
🚁初始化棋盘
//传入字符数组首地址,行,列以及初始化的类容,可以更根据初始化类容初始化棋盘 void Initboard(char show[ROWS][COLS], int row, int col, char set) { int i = 0; int j = 0; for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { show[i][j] = set; } } }
🚁布置雷
void Set_mine(char mine[ROWS][COLS], int row, int col) { int count = 0; while (count < Easy_mine) //雷的数目布置完毕跳出循环 { //使用rand函数在9*9的范围内随机生成雷 int x = rand() % row + 1; int y = rand() % col + 1; //判断要生成雷的坐标是否已经被布置雷了,防止重复布置雷 if (mine[x][y] == '0') { mine[x][y] = '1'; count++; //记录成功布置类的个数 } } }
🚁打印扫雷游戏棋盘
界面展示
void Display_show(char show[ROWS][COLS], int row, int col) { int i = 0; int j = 0; printf("-------------扫雷----------------\n"); //打印第一行的数字,方便玩家输入坐标 for (i = 0; i <= row; i++) { printf("%d ", i); } printf("\n"); //11*11的数组但是仅仅打印中间的9*9 for (i = 1; i < row + 1; i++) { printf("%d ", i); //打印第一列的数字,方便玩家输入坐标 for (j = 1; j < col + 1; j++) { printf("%c ", show[i][j]); } printf("\n"); } printf("-------------扫雷----------------\n"); }
🚁玩家排雷并判断输赢
//同时传入mine数组和show数组 void Find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) { int count = 0; while (1) { int x = 0; int y = 0; printf("请输入要排查的坐标:>"); scanf("%d%d", &x, &y); //玩家输入要排雷的坐标 //判断玩家要排查的坐标是否合法,防止越界 if ((x <= ROW && x > 0) && (y <= COL && y > 0)) { `//判断玩家要排查的坐标是否未被排查 if (show[x][y] == '*') { //判断玩家要排查雷的坐标是否是雷 if (mine[x][y] == '1') { printf("很遗憾,你被炸死了!\n"); Display_show(mine, ROW, COL); break; } else { //玩家要排查的坐标不是雷,则展示周围有几个雷 //传入的count用于记录玩家排的不是雷的坐标 unfold(mine, show, x, y,&count); //打印排查过后的棋盘show Display_show(show, ROW, COL); } } else { printf("重复输入,请重新输入!\n"); } } else { printf("输入错误,请重新输入!\n"); } //count的值为(9*9 - 10)的时候说明玩家排雷成功 if (count ==ROW * COL - Easy_mine) { printf("恭喜你,排雷成功!\n"); Display_show(mine, ROW, COL); break; } } }
🚁展开一片
void unfold(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y, int* p) { int sum = 0; //判断坐标是否合法,防止越出9*9的范围,判断坐标是否被判断过防止死递归 if ((x <= ROW && x > 0) && (y <= COL && y > 0) && show[x][y] == '*') { (*p)++; //判断玩家要排查的坐标周围8个坐标有几个雷 for (int i = -1; i < 2; i++) { for (int j = -1; j < 2; j++) { //sum记录周围雷的个数 //因为mine数组中存的是字符,雷是'1',非雷是'0',由于字符在内存中存的是ASC码值,'0'-'0'=数字0,'1'-'0'=数字1 sum = sum + mine[x + i][y + j] - '0'; } } //如果要排查坐标周围没有雷,就展开一片 if (sum == 0) { //给已经判断周围没有雷的坐标赋上' '(空格),用于打印展示以及作为已经被判断的标志防止死递归 show[x][y] = ' '; //遍历走位坐标实现展开一片 for (int i = -1; i < 2; i++) { for (int j = -1; j < 2; j++) { unfold(mine, show, x + i, y + j, &(*p)); } } } //当周围有雷就给坐标对应数组赋上周围雷的个数的数字字符 else { show[x][y] = '0' + sum; return; } } else return; }
🚀结语
感谢各位美女帅哥能看到这, 希望这篇博客能让大家有所收获, 如果觉得阿辉写得不错的话,记得给个赞呗,你们的支持是我创作的最大动力🌹