1.扫雷游戏的规则介绍
1## 1.1游戏概述
《扫雷》是一款大众类的益智小游戏,于1992年发行。游戏目标是在最短的时间内根据点击格子出现的数字找出所有非雷格子,同时避免踩雷,踩到一个雷即全盘皆输,其胜利条件就是点开所有不是地雷的格子。
1.2游戏规则的描述
扫雷规则也是非常简单的,在确定大小的矩形雷区中随机布置一定数量的地雷,而你的目标就是避开这些雷,打开其他所有格子,(初级为9x9个方块10个雷,中级为16x16个方块40个雷,高级为16x30个方块99个雷,自定义级别可以自己设定雷区大小和雷数,但是雷区大小不能超过24*30),我们需要尽快找出雷区中的所有不是地雷的方块,而且不许踩到地雷。
网页版扫雷游戏
2.游戏实现思路
数据结构的思路分析:
首先,我们需要一个结构来实现存储游戏的状态,比如有棋盘,雷的位置,已标记的位置。
如果我们需要的在99的棋盘上布置雷的信息和排查雷的信息,那么我们就要创建一个99的数组(扫雷游戏的棋盘是一个多维数组)来存放这些信息,而我们只需关注棋盘和雷的变化即可
3.代码的实现
对于代码的实现,首先,我们要对这些二维数组进行初始化,创建函数菜单,棋盘的设置,雷的布置,排查雷
3.2创建菜单函数
3.3棋盘的设置
char mine[ROWS][COLS] = { 0 };
char show[ROWS][COLS] = { 0 };
-
char mine[ROWS][COLS] = { 0 };
声明mine
是二维字符数组。数组的维度由ROWS
和COLS
宏(通常代表行数和列数)定义。这意味着数组mine
会有ROWS
行,每行有COLS
个元素。数组中的所有元素都被初始化为字符0
。在扫雷游戏中,这个数组可能会用来表示游戏场地的底层状态,其中每个元素可以用来标记某个位置是否有地雷(例如,用’0’表示没有地雷,其他字符表示有地雷或地雷数量等)。 -
char show[ROWS][COLS] = { 0 };
类似地,这一行也声明show
是二维字符数组,其结构与mine
相同,同样有ROWS
行和COLS
列,所有元素初始值也为0
。在扫雷游戏中,show
数组可能用来表示玩家看到的游戏界面,即显示给玩家的场地状态。初始化为0
可能意味着所有格子最初对玩家来说都是隐藏的或者标记为未探索。随着游戏进行,这个数组会根据玩家的选择更新,显示出实际的数字或地雷标志等。
3.4初始化
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 (j = 0; j < cols; j++) {
arr[i][j] = set;
}
}
}
//
InitBoard(mine, ROW, COLS,'0');//初始化为0
InitBoard(show, ROW, COLS,'*');//初始化为*
3.5打印棋盘
void DisplayBoard(char arr[ROWS][COLS], int row, int col)
{
int i = 0;
//打印列
printf("------扫雷游戏------\n");
//打印'0'和'*'的时候,把它们分成两部分
for (i = 0; i <= col; i++) {
printf("%d ", i);
}
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");
}
}
3.6雷的布置
void SetMine(char arr[ROWS][COLS], int row, int col)
{
int count = EASY_COUNT;
while (count)
//count要大于等于10
{
int x = rand() % row + 1;//让rand生成随机值
int y = rand() % col + 1;
if (arr[x][y] == '0') {
arr[x][y] = '1';
count--;
}
}
}
3.7雷的排查
void FindMine(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_COUNT)
{
printf("请输入要排查的坐标\n");
scanf_s("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (show[x][y] == '*') {
if (mine[x][y] == '1')
{
printf("很遗憾,你被炸死了\n");
DisplayBoard(mine, ROW, COL);
break;
}
else
{
//该坐标不是雷,就得统计坐标周围有几个雷
int count = GetMineCount(mine, x, y);
show[x][y] = count + '0';
DisplayBoard(show, ROW, COL);
win++;
}
}
else
{
printf("该坐标已经排查,请重新输入坐标\n");
}
}
else
{
printf("坐标非法,请重新输入\n");
}
}
if (win == row * col - EASY_COUNT) {
printf("恭喜你,排雷成功\n");
DisplayBoard(mine, ROW, COL);
}
}
4.完整的代码
4.1头文件<game.h>
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define ROW 9//行
#define COL 9//列
#define ROWS ROW+2
#define COLS COL+2
#define EASY_COUNT 10
//棋盘初始化的函数声明
void InitBoard(char arr[ROWS][COLS], int rows, int cols, char set);
//打印棋盘的函数声明
void DisplayBoard(char arr[ROWS][COLS],int row,int col);
//布置雷的函数声明
void SetMine(char arr[ROWS][COLS],int row,int col);
//排查雷的函数声明
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
4.2源文件<game.c>
#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 (j = 0; j < cols; j++) {
arr[i][j] = set;
}
}
}
void DisplayBoard(char arr[ROWS][COLS], int row, int col)
{
int i = 0;
//打印列
printf("------扫雷游戏------\n");
for (i = 0; i <= col; i++) {
printf("%d ", i);
}
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");
}
}
void SetMine(char arr[ROWS][COLS], int row, int col)
{
int count = EASY_COUNT;
while (count)
//count要大于等于10
{
int x = rand() % row + 1;
int y = rand() % col + 1;
if (arr[x][y] == '0') {
arr[x][y] = '1';
count--;
}
}
}
static int GetMineCount(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;
}
void FindMine(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_COUNT)
{
printf("请输入要排查的坐标\n");
scanf_s("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (show[x][y] == '*') {
if (mine[x][y] == '1')
{
printf("很遗憾,你被炸死了\n");
DisplayBoard(mine, ROW, COL);
break;
}
else
{
int count = GetMineCount(mine, x, y);
show[x][y] = count + '0';
DisplayBoard(show, ROW, COL);
win++;
}
}
else
{
printf("该坐标已经排查,请重新输入坐标\n");
}
}
else
{
printf("坐标非法,请重新输入\n");
}
}
if (win == row * col - EASY_COUNT) {
printf("恭喜你,排雷成功\n");
DisplayBoard(mine, ROW, COL);
}
}
4.3源文件<test .c>
#include "game.h"
void menu() {
printf("********************\n");
printf("***** 1.play *****\n");
printf("***** 0.exit *****\n");
printf("********************\n");
}
void game() {
char mine[ROWS][COLS] = { 0 };
char show[ROWS][COLS] = { 0 };
InitBoard(mine, ROW, COLS,'0');
InitBoard(show, ROW, COLS,'*');
SetMine(mine,ROW,COL);
DisplayBoard(mine, ROW, COL);
DisplayBoard(show, ROW, COL);
FindMine(mine, show, ROW, COL);
}
void test() {
int put = 0;
srand((unsigned int)time(NULL));
do
{
menu();
printf("请选择:>");
scanf_s("%d", &put);
switch (put) {/
case 1:
game();
break;
case 0:
printf("游戏结束,退出游戏\n");
break;
default:
printf("选择错误,请重新选择\n");
break;
}
} while (put);
}
int main() {
test();
return 0;
}