欢迎来到我的博客!!💃💃
🏡🏡推荐博客:August_._一起持续学习,不断总结,共同进步🎊🎊
思路讲解
文件结构设计
我们学过多文件的形式对函数的声明和定义,现在我们设计三个文件:
game.h //游戏需要的数据类型和函数声明
game.c //游戏中函数的实现
main.c //游戏的测试逻辑
结构分析
定义俩个数组:
char mine[ROWS][COLS] = {0}; //放雷
char show[ROWS][COLS] = {0}; //显示排雷的信息
⼀个棋盘(数组mine)存放布置好的雷的信息,另⼀个棋盘(数组show)存放排查出的雷的信息。在mine数组中排查雷,排查出的数据存放在show数组,并且打印show数组的信息给后期排查参考。俩个数组使⽤同⼀套函数处理,可以使两个数组的类型⼀致,show数组开始时初始化为字符 ’ * ‘,mine数组最开始初始化为字符’0’,布置雷改成’1’。
注意:
扫雷游戏中排查四周时,访问周围的⼀圈8个位置,统计周围雷的个数时会越界,我们为了防⽌越界,可以给数组扩⼤⼀圈,雷还是布置在中间的 9 x 9 的坐标上,周围⼀圈不布置雷就⾏,这样就解决了越界的问题。所以我们将存放数据的数组创建成11 x 11 是⽐较合适。
初始化棋盘
通过 for 循环遍历二维数组,完成棋盘的初始化。其中第四个参数 “set” 是棋盘初始化的字符。
for(int i=0; i<rows; i++)
for(int j=0; j<rows; j++)
qipan[i][j] = set;
打印棋盘
虽然定义了俩个 11 x 11 的数组,但我们只需打印出 show 数组中间 9 x 9 的部分就行了。
void dayin(char qipan[ROWS][COLS], int row, int col)
{
int i;
printf("-----------扫雷游戏-----------\n");
for(i=0; i<=col; i++) printf("%d ", i);
printf("\n");
for(i=1; i<=row; i++){
printf("%d ", i);
for(int j=1; j<=row; j++) printf("%c ", qipan[i][j]);
printf("\n");
}
}
布置雷
在 game.h 文件中,先宏定义:
#define COUNT 10 //设置雷的总数
通过while循环不断生成雷的坐标,当该坐标处没有雷时,在该处布置雷,并且变量 counts 减一,进入下次循环;直到 counts 等于0,此时循环结束。
void putmine(char qipan[ROWS][COLS], int row, int col)
{
int x, y,counts = COUNT;
while (counts) {
x = rand()%row + 1;
y = rand()%col + 1;
if(qipan[x][y] == '0'){
qipan[x][y] = '1';
counts--;
}
}
}
统计雷的信息
玩家选择 行、列 后,game.c 文件中的 getmine() 函数会统计此处周围八个点含雷的数量。因为 “雷” 是用字符 ‘1’ 来表示的,如果此处没有 ”雷“ ,则用字符 ‘0’ 来表示。
在ASCII码中,'0' 是 48,'1' 是 49
。
int getmine(char mine[ROWS][COLS], int x, int y)
{
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');
}
findmine() 函数中:
sum = getmine(mine, x, y); //接收getmine()返回的数字,即周围雷的总数
show[x][y] = sum + '0'; //将数字转化为字符
排查雷
定义变量 win ,如果 win == ROW*COL-COUNT 条件成立,则排雷成功,游戏结束。
if(win == ROW*COL-COUNT){
printf("\n恭喜你,排雷成功!\n游戏结束!");
break;
}
源代码
game.h
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define COUNT 10
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
//初始化棋盘
void chushihua(char qipan[ROWS][COLS], int rows, int cols, int set);
//打印棋盘
void dayin(char qipan[ROWS][COLS], int row, int col);
//布置雷
void putmine(char qipan[ROWS][COLS], int row, int col);
//排查雷
void findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
main.c
#include "game.h"
void menu()
{
printf(" ----------扫雷游戏------------\n");
printf("| 【1】 Play |\n");
printf("| 【0】 Stop |\n");
printf(" ------------------------------\n");
}
void game()
{
char mine[ROWS][COLS] = {0};//放雷
char show[ROWS][COLS] = {0};//显示排雷的信息
//初始化棋盘
chushihua(mine, ROWS, COLS, '0');
chushihua(show, ROWS, COLS, '*');
//打印棋盘
dayin(show, ROW, COL);
//布置雷
putmine(mine, ROW, COL);
//排查雷
findmine(mine, show, ROW, COL);
}
int main(void)
{
int input;
srand((unsigned int)time(NULL));
do {
menu();
printf("请输入您的选择:");
scanf("%d",&input);
switch (input) {
case 1: game();
break;
case 0: printf("\n游戏结束!");
break;
default: printf("\n输入有误,请重新输入");
}
}while (input);
return 0;
}
game.c
#include "game.h"
//初始化棋盘
void chushihua(char qipan[ROWS][COLS], int rows, int cols, int set)
{
for(int i=0; i<rows; i++)
for(int j=0; j<rows; j++)
qipan[i][j] = set;
}
//打印棋盘
void dayin(char qipan[ROWS][COLS], int row, int col)
{
int i;
printf("-----------扫雷游戏-----------\n");
for(i=0; i<=col; i++) printf("%d ", i);
printf("\n");
for(i=1; i<=row; i++){
printf("%d ", i);
for(int j=1; j<=row; j++) printf("%c ", qipan[i][j]);
printf("\n");
}
}
//放雷
void putmine(char qipan[ROWS][COLS], int row, int col)
{
int x, y,counts = COUNT;
while (counts) {
x = rand()%row + 1;
y = rand()%col + 1;
if(qipan[x][y] == '0'){
qipan[x][y] = '1';
counts--;
}
}
}
//统计雷的信息
int getmine(char mine[ROWS][COLS], int x, int y)
{
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 findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
int x=0, y=0, win=0;
while(win<ROW*COL-COUNT){
printf("请输入坐标(x y): ");
scanf("%d %d", &x, &y);
if(x>=1&&x <= ROW && y >= 1 && y <= COL){
if(mine[x][y] == '1'){
printf("\n你踩到雷啦! 游戏结束!!\n");
dayin(mine, ROW, COL);
break;
}
else{
int sum = getmine(mine, x, y);
show[x][y] = sum + '0';
dayin(show, ROW, COL);
win++;
}
if(win == ROW*COL-COUNT){
printf("\n恭喜你,排雷成功!\n游戏结束!");
break;
}
}
}
}
运行截图
以下是部分运行截图,你也可以试着运行下哦!