C语言扫雷小游戏实现解析--一看到底

目录

1.游戏及相关规则介绍 

扫雷游戏的基本规则

2.游戏实现 

2.1游戏实现简单分析

2.2游戏基本框架搭建 

2.2.1 雷场创建及其初始化

2.2.2  布置雷 

2.2.3  排查雷 

3.游戏源代码 

3.1test.c文件

3.2   game.c文件 

3.3头文件


1.游戏及相关规则介绍 

扫雷游戏作为一种老少咸宜的益智游戏,它的游戏目标十分简单,就是要求玩家在最短的时间内,根据点击格子之后所出现的数字来找出所有没有炸弹的格子,同时在找的时候要避免点到炸弹,一旦踩到炸弹则游戏结束。即玩家需要找到雷区中所有不是地雷的方格,同时避免踩到地雷

扫雷游戏的基本规则

  • 方格数字是几,就代表周围有几个炸弹

数字是1,说明周围有1个炸弹;数字是2,说明周围有2个炸弹;数字是5,说明周围有5个炸弹。

周围指的是3x3的区域,也就是9个小方格的区域内的炸弹数,在看周围区域的时候,将数字2.放在9个小方格的正中间。

2.游戏实现 

2.1游戏实现简单分析

我们需要点开一个地方,如果是雷就结束游戏,如果不是雷就显示周围八个坐标雷的数量的总和

这里使用双雷场实现

一个用于保存放置好的雷的信息

一个用于保存排查雷的信息

看图片说明:

1.操作雷场使用1作为雷,使用字符‘0’作为非雷的好处是:便于计算坐标周围雷的数量,直接相加。 

2.我们思考一下,如果我们9x9的雷场上操作坐标为9.9的位置就是上图红色圆圈的坐标,是不是意味着要计算周围八个坐标,这个时候就会产生数组越界的情况,那么我们的解决办法是将实际雷场扩大一圈,9x9的雷场变为11x11,实际操作和打印的雷场还是9x9,实际操作雷场和客户端显示雷场都改变,是为了相对应,防止重复的坐标转化计算。

2.2游戏基本框架搭建 

三个文件

test.c 作为程序入口

game.c 作为函数的实现文件

game.h 作为函数名和公用资源的概括

2.2.1 雷场创建及其初始化

这里我们需要初始化一下雷场。首先将两个雷场初始化为无雷状态。

对于实际存放保存雷的数组来说:

字符1表示是雷    字符0表示是非雷

对于存放排查雷的信息的数组来说:

字符*表示是雷    字符#表示是非雷

这里两个个巧妙的点

1.宏定义了ROWS 和COWS来控制雷场的大小可以很方便的更改

2.初始化函数设置参数的时候,设置了一个字符参数方便后台游戏设计人员更改雷的样式,也方便操作两个雷场的不同形式的雷的设置。

2.2.2 打印雷场,设置打印样式

通过for循环来实现雷场的打印,由于展现的雷场是9*9布局的这里传参传的是COW和ROW

 我们来看一下实现效果,可以检验一下雷场的初始化情况:

这个是:保存实际放置雷1信息的雷场

这是保存排雷信息的雷场: 

2.2.2  布置雷 

布置雷的方法:

1.产生随机小于行数的横坐标,产生随机小于列的纵坐标,来实现布置雷的位置的随机化

2.提前设置好要布置的雷的数量 

我们布置10颗雷看一下

我们看一下布置效果:

 这里雷的数量可以修改为宏,这样就可以简便的更改雷的数量了

2.2.3  排查雷 

思路:玩家输入坐标,先判断一下坐标是否在雷场范围内,再判断是否是雷,如果是雷就提示被炸死,游戏结束。如果不是雷就显示周围八个坐标雷的数量。

判断输赢:当玩家查找了除了雷以外的所有点位坐标都没有踩雷,此时游戏结束玩家排雷成功游戏结束,我们看一下实现代码:

 判断输赢代码:

计算返回周围八个坐标雷的数量的代码:

至此功能游戏基本实现,为了测试方便我们在雷场放置80个雷,我们看一下实现效果:
 此时只有(8 4)坐标不是雷我们试一下:

这里这个扫雷小游戏实现基本完成但是功能不算太完善,考试完后我会继续更改一下,包括雷场无雷的连续展开的递归实现,都会后面继续补充完整,我现在把雷设置为10个的源代码放在这里,大家可以先试玩一下体验效果,对没有做好的地方提出宝贵意见非常高兴能和大家一起交流学习成长。源代码我放在了了最后,大家一定要分文件拷贝使用:

3.游戏源代码 

3.1test.c文件

#include"game.h"




void game()
{
	char Setpoint[ROWS][COWS] = { 0 };//存放布置好的雷
	char Showpoint[ROWS][COWS] = { 0 };//存放排查出的雷的信息
	//初始化一下雷场
	Firstbord(Setpoint,ROWS,COWS,'0');
	Firstbord(Showpoint, ROWS, COWS, '#');
	//打印一下雷场
	//Display(Setpoint, ROW, COW);
	Display(Showpoint, ROW, COW);
	//布置雷
	Setmybord(Setpoint, ROW, COW);
	//Display(Setpoint, ROW, COW);
	//排查雷
	Find(Setpoint, Showpoint, ROW, COW);
}



int main()
{


	int input = 0;
	do
	{
		srand((unsigned int)time(NULL));
		menu();
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("扫雷开始\n");
			game();
			break;
		case 0:
			printf("游戏退出\n");
			break;
		default:
			printf("选择错误请重新输入\n");
			break;

		}

	} while (input);
	return 0;
}

3.2   game.c文件 

#include"game.h"

void menu()
{
	printf("--------------------\n");
	printf("|                  |\n");
	printf("|   1.开始游戏     |\n");
	printf("|   0.游戏退出     |\n");
	printf("|                  |\n");
	printf("--------------------\n");
	printf("请选择>\n");
}//菜单函数

//初始化雷场函数
void Firstbord(char arr[ROWS][COWS], int rows, int cows, char set)
{
	int i = 0;
	for (i = 0; i < rows; i++)
	{
		int j = 0;
		for (j = 0; j < cows; j++)
		{
			arr[i][j] = set;
		}
	}

}

//打印雷场
void Display(char arr[ROWS][COWS], int row, int cow)
{
	int i = 0;
	for (i = 1; i <= row; i++)
	{
		printf("-------------------------------------\n");
		printf("|");
		int j = 0;
		for (j = 1; j <= cow; j++)
		{
			printf(" %c |", arr[i][j]);
		}
		printf("\n");
		
	}
	printf("-------------------------------------\n");
}
//布置雷
void Setmybord(char bord[ROWS][COWS], int row, int cow)
{
	int count = EASY_COUNT;//雷的数量
	while (count)
	{
		int x = rand() % row + 1;
		int y = rand() % cow + 1;
		//判断一下这个坐标是否被放置过雷,没有才放雷
		if (bord[x][y] == '0')
		{
			bord[x][y] = '1';
			count--;
		}
	}
}
//排查雷

int Getcount(char minebord[ROWS][COWS], int i, int j)
{
	//把周围八个坐标进行相加就行这就是用字符1和0表示的好处return
	return (minebord[i + 1][j] + minebord[i - 1][j] + minebord[i][j + 1] + minebord[i][j - 1] +
		minebord[i - 1][j - 1] + minebord[i - 1][j + 1] + minebord[i + 1][j - 1] + minebord[i + 1][j + 1]-8*'0');
}
void Find(char mine[ROWS][COWS], char show[ROWS][COWS], int row, int cow)
{
	int x = 0;
	int y = 0;
	int win = 0;
	while (win<row*cow-EASY_COUNT)
	{
		printf("请输入要排查的坐标:》\n");
		scanf("%d %d", &x,& y);
		if (x >= 1 && x <= row && y >= 1 && y <= cow)
		{
			if (mine[x][y] == '1')
			{
				printf("----------------\n");
				printf("|  你被炸死了  |\n");
				printf("|这都能被你玩死|\n");
				printf("|栓        Q   |\n");
				printf("----------------\n");
				Display(mine, ROW, COW);
				break;
			}
			else
			{
				//改位置不是雷,统计这个坐标周围有多少个雷
				int count = Getcount(mine, x, y);
				show[x][y] = count + '0';//'1' 4,'0'
				Display(show, ROW, COW);
				win++;
			}

		}
		else
		{
			printf("坐标非法请重新输入\n");
		}
	}
	if (win == row * cow - EASY_COUNT)
	{
		printf("恭喜你,排雷成功\n");
		Display(mine, row, cow);
	}
}

3.3头文件

#define  _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define ROW 9
#define COW 9
#define ROWS (ROW+2)
#define COWS  (COW+2)
#define EASY_COUNT 10

void menu();
void Firstbord(char arr[ROWS][COWS], int rows, int cows, char set);//初始化雷场
void Display(char arr[ROWS][COWS],int row,int cow);//打印雷场
void Setmybord(char bord[ROWS][COWS], int row, int cow);//布置雷

  • 7
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值