目录
一、游戏介绍
相信大家应该都玩过扫雷游戏吧,没玩过也没有关系,我先来给大家介绍一下扫雷游戏的玩法:
1、胜利条件:这个游戏的目标就是在给定大小的棋盘上找出所有没有地雷的格子(期间不能踩雷,踩雷则输)后胜利。
2、游戏细节:
1.每点击一个格子,周围都会出现一些数字,这些数字代表周围8个格子中地雷的数量。
2.棋盘上的一些格子中有地雷,翻开后会有图标,而其他格子被翻开后是空白的。
图中所给的是9*9的棋盘,而我们现在要实现的也是这样一个9*9棋盘的扫雷游戏。
(我在本篇文章末尾放了一个在线扫雷的链接,各位有兴趣的可以玩一下)
二、设计思路
1、文件创建
首先,我们要分别创建两个源文件,分别为test.c和game.c,然后再创建一个头文件,我把它取名为game.h。
2、主函数部分(test.c中)
#include "game.h"//#include<stdio.h>在game.h中
int main()
{
test();
return 0;
}
3、菜单打印(game.c中)
//游戏菜单
void meun() {
printf("*******************\n");
printf("***** 1.play ******\n");
printf("***** 0.exit ******\n");
printf("*******************\n");
}
在这里,我们采用输入1为继续玩,输入0为结束游戏的方式控制游戏的执行。
4、初始化棋盘(game.c中)
//初始化棋盘
void Reinitboard(char board[ROWS][COLS], int rows, int cols, char set) {
int i = 0, j = 0;
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++) {
board[i][j] = set;
}
}
}
注意:这里的ROWS和COLS以及下文的ROW和COL均为在game.h中定义的宏。
//棋盘真实大小
#define ROW 9
#define COL 9
//棋盘定义大小
#define ROWS ROW+2
#define COLS COL+2
5、打印棋盘(game.c中)
//打印棋盘
void Printboard(char board[ROWS][COLS], int row, int col) {
int i = 0, j = 0;
printf("-------扫雷-------\n");//分割线
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");
}
printf("-------扫雷-------\n");//分割线
}
打印效果如图:
6、安放雷(game.c中)
//安放雷
void SetMine(char board[ROWS][COLS], int row, int col) {
int x = 0;
int y = 0;
int count = NUMBER;
while (count) {
x = rand() % row + 1;
y = rand() % col + 1;//生成随机数
if (board[x][y] != '1') {//判断是否已安置地雷
board[x][y] = '1';
count--;
}
}
}
在这里,我们要设置两个数组,一个是埋雷数组(无雷为0,有雷为1。注意:都是字符,不是数字) ,另一个是展示数组,主要向我们展示游戏进程(未被翻的位置用 * 表示)。埋雷数组用mine表示,展示数组用show表示。同时,安放雷的过程中,我们还要用到几个函数:
1.rand()函数
rand()不是真的随机数,因其周期特别长,故在一定的范围里可看成是随机的。
rand()返回一随机数值的范围在0至RAND_MAX 间。RAND_MAX的范围最少是在32767之间(int)。0~RAND_MAX每个数字被选中的机率是相同的。用户未设定随机数种子时,系统默认的随机数种子为1。rand()产生的是伪随机数字,每次执行时是相同的;若要不同,用函数srand()初始化它。所在头文件: stdlib.h
2.srand()函数
srand()用来设置rand()产生随机数时的随机数种子。
参数seed必须是个整数,通常可以利用time(0)的返回值或NULL来当做seed。
如果每次seed都设相同值,rand()所产生的随机数值每次就会一样。所在头文件: stdlib.h
3.time()函数
time函数所返回的时间是自1970年1月1日00:00:00以来的数秒。()里如果不为空,那么函数会返
回当前时间的差值,并将这个值存储在参数所指向的变量中。()里如果是NULL,就只返回时间
的差值。所在头文件:time.h
同时,代码中的NUMBER为在game.h中定义的宏,代表雷的个数。
//雷的个数
#define NUMBER 10
7、排查雷 (game.c中)
完成了安放雷的函数代码,接下来就要搞定排查雷的问题。
//排查雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) {
int x = 0;
int y = 0;
int cnt = 0;
while (cnt<ROW*COL-NUMBER) {
printf("请输入要排查的位置:");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col) {//限定坐标范围,防止越界
if (mine[x][y] != '1') {//判断雷
int number = GetMine(mine, x, y);//数雷函数
show[x][y] = number + '0';//将数字转化为字符
Printboard(show, ROW, COL);//重新打印展示棋盘
cnt++;
}
else {
Printboard(mine, ROW, COL);
printf("很遗憾,你踩雷了,游戏结束!\n");
printf("菜就多练!\n");
break;
}
}
else {
printf("该位置错误(x(1到9),y(1到9)),请重新输入!\n");
}
}
if (cnt == ROW * COL - NUMBER) {//判断是否胜利
printf("恭喜你,靠实力排雷成功!\n");
}
}
8、数雷(game.c中)
上述代码中的数雷函数如下:
//数雷
int GetMine(char mine[ROWS][COLS], int x, int y) {
int i = 0;
int j = 0;
int count = 0;
for (i = -1; i <= 1; i++) {
for (j = -1; j <= 1; j++) {
count += (mine[x + i][y + j] - '0');
}
}
return count;
}
这里的count表示雷的数量,又因为mine中的每个元素,不是‘1’就是‘0’,它们与‘0’相减,就得到了雷的数量。
9、游戏测试(game.c中)
//游戏测试
void test() {
void meun();
meun();
int num = 0;
srand((unsigned int)time(NULL));
do {
printf("请输入:>> ");
scanf("%d", &num);
switch (num) {
case 1:
game();
break;
case 0:
printf("退出游戏");
break;
default:
printf("输入错误,请重新输入!");
break;
}
} while (num);//num控制循环的结束
}
三、完整代码
1、test.c
#include "game.h"
int main()
{
test();
return 0;
}
2、game.c
#include "game.h"
//游戏菜单
void meun() {
printf("*******************\n");
printf("***** 1.play ******\n");
printf("***** 0.exit ******\n");
printf("*******************\n");
}
//游戏测试
void test() {
void meun();
meun();
int num = 0;
srand((unsigned int)time(NULL));
do {
printf("请输入:>> ");
scanf("%d", &num);
switch (num) {
case 1:
game();
break;
case 0:
printf("退出游戏");
break;
default:
printf("输入错误,请重新输入!");
break;
}
} while (num);
}
//游戏实现
void game() {
char mine[ROWS][COLS] = { 0 };
char show[ROWS][COLS] = { 0 };
//初始化棋盘
Reinitboard(mine, ROWS, COLS, '0');
Reinitboard(show, ROWS, COLS, '*');
//打印棋盘
//Printboard(mine, ROW, COL);
Printboard(show, ROW, COL);
//安放雷
SetMine(mine, ROW, COL);
//排查雷
FindMine(mine, show, ROW, COL);
}
//初始化棋盘
void Reinitboard(char board[ROWS][COLS], int rows, int cols, char set) {
int i = 0, j = 0;
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++) {
board[i][j] = set;
}
}
}
//打印棋盘
void Printboard(char board[ROWS][COLS], int row, int col) {
int i = 0, j = 0;
printf("-------扫雷-------\n");
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");
}
printf("-------扫雷-------\n");
}
//安放雷
void SetMine(char board[ROWS][COLS], int row, int col) {
int x = 0;
int y = 0;
int count = NUMBER;
while (count) {
x = rand() % row + 1;
y = rand() % col + 1;
if (board[x][y] != '1') {
board[x][y] = '1';
count--;
}
}
}
//排查雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) {
int x = 0;
int y = 0;
int cnt = 0;
while (cnt<ROW*COL-NUMBER) {
printf("请输入要排查的位置:");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col) {
if (mine[x][y] != '1') {
int number = GetMine(mine, x, y);
show[x][y] = number + '0';
Printboard(show, ROW, COL);
cnt++;
}
else {
Printboard(mine, ROW, COL);
printf("很遗憾,你踩雷了,游戏结束!\n");
printf("菜就多练!\n");
break;
}
}
else {
printf("该位置错误(x(1到9),y(1到9)),请重新输入!\n");
}
}
if (cnt == ROW * COL - NUMBER) {
printf("恭喜你,靠实力排雷成功!\n");
}
}
//数雷
int GetMine(char mine[ROWS][COLS], int x, int y) {
int i = 0;
int j = 0;
int count = 0;
for (i = -1; i <= 1; i++) {
for (j = -1; j <= 1; j++) {
count += (mine[x + i][y + j] - '0');
}
}
return count;
}
3、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 NUMBER 10
//游戏菜单
void meun();
//游戏测试
void test();
//游戏实现
void game();
//初始化棋盘
void Reinitboard(char board[ROWS][COLS], int rows, int cols, char set);
//打印棋盘
void Printboard(char board[ROWS][COLS], int row, int col);
//安放雷
void SetMine(char board[ROWS][COLS], int row, int col);
//排查雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
//数雷
int GetMine(char mine[ROWS][COLS], int x, int y);
在线扫雷游戏的链接:http://www.minesweeper.cn/
以上便是用c语言实现扫雷游戏的全部内容,感谢各位看官的观看,如本篇文章对你有所帮助,可以一键三连支持一下,感谢支持!!!