今天我们来完成用C语言做个简易的扫雷游戏。
- 1.首先我们要做个游戏菜单运行的雏形。
建立一个test.c文件
int main() {
int a = 0;
do{
menu();
printf("请输入您的选择:>");
scanf("%d", &a);
switch(a)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("错误输入,请重新输入\n");
break;
}
}while (a);
return 0;
}
因为是游戏,无论选择是否要玩我们都应该进行一次程序,所以我们应该使用do while循环。
menu和game函数是我们后面需要去编写的。
- 2.编写menu函数
void menu() {
printf("*****扫雷游戏******\n");
printf("*****1.play ******\n");
printf("*****0.exit ******\n");
printf("******************\n");
}
这就是一个简易的菜单函数。
- 3.编写game函数
1.编写棋盘
首先我们要明白扫雷的基本逻辑,我们应该分别有两个棋盘,也就是两个二维数组一个是布置雷的情况,一个是展示给玩家的棋盘。
其次我们知道扫雷是把周围9个格子是否有几个雷,标在我们排查的格子上。但是例如9x9的扫雷中,我们选取周围的格子,外面的我们也要探索,所以我们干脆设定11x11的棋盘格子。
我们建立一个头文件game.h在里面编写
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
其次在test.c中编写以下代码建立我们的两个棋盘。
void game() {
char mine[ROWS][COLS] = {0};
char show[ROWS][COLS] = {0};
}
2.棋盘初始化
我们要把二维数组初始化,show数组是展示给玩家的,所以都要是*符号,而内部棋盘则都为0
所以我们设立函数InitBoard来初始化棋盘。
我们建立个文件game.c用来编写我们后面要在game函数中使用的函数。
首先我们要在头文件game.h声明
//棋盘初始化
void InitBoard(char arr[ROWS][COLS],int rows,int cols,int set);
接着在game.c中编写棋盘初始化。
void InitBoard(char mine[ROWS][COLS], int rows, int cols,int set) {
int i = 0;
for (i = 1; i < rows; i++) {
int j = 0;
for (j = 1; j < cols; j++) {
mine[i][j] = set;
}
}
}
设定set这样可以方便我们初始化什么字符,这样我们可以避免要写两个相似函数,分别去初始化'0'和初始化'*'。
3.布置雷
我们要开始布置雷的位置,我们要随机或者坐标,来布置雷的位置,所以我们要用到随机数。当然我们要在头文件编写以下代码
#include<stdlib.h>
#include<time.h>
接着在test.c中添加代码
srand((unsigned int)time(NULL));
这样我们就可以使用随机数。我们为了在后面方便更改游戏难度,所以我们在后文件定义一个变量
#define EASY 10
接下来在game.c中编写布置雷函数的代码
void InputBoard(char arr[ROWS][COLS], int row, int col) {
int count = EASY;
while (count) {
int x = rand() % row + 1;
int y = rand() % col + 1;
if (arr[x][y] == '0') {
arr[x][y] = '1';
count--;
}
}
}
我们默认'1'为雷。而count就是雷的个数,每布置一颗减少一count,这样我们就完成好了布置雷的代码。
4.打印棋盘
当我们在输入我们检测的格子,肯定要弹出棋盘,所以我们要打印出棋盘给玩家观看。
首先在头文件game.h中声明打印棋盘的函数。
void PlayBoard(char arr[ROWS][COLS], int row, int col);
接着在game.c中编写打印棋盘的函数。
void PlayBoard(char arr[ROWS][COLS], int row, int col) {
printf("------扫雷游戏------\n");
int i = 0;
int k = 0;
for (k = 0; k <=row; k++) {
printf("%d ", k);
}
printf("\n");
for (i = 1; i <= row; i++) {
int j = 0;
printf("%d ", i);
for (j = 1; j <= col; j++) {
printf("%c ", arr[i][j]);
}
printf("\n");
}
}
这样我们就完成了打印棋盘的函数。
5.排查雷
扫雷游戏最重要的肯定是排查雷的过程。所以我们肯定要编写排查雷的函数。首先还是在头文件声明函数
void FindBoard(char mine[ROWS][COLS],char show[ROWS][COLS], int row, int col);
因为我们要首先检查是否有雷,其次要在展示给玩家的棋盘中展示周围的情况。所以我们要有两个二维数组。
接着我们要在game.c中编写代码
void FindBoard(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) {
int x = 0;
int y = 0;
int win = 0;
while (win<row*col-EASY) {
printf("请输入排查的坐标:>");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >=1 && y <= col) {
if (mine[x][y] == '1') {
printf("很遗憾,你被炸死了\n");
PlayBoard(mine, ROW, COL);
break;
}
else {
int count = MakeCount(mine,x,y);
show[x][y] = count+'0';
PlayBoard(show, ROW, COL);
win++;
}
}
else {
printf("非法输入,请重新输入\n");
}
}
}
因为如果没有中雷,我们要提供周围雷的数量,所以我们再在前面编写统计雷的个数的函数Makecount。
int MakeCount(char mine[ROWS][COLS],int x,int y) {
int i = 0;
int count = 0;
for (i = x - 1; i <= x + 1; i++) {
int j = 0;
for (j = y - 1; j <= y + 1; j++) {
count+=(mine[i][j] - '0');
}
}
return count;
}
这个函数的逻辑用画图来解释
假设我们排查中间坐标的格子,那周围的格子的坐标我们都能求得,之后就统计周围的'1'的数量。
这样我们就完成了排查雷的过程。接着我们就要完成test.c中game函数的过程。
void game() {
char mine[ROWS][COLS] = {0};
char show[ROWS][COLS] = {0};
InitBoard(mine, ROWS, COLS, '0');
InitBoard(show, ROWS, COLS, '*');
InputBoard(mine,ROW,COL);
PlayBoard(show, ROW, COL);
FindBoard(mine,show, ROW, COL);
}
这样我们就完成了最简单的扫雷游戏。(要注意注明头文件#include"game.h")
当然还有进阶的需要大家自己去拓展升级。
1.难度的不同
9x9 10个雷
16x16 40个雷
30x16 99个雷
2.如果排除位置不是雷,周围也没有雷,可以展开周围的一片。
3.是否可以标记雷的位置。
4.是否有排查雷的时间。