前言
1. 扫雷游戏的背景
扫雷游戏源于一个称为“华盛顿连锁”的猜数游戏,这个游戏最早出现在20世纪70年代初,在美国空军里盛行,后来这个游戏变成了一个电脑程序,称为Windows系统上的一个经典游戏。
2. 游戏亮点
电脑上扫雷游戏最大的亮点便是其中地雷的位置是随机分布的,每一盘游戏的地雷的位置都不一样,这种随机性增加了游戏的新颖感和玩家游玩时的刺激感。
代码实现
1. 游戏菜单制作
1.1 定义一个menu函数打印出游戏菜单
在玩游戏的时候我们都知道,游戏的开始界面会有游戏菜单,它会显示两个选项,分别是:1.玩游戏;2.退出游戏。
以下是游戏菜单代码:
void menu()
{
printf("----------------------\n");
printf("----- 1.play -----\n");
printf("----- 0.exit -----\n");
printf("----------------------\n");
}
通过以上代码我们可以知道,它定义一个menu函数来实现打印出游戏菜单的效果,其中1.play代表玩游戏选项,0.exit代表退出游戏选项。
2. 游戏内容制作
1.1 定义一个game函数来实现扫雷游戏的内容
首先我们要明白扫雷游戏中需要有一个9*9的棋盘,并且棋盘中要有10个随机地雷,所以我们可以通过定义两个数组来实现存放布置的地雷和存放排查出的地雷的信息的效果,定义了上述两个数组之后要再定义两个函数来实现布置地雷和排查地雷两个操作,最后通过定义两个函数来实现初始化棋盘和打印棋盘两个操作。
以下是游戏内容的代码:
void game()
{
char mine[RS][CS];//存放布置好地雷的信息
char show[RS][CS];//存放排查出的地雷的信息
//1.初始化棋盘
InitBoard(mine, RS, CS, '0');//mine数组最开始全是'0'
InitBoard(show, RS, CS, '*');//show数组最开始全是'*'
//2.打印棋盘
DisplayBoard(show, R, C);
//3.布置地雷
SetMine(mine, R, C);
//4.排查地雷
FindMine(mine, show, R, C);
}
1.1.1 初始化棋盘函数的详细内容
把上述两个小节的复杂内容完成之后,我们开始进行简单的函数实现,首先我们要知道初始化棋盘的含义,一个9*9的棋盘需要9行9列,所以需要定义两个变量控制行和列的内容,还需要定义一个形参存储每个行列数组成的坐标。
以下是初始化棋盘函数的代码:
void InitBoard(char board[RS][CS], int rs, int cs, char set)
{
//i控制棋盘内的行数
int i = 0;
for (i = 0; i < rs; i++)
{
//j控制棋盘内的列数
int j = 0;
for (j = 0; j < cs; j++)
{
//定义一个形参set来存储棋盘内容
board[i][j] = set;
}
}
}
1.1.2 打印棋盘函数的详细内容
在编写打印棋盘函数内容的时候我们要明白需要的信息有排查出雷的信息和每行每列的信息。
以下是打印棋盘函数的代码:
void DisplayBoard(char board[RS][CS], int r, int c)
{
int i = 0;
printf("********扫雷游戏********\n");
//生成初始棋盘的列数
for (i = 0; i <= c; i++)
{
printf("%d ", i);
}
printf("\n");
//生成初始棋盘的行列内容
for (i = 1; i <= r; i++)
{
printf("%d ", i);
int j = 0;
for (j = 1; j <= c; j++)
{
printf("%c ", board[i][j]);
}
printf("\n");
}
printf("********扫雷游戏********\n");
}
1.1.3 布置地雷函数的详细内容
首先我们要知道在一个9*9棋盘里有10个地雷,并且这10个地雷都是随机分布的,所以需要一个rand函数来生成随机数,随机数模行数加一便是生成的随机行坐标,随机数模列数加一便是生成的随机列坐标,生成的随机行、列坐标用来布置地雷,有一个点需要注意的是没布置一个地雷,地雷数要减一,结构分析完成。
以下是布置地雷函数的代码:
void SetMine(char board[RS][CS], int r, int c)
{
//布置10个地雷
int count = 10;
//生成随机的坐标,布置地雷
while(count)
{
int x = rand() % r + 1;
int y = rand() % c + 1;
if(board[x][y] == '0')
{
board[x][y] = '1';
count--;
}
}
}
1.1.4 排查地雷函数的详细内容
首先我们需要知道排查地雷是需要定位棋盘内的坐标位置的,所以需要布置好地雷的信息和排查出地雷的信息,需要注意的点是,如果该坐标位置不是地雷,那就统计这个坐标周围有几个地雷,所以我们需要定义一个函数来实现统计一个坐标位置周围有几个地雷的操作。
然后我们在排查地雷的过程中要明白,十个地雷终究会排查完,所以需要定义一个变量,当这个变量满足地雷被排查完的条件,则停止排查。
以下是排查地雷函数的代码:
void FindMine(char mine[RS][CS], char show[RS][CS], int r, int c)
{
int x = 0;
int y = 0;
int win = 0;
//当win < r * c - 10时,代表地雷还没全部排查完成,继续进入while循环排查
while (win < r * c - 10)
{
printf("请输入要排查的坐标:>");
scanf("%d %d", &x, &y);
//输入的坐标要满足第一个if内的条件
if (x >= 1 && x <= r && y >= 1 && y <= c)
{
if (mine[x][y] == '1')
{
printf("很遗憾,你被炸死了\n");
printf("\n");
DisplayBoard(mine, R, C);
break;
}
else
{
//该坐标位置不是地雷,就统计这个坐标周围有几个地雷
int count = GetMineCount(mine, x, y);
show[x][y] = count + '0';
DisplayBoard(show, R, C);
win++;
}
}
else
{
printf("坐标错误,请重新输入\n");
}
}
//当win == r * c - 10时代表10个地雷已经全部排查完成
if (win == r * c - 10)
{
printf("恭喜你,排雷成功\n");
DisplayBoard(mine, R, C);
}
}
之前我们说过当排查到的坐标位置不是地雷时,需要统计周边的地雷数,要完成这个操作需要再定义一个函数,函数包括布置地雷的信息和坐标信息。
以下是统计坐标周围地雷的代码:
int GetMineCount(char mine[RS][CS], int x, int y)
{
return(mine[x - 1][y] + mine[x - 1][y - 1] + mine[x][y - 1]
+ mine[x + 1][y - 1] + mine[x + 1][y] + mine[x + 1][y + 1] + mine[x][y + 1] +
mine[x - 1][y + 1] - 8 * '0');
}
3. 扫雷代码实现的总框架
在前两个章节我们分析了扫雷游戏所需要的各种操作,现在我们需要把上述操作进行归类,分出哪一些是头文件里的内容,哪些是源文件里的内容。
首先我们要知道扫雷游戏的实现需要一个声明扫雷游戏里操作函数的头文件(SaoLei_game.h),其次还需要一个说明头文件里函数的内容的源文件(SaoLei_game.c),最后需要一个测试扫雷游戏的源文件(text-1.c)。
由此可以进行扫雷各项操作函数的归类。
1.1 SaoLei_game.h的内容
首先我们要知道扫雷游戏的头文件里包括:扫雷游戏里地雷的数量、棋盘的行列数、棋盘行列数的标号、初始化棋盘函数的声明、打印棋盘函数的声明、布置地雷函数的声明以及排查地雷函数的声明。
以下是SaoLei_game.h的代码实现:
开头#pragma once的意思是写在头文件开头的编译指令,使得编译器能够自动帮我们实现“只编译一次该头文件”,从而避免了多次include该头文件导致的重复定义或声明问题。
1.2 SaoLei_game.c的内容
首先我们要知道该源文件里的内容是对SaoLei_game.h里所声明的函数进行定义,也就是对里面的函数进行详细说明。
以下是SaoLei_game.c的代码内容:
初始化棋盘函数
打印棋盘函数
布置地雷函数
统计坐标周围的地雷个数
排查地雷函数
在这个源文件中需要注意的是在文件开头需要写下#include "SaoLei_game.h",为什么呢,因为我们在该源文件中定义的函数是来自于上述头文件中的,所以需要用一个include来包含头文件。
1.3 text-1.c的内容
首先我们要知道实现扫雷游戏,需要一个测试源文件,而里面是需要头函数的来进行测试的,头函数里包括:提示输入游戏选项、用switch语句来进行三种选择操作,选择一是进入扫雷游戏,选择二是退出游戏,选择三是提示输入的选项错误,请重新选择;除了头函数里的内容,源文件里面也要包括:扫雷游戏的菜单内容、扫雷游戏的游戏内容。
以下是text-1.c的代码内容:
为什么要在开头加入#include "SaoLei_game.h"内容呢,这是因为我们测试扫雷游戏所需要的函数操作都存在了SaoLei_game.h头文件中,所以需要在开头声明头文件,用于测试扫雷游戏时调用里面的函数。(SaoLei_game.h的内容在前面的 3.扫雷代码实现的总框架 中的1.1小节讲到)
测试文件(text-1.c)里要注意的事项:
初始化棋盘操作要排在其他操作前,不可以颠倒顺序,如果颠倒顺序会出现乱码,导致程序运行错误。
总结
扫雷游戏的代码实现固然复杂,但可以通过对它的代码结构进行逐层分析来实现清晰编写,希望各位读者通过阅读本篇博客能够清楚地了解怎么编程实现扫雷游戏代码。
最后感谢各位读者的耐心观看,如有错误,尽情在评论区留言。