Bootstrap

用C语言实现扫雷游戏

目录

一、游戏介绍 

二、设计思路

1、文件创建

2、主函数部分(test.c中) 

3、菜单打印(game.c中) 

4、初始化棋盘(game.c中) 

5、打印棋盘(game.c中)

6、安放雷(game.c中)

1.rand()函数

 2.srand()函数

3.time()函数

7、排查雷 (game.c中)

8、数雷(game.c中)

9、游戏测试(game.c中)

三、完整代码

1、test.c

2、game.c

3、game.h


一、游戏介绍 

相信大家应该都玩过扫雷游戏吧,没玩过也没有关系,我先来给大家介绍一下扫雷游戏的玩法:

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语言实现扫雷游戏的全部内容,感谢各位看官的观看,如本篇文章对你有所帮助,可以一键三连支持一下,感谢支持!!! 

 

 

 

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;