扫雷游戏是一款经典的逻辑游戏,玩家需要在雷区中找出所有没有地雷的格子,并且避免触碰到地雷。本文将详细介绍如何使用C语言来实现一个简单的扫雷游戏,并对每一步进行详细的解析。
第一步:准备工作
首先,我们需要定义游戏的基本规则和界面。扫雷游戏的界面由一个矩阵组成,每个矩阵元素代表一个格子。其中,一部分格子隐藏着地雷,其余的格子则是空白。玩家需要点击格子,如果输入坐标的格子是空白,则显示该格子周围的数字,表示该格子周围有多少个地雷;如果输入坐标的格子是地雷,则游戏结束
第二步:设计数据结构
为了实现游戏,我们需要定义一些数据结构来表示游戏的状态。以下是一些可能需要的数据结构:
(一)、游戏板
一个二维字符数组,用于表示游戏界面。其中,'*'代表空白,数字代表该格子周围的地雷数量,我们设计两个二维数组,一个为展示棋盘,我们用 show[ ][ ]来表示,他主要用来实现展周围有多少雷,以及游戏过程的,如下图:
(二)、地雷分布
一个二维整数数组,用于记录每个格子是否隐藏着地雷。我们用 char mine[ ][ ]他主要用于放置地雷,当玩家输入坐标时,其主要与mine[ ][ ]上的雷坐标比较,如果输入坐标的位置不是雷,则统计该周围有多少雷,然后反映在show[ ][ ]数组对应坐标上。mine[ ][ ]如下图:
第三步:实现过程
以下是使用C语言编写扫雷游戏的主要步骤:
1.初始化游戏板和地雷分布。
2.显示游戏界面。
3.处理用户输入。
4.判断游戏胜负。
重复步骤2-4,直到游戏结束。
(一)、初始化游戏板和地雷分布。
在进行代码编写时,我们可以用三个文件(两个源文件、一个头文件)分别编写,分别是:game.h头文件,game.c头文件,test.c源文件。(game.h头文件用于游戏过程中的函数声明,game.c则用于函数的实现,这样对函数进行封装以便日后进行修改或者应用,test.c则是我们熟知的实现整个游戏的过程。)
1、初始化游戏版
(1)、打印菜单
玩过游戏的都知道,在你进行游戏之前都会有一个选择菜单来决定你是否进行游戏以及选择游戏难度,故我们也可以实现这一过程,代码如下:
//test.c
void menu()
{
printf("******************************\n");
printf("********** 1.play ***********\n");
printf("********** 0.exit ***********\n");
printf("******************************\n");
}
int main()
{
int n = 0;
menu();//打印菜单
do
{
printf("请输入你的选择:");
scanf("%d", &n);
switch (n)
{
case 1:
game();//开始游戏
break;
case 0: break;//退出
default:
printf("输入错误,重新输入-->:");
break;
}
} while (n);
}
运行结果如下图:
(2)、创立棋盘
说到初始化棋盘,我们必须要明白一个概念,我们扫雷的时候,如果扫到的点不是雷,那么返回周围雷的数量,我们以9*9的棋盘为例如图,如果取代的点为边上点,则周围点就以超出数组,不能实现统计雷的功能,那我们创立10*10的数组,取中间的9*9为棋盘则很好的解决了这一问题。
2、初始化棋盘
- 我们可以在game.h文件声明初始化棋盘函数,以及定义数组行列数,然后再game.c源文件中进行函数实现,如下列代码:
//game.h文件
#pragma once
#include<stdio.h>
#include<stdlib.h>
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
void initboard(char arr[ROWS][COLS], int rows, int cols, char set);
//game.c文件
void initboard(char arr[ROWS][COLS], int rows, int cols, char set)
{
int i = 0;
for (i = 0;i < rows;i++)
{
int j = 0;
for (int j = 0; j < cols;j++)
{
arr[i][j] = set;
}
}
}
(4)、地雷分布
初始化棋盘后,我们就要放置雷进入数组了,我们可以将雷用某一特定字符表示,然后用循环将数组中特定数量字符替换为特定字符,表示雷的放置,代码如下:
//game.c文件
void setboard(char arr[ROWS][COLS], int row, int col,int mi)
{
int l = min;
while (l > 0)
{
int ro = rand() % row + 1;
int co = rand() % col + 1;
if (arr[ro][co] == '0')
{
arr[ro][co] = '1';
l--;
}
}
}
因为固定数量的雷是随机放置的,因此用两随机数表示雷放置的坐标
(二)、显示游戏界面
当一切准备就绪之后我们就要开始进行游戏了,首先是显示游戏界面,函数如下:
//game.c文件
void disboard(char arr[ROWS][COLS],int row,int col)
{
printf("******************扫雷***************\n");
for (int i = 0; i <= col;i++)
{
printf("%d ", i);
}
printf("\n");
for (int i = 1; i <= row; i++)
{
printf("%d ", i);
for (int j = 1; j <= col; j++)
{
printf("%c ", arr[i][j]);
}
printf("\n");
}
printf("******************扫雷***************\n");
}
运行结果是:
(三)、玩家输入并判断胜负
显示游戏界面之后,玩家进行输入开始游戏,当玩家输入坐标后,在mine[ ][ ]数组上进行判断玩家输入坐标是否与雷坐标相同,如果相同则游戏结束,即玩家被炸死了,反之,则统计周围雷的数量,在show[ ][ ]数组相同坐标处写入对应周围雷的数量,实现函数如下:
//geme.c文件
void findboard(char show[ROWS][COLS], char mine[ROWS][COLS], int row, int col, int mi)
{
int x = 0;
int y = 0;
int count = mi;
while (1) {
printf("请输入你要排查的坐标—>: ");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (mine[x][y] == '1')
{
printf("很遗憾,你被炸死了\n");
disboard(mine, ROW, COL);
break;
}
else
{
int n = Getminecount(mine, ROW, COL);
//显示周围有几个雷
show[x][y] = n + '0';
disboard(show, ROW, COL);
}
}
else
printf("输入不合规范,请重新输入");
// else
//{
//prntf("输入错误,请重新输入->: ");
//}
}
}
运行如图:
到此,整个简易的代码已完成,完整代码如下:
//game.h文件
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define ROW 9
#define COL 9
#define min 10
#define ROWS ROW+2
#define COLS COL+2
void initboard(char arr[ROWS][COLS], int rows, int cols, char set);
void disboard(char arr[ROWS][COLS], int row, int col);
void setboard(char arr[ROWS][COLS], int row, int col,int mi);
void findboard(char show[ROWS][COLS], char[ROWS][COLS], int row, int col,int mi);
//game.c文件
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void initboard(char arr[ROWS][COLS], int rows, int cols, char set)
{
int i = 0;
for (i = 0;i < rows;i++)
{
int j = 0;
for (int j = 0; j < cols;j++)
{
arr[i][j] = set;
}
}
}
void disboard(char arr[ROWS][COLS],int row,int col)
{
printf("******************扫雷***************\n");
for (int i = 0; i <= col;i++)
{
printf("%d ", i);
}
printf("\n");
for (int i = 1; i <= row; i++)
{
printf("%d ", i);
for (int j = 1; j <= col; j++)
{
printf("%c ", arr[i][j]);
}
printf("\n");
}
printf("******************扫雷***************\n");
}
void setboard(char arr[ROWS][COLS], int row, int col,int mi)
{
int l = min;
while (l > 0)
{
int ro = rand() % row + 1;
int co = rand() % col + 1;
if (arr[ro][co] == '0')
{
arr[ro][co] = '1';
l--;
}
}
}
static int Getminecount(char mine[ROWS][COLS], int x, int y)
{
return mine[x - 1][y] + mine[x - 1][y - 1] +
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 findboard(char show[ROWS][COLS], char mine[ROWS][COLS], int row, int col, int mi)
{
int x = 0;
int y = 0;
int count = mi;
while (1) {
printf("请输入你要排查的坐标—>: ");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (mine[x][y] == '1')
{
printf("很遗憾,你被炸死了\n");
disboard(mine, ROW, COL);
break;
}
else
{
int n = Getminecount(mine, ROW, COL);
//显示周围有几个雷
show[x][y] = n + '0';
disboard(show, ROW, COL);
}
}
else
printf("输入不合规范,请重新输入");
// else
//{
//prntf("输入错误,请重新输入->: ");
//}
}
}
//test.c文件
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#include "game.h"
//扫雷包括菜单,游戏,
#include<stdio.h>
void menu()
{
printf("******************************\n");
printf("********** 1.play ***********\n");
printf("********** 0.exit ***********\n");
printf("******************************\n");
}
void game()
{
char mine[ROWS][COLS];
char show[ROWS][COLS];
//初始化棋盘
initboard(mine, ROWS, COLS,'0');
initboard(show, ROWS, COLS,'*');
//打印棋盘
disboard(show, ROW, COL);
//放置雷
setboard(mine, ROW, COL,min);
//disboard(mine, ROW, COL);
//找雷
findboard(show, mine, ROW, COL,min);
}
int main()
{
int n = 0;
menu();//打印菜单
srand((unsigned int)time(NULL));
do
{
printf("请输入你的选择:");
scanf("%d", &n);
switch (n)
{
case 1:
game();//开始游戏
break;
case 0: break;//退出
default:
printf("输入错误,重新输入-->:");
break;
}
} while (n);
}
以上是一个简单的扫雷游戏实现。当然,这只是一个基础版本,还有很多可以改进和优化的地方比如:1.是否可以选择游戏难度:9*9棋盘、16*16棋盘、30*36棋盘等
2.如果周围都没雷展开一片
3.是否可以标记雷
4.是否可以加上计时器
仍然有很大的完善空间,革命尚未成功,同志任需努力,如果各位盆友喜欢我的文章,麻烦帮忙点点赞,你们的支持是我最大的动力