文章目录
🏷️前言
扫雷小游戏是电脑自带的一个趣味小游戏,相信许多小伙伴对它都有所了解,那么如和使用C语言来编写出一个扫雷游戏呢?
接下来,我将详细为大家讲解如和用C语言来实现一个简化版扫雷小游戏,如果觉得内容对你有所帮助,请点个赞支持一下吧!💓
📕游戏整体思路
- 创建三个文件test.c 、扫雷.c 、 扫雷.h
- 在test.c文件中写出游戏的大体框架
- 在扫雷.c文件中编写游戏的具体实现过程
- 在扫雷.h文件中将所使用到的函数进行声明
📙代码讲解
📖游戏框架
- 引用扫雷.h头文件
- 初始化随机函数种子
- 游戏选项至少执一次,所以用do…while循环来实现游戏整体框架的构建
- 调用menu()函数打印游戏的菜单
- 通过使用switch选择语句来判断玩家所选择的游戏状态
- 调用game()函数实现游戏过程
代码如下:(代码中附有讲解)
#define _CRT_SECURE_NO_WARNINGS
#include "扫雷.h"
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
//打印菜单
menu();
//玩家选择游戏状态
printf("请选择:>");
scanf("%d", &input);
//游戏状态实现
switch (input)
{
case 0:
printf("退出游戏!");
break;
case 1:
game();
break;
default:
printf("输入错误,请重新输入!\n");
break;
}
} while (input);
return 0;
}
📖具体实现过程
📜游戏菜单的打印
定义一个menu()函数来实现菜单的打印:
void menu()
{
printf("****************************\n");
printf("********** 1.play **********\n");
printf("********** 0.exit **********\n");
printf("****************************\n");
}
📜game函数的定义
- 定义两个数组a和b用来储存游戏数据:
char a[ROWS][COLS] = { 0 };
char b[ROWS][COLS] = { 0 };
由于计算排查坐标周围雷的数量时,当排查边上的坐标时会发生数组越界,所以在定义数组时,将数组扩大一圈。
- 调用init_board函数初始化棋盘:
init_board(a, ROWS, COLS, '0');
init_board(b, ROWS, COLS, '*');
- 调用set_a函数在数组a中布置雷:
set_a(a, ROW, COL);
- 调用display_board函数打印棋盘,在布置雷以及每一次排雷之后都打印一次棋盘b:
display_board(b, ROW, COL);
- 调用find_a函数进行排雷:
find_a(a, b, ROW, COL);
代码如下:
void game()
{
//定义两个数组,一个(a)用来存放布置好的雷的信息,另外一个(b)用来存放排查出的雷的信息
char a[ROWS][COLS] = { 0 };
char b[ROWS][COLS] = { 0 };
//初始化棋盘
//a初始化为全'0'
//b初始化为全'*'
init_board(a, ROWS, COLS, '0');
init_board(b, ROWS, COLS, '*');
//布置雷
set_a(a, ROW, COL);
//打印棋盘
display_board(b, ROW, COL);
//排雷
find_a(a, b, ROW, COL);
}
📜初始化棋盘与打印棋盘
定义两个函数init_board和display_board,分别用于初始化棋盘和棋盘的打印:
//初始化棋盘
void init_board(char board[ROWS][COLS], int rows, int cols, char set)
{
int i = 0;
for (i = 0; i < rows; i++)
{
int j = 0;
for (j = 0; j < cols; j++)
{
board[i][j] = set;
}
}
}
//打印棋盘
void display_board(char board[ROWS][COLS], int row, int col)
{
int i = 0;
int j = 0;
//打印列号
for (j = 0; j <= col; j++)
{
printf("%d ", j);
}
printf("\n");
for (i = 1; i <= row; i++)
{
//打印行号
printf("%d ", i);
for (j = 1; j <= col; j++)
{
printf("%c ", board[i][j]);
}
printf("\n");
}
}
📜布置雷
定义一个函数set_a,用来在数组a中布置雷:
布置雷可以用rand()函数生成两个随机数来当作布置雷的坐标;使用rand()之前需要在主函数中调用srand()生成时间戳,使用系统时间初始化!
void set_a(char a[ROWS][COLS], int row, int col)
{
//随机布置10个雷
int count = EASY_COUNT;
while (count)
{
int x = rand() % row + 1;
int y = rand() % col + 1;
//在未被占用的格子中放置雷
if (a[x][y] == '0')
{
a[x][y] = '1';
count--;
}
}
}
📜排雷
定义一个函数find_a,用来进行排雷
void find_a(char a[ROWS][COLS], char b[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
int win = 0;
//总共有81个格子,当排除71个格子都没有被炸死,则游戏胜利
while (win < (row * col - EASY_COUNT))
{
printf("请输入要排查的坐标:>");
scanf("%d %d", &x, &y);
//判断坐标的合法性以
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
//判断坐标是否被排查过
if (b[x][y] == '*')
{
//判断是否踩雷
if (a[x][y] == '1')
{
printf("很遗憾,你被炸死了!\n");
display_board(a, ROW, COL);
break;
}
else
{
int count = get_a_count(a, x, y);
b[x][y] = count + '0';
display_board(b, ROW, COL);
win++;
}
}
else
{
printf("该坐标已经被排查过了!\n");
}
}
else
{
printf("该坐标非法,请重新输入!\n");
}
}
if (win == (row * col - EASY_COUNT))
{
printf("恭喜你,排雷成功!\n");
display_board(a, ROW, COL);
}
}
📜计算玩家排查坐标周围有多少颗雷
定义一个函数get_a_count,用来计算排查坐标周围的雷的数量:
注意:二维数组中所存的值是字符型,通过将周围的八个字符型加起来后减去八个‘0’的ARC2码值将其转换为整型
int get_a_count(char a[ROWS][COLS], int x, int y)
{
return (a[x - 1][y - 1] +
a[x - 1][y] +
a[x - 1][y + 1] +
a[x][y + 1] +
a[x + 1][y + 1] +
a[x + 1][y] +
a[x + 1][y - 1] +
a[x][y - 1] - 8 * '0');
}
📖在头文件中声明函数
将所用到的函数在扫雷. h 文件中进行声明:
#define ROW 9 //扫雷时打印在屏幕上的行数
#define COL 9 //扫雷时打印在屏幕上的列数
#define ROWS ROW+2 //数组的行数
#define COLS COL+2 //数组的列数
#define EASY_COUNT 10 //布置雷的个数
#include<stdio.h>
//菜单
void menu();
//玩游戏
void game();
//初始化棋盘
void init_board(char board[ROWS][COLS], int rows, int cols, char set);
//打印棋盘
void display_board(char board[ROWS][COLS], int row, int col);
//布置雷
void set_a(char a[ROWS][COLS], int row, int col);
//计算周围有几颗雷
int get_a_count(char a[ROWS][COLS], int x, int y);
//排雷
void find_a(char a[ROWS][COLS], char b[ROWS][COLS], int row, int col);
📘完整代码
1. 扫雷.h文件
#define ROW 9 //扫雷时打印在屏幕上的行数
#define COL 9 //扫雷时打印在屏幕上的列数
#define ROWS ROW+2 //数组的行数
#define COLS COL+2 //数组的列数
#define EASY_COUNT 10 //布置雷的个数
#include<stdio.h>
//菜单
void menu();
//玩游戏
void game();
//初始化棋盘
void init_board(char board[ROWS][COLS], int rows, int cols, char set);
//打印棋盘
void display_board(char board[ROWS][COLS], int row, int col);
//布置雷
void set_a(char a[ROWS][COLS], int row, int col);
//计算周围有几颗雷
int get_a_count(char a[ROWS][COLS], int x, int y);
//排雷
void find_a(char a[ROWS][COLS], char b[ROWS][COLS], int row, int col);
2. 扫雷.c文件
#define _CRT_SECURE_NO_WARNINGS
#include "扫雷.h"
//打印菜单
void menu()
{
printf("****************************\n");
printf("********** 1.play **********\n");
printf("********** 0.exit **********\n");
printf("****************************\n");
}
//玩游戏
void game()
{
//游戏数据存储需要两个 9*9 的数组,但为了防止使用时数组越界,使用 11*11 的数组
//一个(a)用来存放布置好的雷的信息,另外一个(b)用来存放排查出的雷的信息
char a[ROWS][COLS] = { 0 };
char b[ROWS][COLS] = { 0 };
//初始化棋盘
//a初始化为全'0'
//b初始化为全'*'
init_board(a, ROWS, COLS, '0');
init_board(b, ROWS, COLS, '*');
//打印棋盘
//display_board(a,ROWS,COLS);
//display_board(b,ROWS,COLS);
//
//布置雷
set_a(a, ROW, COL);
//打印棋盘
//display_board(a, ROW, COL);
display_board(b, ROW, COL);
//排雷
find_a(a, b, ROW, COL);
}
//初始化棋盘
void init_board(char board[ROWS][COLS], int rows, int cols, char set)
{
int i = 0;
for (i = 0; i < rows; i++)
{
int j = 0;
for (j = 0; j < cols; j++)
{
board[i][j] = set;
}
}
}
//打印棋盘
void display_board(char board[ROWS][COLS], int row, int col)
{
int i = 0;
int j = 0;
//打印列号
for (j = 0; j <= col; j++)
{
printf("%d ", j);
}
printf("\n");
for (i = 1; i <= row; i++)
{
//打印行号
printf("%d ", i);
for (j = 1; j <= col; j++)
{
printf("%c ", board[i][j]);
}
printf("\n");
}
}
//布置雷
void set_a(char a[ROWS][COLS], int row, int col)
{
//随机布置10个雷
int count = EASY_COUNT;
while (count)
{
int x = rand() % row + 1;
int y = rand() % col + 1;
//在未被占用的格子中放置雷
if (a[x][y] == '0')
{
a[x][y] = '1';
count--;
}
}
}
//计算周围有几颗雷
int get_a_count(char a[ROWS][COLS], int x, int y)
{
return (a[x - 1][y - 1] +
a[x - 1][y] +
a[x - 1][y + 1] +
a[x][y + 1] +
a[x + 1][y + 1] +
a[x + 1][y] +
a[x + 1][y - 1] +
a[x][y - 1] - 8 * '0');
}
//排雷
void find_a(char a[ROWS][COLS], char b[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
int win = 0;
//总共有81个格子,当排除71个格子都没有被炸死,则游戏胜利
while (win < (row * col - EASY_COUNT))
{
printf("请输入要排查的坐标:>");
scanf("%d %d", &x, &y);
//判断坐标的合法性
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
//判断坐标是否被排查过
if (b[x][y] == '*')
{
//判断是否踩雷
if (a[x][y] == '1')
{
printf("很遗憾,你被炸死了!\n");
display_board(a, ROW, COL);
break;
}
else
{
int count = get_a_count(a, x, y);
b[x][y] = count + '0';
display_board(b, ROW, COL);
win++;
}
}
else
{
printf("该坐标已经被排查过了!\n");
}
}
else
{
printf("该坐标非法,请重新输入!\n");
}
}
if (win == (row * col - EASY_COUNT))
{
printf("恭喜你,排雷成功!\n");
display_board(a, ROW, COL);
}
}
3. test.c文件
#define _CRT_SECURE_NO_WARNINGS
#include "扫雷.h"
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
//打印菜单
menu();
printf("请选择:>");
scanf("%d", &input);
//游戏实现
switch (input)
{
case 0:
printf("退出游戏!\n");
break;
case 1:
game();
break;
default:
printf("输入错误,请重新输入!\n");
break;
}
} while (input);
return 0;
}
📗运行截图
最后,如果觉得内容对你有所帮助,就请点个赞支持一下吧!