目录

一、游戏介绍

二、游戏设计

1、打印游戏菜单

 2.玩家需要进行选择

 3、游戏部分

4、布置地雷

 5、玩家排雷

6、判断玩家获胜

三、整体代码

test.c

game.c

game.h


一、游戏介绍

扫雷是一款十分有趣的游戏,能锻炼思维,打发时间。

首先想要写出这样的一个扫雷游戏,我们得先清楚他的规则:

1.游戏规则很简单,点击方格,如果是地雷,游戏失败,找到所有地雷游戏胜利

2.只要点开一个区域,就可以正式开始了。

Unity 地雷爆炸的力 地雷爆炸体育游戏_python

3.根据现有情况,判断出一定有雷的位置

4.最终找出所有雷

就拿最基础的9x9格子举例:当你点开一个格子的时候,里面会随机出现一个数字,而这个数字代表了该格子周围有多少颗炸弹,需要玩家有很强的逻辑推理能力,没错,你要推理出炸弹在哪里并避开它,每个难度下的炸弹数量不一样,当你把所有没有炸弹的格子都点开之后,雷就被排了,你就赢了

二、游戏设计

1、打印游戏菜单

Unity 地雷爆炸的力 地雷爆炸体育游戏_python_02

 2.玩家需要进行选择

这里利用do———while循环的方式来改进一下代码,玩家进入游戏需要先看到游戏菜单在进行选择,可以利用函数的形式将代码拆分

void meau()
{
	printf("****************\n");
	printf("**** 1.开始 ****\n");
	printf("**** 0.退出 ****\n");
	printf("****************\n");
}
void test()
{
	int input = 0;//创建一个临时变量
	do
	{
		meau();
		scanf("%d", &input);//玩家选择
		switch(input)//进行判断
		{
		case 1:
			printf("开始游戏\n");
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("请重新输入\n");
			break;
		}
	}
	while (input);//非零则继续循环
}

可以先执行以一下判断代码是否正确,然后继续进行下面代码的书写。

Unity 地雷爆炸的力 地雷爆炸体育游戏_c语言_03

 3、游戏部分

首先需要一个9*9的棋盘,可以利用二位数组来进行创建,在这里我们可以创建11*11的格子,

回想一下扫雷游戏的规则,比如这个3代表的是以3为中心的各自周围有3个雷。

Unity 地雷爆炸的力 地雷爆炸体育游戏_Unity 地雷爆炸的力_04

 如果雷在最角落呢?

 

Unity 地雷爆炸的力 地雷爆炸体育游戏_python_05

 像这样的话,我们需要判断图中圈出的1周围有多少颗雷,如果进行创建9*9的数组则会使用到数组下标越界,可能会使编译器报错。这是我们定义成比9*9大则可以解决这个问题。

这里采用定义常量的方法进行定义,方便修改常量的值。

Unity 地雷爆炸的力 地雷爆炸体育游戏_python_06

 准备工作都已经主备好了,便进行真正的操作吧。

将test()函数的   printf("开始游戏\n");    改为game()函数

Unity 地雷爆炸的力 地雷爆炸体育游戏_r语言_07

 创建game()函数后即先创建2个数组

其中mine用来存放地雷——————用0 \ 1 表示 1为地雷

show用来打印出周围有几颗雷——————用 * 来表示

//初始化
void initialize(char board[ROWS][COLS], int rows, int cols, char ret)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < rows; i++)
	{
		for (j = 0; j < cols; j++)
		{
			board[i][j] = ret;
		}
	}
}

//打印
void printf_game(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("\n");
	}
}

初始化后我们可以打印出来,一边检验是否达到我们理想的效果;

Unity 地雷爆炸的力 地雷爆炸体育游戏_python_08

 当然我们也可以将字符所属的行和列也打出来,方便玩家找到所对应的坐标。

//初始化
void initialize(char board[ROWS][COLS], int rows, int cols, char ret)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < rows; i++)
	{
		for (j = 0; j < cols; j++)
		{
			board[i][j] = ret;
		}
	}
}

//打印
void printf_game(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i <= row; i++)//打印行号
	{
		printf("%d ", i);
	}
	printf("\n");
	for (i = 1; i <= row; i++)//注意i=1;
	{
		printf("%d ", i);//打印列号
		for (j = 1; j <= col; j++)//注意j=1;
		{
			printf("%c ", board[i][j]);
		}
		printf("\n");
	}
}

效果如下

Unity 地雷爆炸的力 地雷爆炸体育游戏_r语言_09

4、布置地雷

怎么能随机生成一个数呢?

rand()函数可以帮助我们完成。

//布置雷
void layout(char mine[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int count = BOMB;//雷数
	while (count)
	{
		x = rand() % row + 1;//生成1~9的数
		y = rand() % col + 1;//生成1~9的数
			if ('0' == mine[x][y])//判断雷的坐标是否符合
			{
				mine[x][y] = '1';
				count--;
			}
	}
}

当然还需要加上在主函数中加上  srand((unsigned int)time(NULL));  和引头文件 #include<time.h>
 #include<stdlib.h>

这时来检查一下效果。

Unity 地雷爆炸的力 地雷爆炸体育游戏_人工智能_10

 5、玩家排雷

既然雷都已经布置好了,就该轮到到玩家进行排雷。

//排雷
void exclude(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int i = 0;//没有雷的坐标数量
	while (i<row*col- BOMB)//进行循环条件的限制
	{
		printf("请输入坐标\n");
		scanf("%d %d", &x, &y);
		//判断玩家输入的坐标是否在范围内
		if (x > 0 && x <= row && y > 0 && y <= col)
		{
			if ('1' == mine[x][y])//判断雷的坐标是否符合
			{
				printf("你被炸死了\n");
				printf_game(mine, ROW, COL);
				break;
			}
			else
			{
				//计算该坐标周围有几个雷
				int number = find(mine, x, y);
				show[x][y] = number+'0';
				printf_game(show, ROW, COL);
				i++;
			}
		}
		else
		{
			printf("坐标非法,请重新输入\n");
		}
	}
	if (i == row * col - BOMB)//当把没有雷的格子找完,判定玩家胜利
	{
		printf("排雷成功,玩家获胜\n");
		printf_game(show, ROW, COL);
	}
}

分两种情况,点到雷的地方则被炸死。点到无雷的地方则需要判断周围有几颗雷。

写 find(mine, x, y); 来判断周围有几颗雷。

int find(char mine[ROWS][COLS], int x, int y)
{
	return mine[x - 1][y - 1] + mine[x - 1][y] + 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';
}

其中加减一个字符零尤为重要。我们来回顾一下ASCII表

Unity 地雷爆炸的力 地雷爆炸体育游戏_r语言_11

 其中当一个整形2加上一个字符零的话,就会计算出一个字符型的2。

6、判断玩家获胜

if (i == row * col - BOMB)//当把没有雷的格子找完,判定玩家胜利
	{
		printf("排雷成功,玩家获胜\n");
		printf_game(show, ROW, COL);
	}

利用限制的条件,如果i=整个棋盘的格子数量减去雷的数量时,这是玩家便找到了所有的雷。则判定玩家获胜。

三、整体代码

test.c

#include"game.h"
//打印游戏菜单
void meau()
{
	printf("****************\n");
	printf("**** 1.开始 ****\n");
	printf("**** 0.退出 ****\n");
	printf("****************\n");
}

void game()
{
	//创建棋盘
	char mine[ROWS][COLS];//存放雷
	char show[ROWS][COLS];//表示雷

	//初始化
	initialize(mine, ROWS, COLS,'0');
	initialize(show, ROWS, COLS,'*');
	//打印
	//printf_game(mine, ROW, COL);
	printf_game(show, ROW, COL);
	//布置雷
	layout(mine, ROW, COL);
	//printf_game(mine, ROW, COL);
	//排雷
	exclude(mine, show, ROW, COL);
}
void test()
{
	srand((unsigned int)time(NULL));
	int input = 0;//创建一个临时变量
	do
	{
		meau();
		scanf("%d", &input);//玩家选择
		switch(input)//进行判断
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("请重新输入\n");
			break;
		}
	}
	while (input);//非零则继续循环
}

int main()
{
	打印游戏菜单
	test();
	return 0;
}

game.c

#include"game.h"

//初始化
void initialize(char board[ROWS][COLS], int rows, int cols, char ret)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < rows; i++)
	{
		for (j = 0; j < cols; j++)
		{
			board[i][j] = ret;
		}
	}
}

//打印
void printf_game(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i <= row; i++)//打印行号
	{
		printf("%d ", i);
	}
	printf("\n");
	for (i = 1; i <= row; i++)//注意i=1;
	{
		printf("%d ", i);//打印列号
		for (j = 1; j <= col; j++)//注意j=1;
		{
			printf("%c ", board[i][j]);
		}
		printf("\n");
	}
}

//布置雷
void layout(char mine[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int count = BOMB;//雷数
	while (count)
	{
		x = rand() % row + 1;//生成1~9的数
		y = rand() % col + 1;//生成1~9的数
			if ('0' == mine[x][y])//判断雷的坐标是否符合
			{
				mine[x][y] = '1';
				count--;
			}
	}
}

//寻找雷数
int find(char mine[ROWS][COLS], int x, int y)
{
	return mine[x - 1][y - 1] + mine[x - 1][y] + 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 exclude(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int i = 0;//没有雷的坐标数量
	while (i<row*col- BOMB)//进行循环条件的限制
	{
		printf("请输入坐标\n");
		scanf("%d %d", &x, &y);
		//判断玩家输入的坐标是否在范围内
		if (x > 0 && x <= row && y > 0 && y <= col)
		{
			if ('1' == mine[x][y])//判断雷的坐标是否符合
			{
				printf("你被炸死了\n");
				printf_game(mine, ROW, COL);
				break;
			}
			else
			{
				//计算该坐标周围有几个雷
				int number = find(mine, x, y);
				show[x][y] = number+'0';
				printf_game(show, ROW, COL);
				i++;
			}
		}
		else
		{
			printf("坐标非法,请重新输入\n");
		}
	}
	if (i == row * col - BOMB)//当把没有雷的格子找完,判定玩家胜利
	{
		printf("排雷成功,玩家获胜\n");
		printf_game(show, ROW, COL);
	}
}

game.h

#define ROW 9
#define COL 9

#define ROWS ROW+2
#define COLS COL+2

#define BOMB 10

#include<stdio.h>
#include<time.h>
#include<stdlib.h>

//初始化
void initialize(char board[ROWS][COLS], int row, int col, char ret);

//打印
void printf_game(char board[ROWS][COLS], int row, int col);

//布置雷
void layout(char mine[ROWS][COLS], int row, int col);

//排雷
void exclude(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);