资讯专栏INFORMATION COLUMN

C语言实现入门级小游戏——扫雷

nevermind / 952人阅读

摘要:上一期咱们用语言实现了三子棋的小游戏语言实现三子棋今天我们再来写个扫雷的游戏,说起扫雷,相信大家都不陌生,可能许多朋友还是玩扫雷的高手。

     上一期咱们用C语言实现了三子棋的小游戏  C语言实现三子棋 

     今天我们再来写个扫雷的游戏,说起扫雷,相信大家都不陌生,可能许多朋友还是玩扫雷的高手。

 

其实扫雷和三子棋有许多相似之处,都需要用到数组的知识。

  今天的扫雷也是相当有趣的

由于博主是一个编程学习的小白,所以这只是扫雷的初级版,此版本有一些功能还无法实现,在后续的学习中,我会持续更新,不断对这个小游戏进行优化,期待大家的关注,还有,这篇文章中若有错误或不当的地方,欢迎大家指正!  

关于这个扫雷项目的代码,欢迎访问我的gitee代码仓库:

https://gitee.com/living-amethyst/code2021/tree/master/test_11_09_mine%20clearance 

  让我们开始吧!

目录

一.游戏的整体思路

二.创建游戏菜单 

三.游戏主体的实现

1.创建棋盘(数组) 

2.初始化棋盘 

3.打印棋盘

4.布置雷

4.排查雷 

四.全部的代码 

五.关于游戏的改进的思考 


 


一.游戏的整体思路

为了让代码的可读性更高,思维性更强,我们需要创建三个文件来完成这个项目

  1. test.c   —— 测试游戏
  2. game.h—— 游戏函数的声明
  3. game.c—— 游戏函数的实现

 然后我们需要建立两个棋盘,为什么呢?

 

 我们先想一下扫雷的游戏规则,如图,如果我选中的方块不是雷,那么它上面就会显示一个数字,这个数字代表它以它为中心的这个3*3区域内(红色方框)地雷的个数,它的范围是0~8,我们初步的设想是:无雷的放数字0,有雷的放数字1

     但是如果我这个方块不是雷,显示它周围的雷的格式时,如果它的周围有一个雷,需要显示

数字1时 ,我们就会分不清这个1 是雷?还是排查出的周围雷的个数?所以我们需要建立两个棋盘

 一个棋盘用来存放布置好的雷的信息(这是游戏结束前不让玩家看到的)

 另一个棋盘存放排查好的雷的信息(这是游戏过程中玩家看到的)

还有一个问题

如果我们布置的棋盘是9*9的 

    当我们选择了排查这个位置的周围的雷的个数时,它的旁边就没有了,所以我们要将棋盘扩展为11*11

(但是打印时只打印9*9的棋盘 )

  如图,这样我们就能排查这格周围的地雷的个数了

我们具体这样操作

 

二.创建游戏菜单 

与之前的三子棋游戏一样,我们首先需要设置一个游戏菜单

   由于一进入游戏,我们首先就要看到菜单,所以这里我们采用do...while循环

我们的菜单需要实现的功能有:

  1. 游戏的进入
  2. 游戏的退出
  3.  非法输入的返回提示和说明
void menu(){	printf("************************/n");	printf("*****   1.play   *******/n");	printf("*****   0.exit   *******/n");	printf("************************/n"); }void test(){	int input = 0;	do	{		menu();		printf("请选择");		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;}

 

 这里我们创建了test函数和menu函数,为的是让逻辑更清晰,现在我们的菜单部分就完成了

对于这个游戏菜单,我们能实现的游戏功能有: 

  • 输入1进入游戏
  • 输入0退出游戏
  • 输入其他数字提示选择错错误,将重新输入

 

                                             这是菜单的运行效果

三.游戏主体的实现

1.创建棋盘(数组) 

//创建数组	char mine[ROWS][COLS] = { 0 };//存放布置好的雷的信息	char show[ROWS][COLS] = { 0 };//存放排查好的雷的信息

2.初始化棋盘 

我们把mine数组作为存放布置好的雷的信息的棋盘

       把show数组作为存放排查好的雷的信息棋盘 

我们用一个InitBoard函数来初始化这两个棋盘 

 看代码:

//函数的声明void InitBoard(char board[ROWS][COLS], int rows,int cols,char set);//函数的定义void InitBoard(char board[ROWS][COLS], int rows, int cols, char set){	int i = 0;	int j = 0;	for(i = 0;i < rows;i++)	{		for (j = 0;j < cols;j++)		{			board[i][j] = set;		}	}}//函数的调用//初始化mine数组为全字符"0"	InitBoard(mine,ROWS,COLS,"0");	//初始化show数组为全"*"	InitBoard(show,ROWS,COLS,"*");

我们把mine数组全部初始化为字符 " 0 "

       把show数组全部初识化为字符 " * " 

3.打印棋盘

我们与两个棋盘

其中 mine数组代表的棋盘时游戏结束后或者游戏测试人员才能看到的

另一个show数组代表的棋盘是玩家玩游戏时能看到的

我们上代码

//函数的定义void DisplayBoard(char board[ROWS][COLS], int row, int col);//函数的定义void DisplayBoard(char board[ROWS][COLS], int row, int col){	//1-9	int i = 0;	int j = 0;	printf("/n");	printf("---扫雷游戏---/n");	//打印列号	for (i = 0;i <= col;i++)	{		printf("%d ", i);	}	printf("/n");	for (i = 1;i <= row;i++)	{		printf("%d ", i);		for (j = 1;j <= col;j++)		{			printf("%c ", board[i][j]);		}		printf("/n");	}	}//函数的调用DisplayBoard(show, ROW, COL);//只打印9*9的内容

4.布置雷

下面我们就可以来布置雷啦,由于雷是随机布置的,于是我们就要用到rand函数 

srand((unsigned int)time(NULL));     //进行初始化
x = rand() % row+1;          //x的范围是1~9
y = rand() %  col+1;          //y的范围是1~9

下面看代码:

//函数的声明void SetMine(char mine[ROWS][COLS],int row,int col);//函数的定义void SetMine(char mine[ROWS][COLS], int row, int col){	//布置10个雷	int count = EASY_COUNT;	while (count)	{		//生产随机的下标		int x = rand() % row + 1;//范围1到9		int y = rand() % col + 1;		if (mine[x][y] == "0")		{			mine[x][y] = "1";			count--;		}	}}//函数的调用SetMine(mine, ROW, COL);

 

 我们加上mine棋盘的打印,并将它注释掉,这是为了方便我们测试游戏或这检查游戏出现的问题的

这里的EASY_COUNT是雷的个数,我们用define定义它

4.排查雷 

关于排查雷,我们是这样实现的:

  1. 输入排查雷的坐标
  2. 检查该坐标是不是雷
  •     (1)是雷    --> 很遗憾炸死了
  •     (0)不是雷  --> 统计坐标周围有几个雷-->存储排查雷的信息到show数组,游戏继续 

这里我们用了 get_mine_count  和  FindMine  两个函数

get_mine_count函数用来统计坐标周围有几个雷

看代码

//声明void FindMine(char mine[ROWS][COLS],char show[ROWS][COLS], int row, int col);//从mine中排查放到show中//排查雷int get_mine_count(char mine[ROWS][COLS], 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+1] +		mine[x + 1][y] +		mine[x][y + 1] +		mine[x - 1][y + 1] - 8 * "0";}void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col){	//1.输入排查雷的坐标	//2.检查该坐标是不是雷	//(1)是雷    --> 很遗憾炸死了	//(0)不是雷  --> 统计坐标周围有几个雷-->存储排查雷的信息到show数组,游戏继续	int x = 0;	int y = 0;	int win = 0;	while (win= 1 && x <= col && y >= 1 && y <= row)		{			if (mine[x][y] == "1")			{				printf("很遗憾,你被炸死了/n");				DisplayBoard(mine, row, col);//把怎么被炸死的显现出来				break;			}			else			{				//不是雷的话统计(x,y)坐标周围有几个雷				int count = get_mine_count(mine, x, y);				show[x][y] = count+"0";				//显示排查出的信息				DisplayBoard(show, row, col);				win++;			}		}		else		{			printf("坐标不合法,请重新输入/n");		}	}	if (win == row * col - EASY_COUNT)	{		printf("恭喜你,排雷成功!");		DisplayBoard(mine, row, col);	}	}//调用FindMine(mine,show,ROW,COL);

 这里有几个需要说明的点:

1.

 这里函数有两个形参,是为了从mine中排查然后放到show中

2.

 

这些代表查找的坐标的周围其他格子的坐标

3.由于我们在棋盘中存放的是字符 "0 "和字符 "1" 

我们先看一下 ASCII码 表

 

 我们可以发现"0" "1" "2"这些字符的ASCII码值都是连续的我们想显示出排查格子周围雷的个数,需要先将字符"0","1","2"...转化为数字 0,1 ,2,3...

我们只需要把每个字符减去一个"0",它的ASCII码值是48就可以了,看看我们是如何操作的吧:

 之后再转化成字符的形式存到数组中

4.我们还要判断玩家输入坐标的合法性:

 

四.全部的代码 

game.h—— 游戏函数的声明

#pragma once#include#include#include#define ROW 9#define COL 9#define EASY_COUNT 10#define ROWS  ROW+2#define COLS  COL+2//初始化棋盘void InitBoard(char board[ROWS][COLS], int rows,int cols,char set);//打印棋盘void DisplayBoard(char board[ROWS][COLS], int row, int col);//布置雷void SetMine(char mine[ROWS][COLS],int row,int col);//排查雷void FindMine(char mine[ROWS][COLS],char show[ROWS][COLS], int row, int col);

 

 game.c—— 游戏函数的实现

#define _CRT_SECURE_NO_WARNINGS#include"game.h"//初始化void InitBoard(char board[ROWS][COLS], int rows, int cols, char set){	int i = 0;	int j = 0;	for(i = 0;i < rows;i++)	{		for (j = 0;j < cols;j++)		{			board[i][j] = set;		}	}}//打印棋盘void DisplayBoard(char board[ROWS][COLS], int row, int col){	//1-9	int i = 0;	int j = 0;	printf("/n");	printf("---扫雷游戏---/n");	//打印列号	for (i = 0;i <= col;i++)	{		printf("%d ", i);	}	printf("/n");	for (i = 1;i <= row;i++)	{		printf("%d ", i);		for (j = 1;j <= col;j++)		{			printf("%c ", board[i][j]);		}		printf("/n");	}	}//布置雷void SetMine(char mine[ROWS][COLS], int row, int col){	//布置10个雷	int count = EASY_COUNT;	while (count)	{		//生产随机的下标		int x = rand() % row + 1;//范围1到9		int y = rand() % col + 1;		if (mine[x][y] == "0")		{			mine[x][y] = "1";			count--;		}	}}int get_mine_count(char mine[ROWS][COLS], 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+1] +		mine[x + 1][y] +		mine[x][y + 1] +		mine[x - 1][y + 1] - 8 * "0";}//排查雷void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col){	//1.输入排查雷的坐标	//2.检查该坐标是不是雷	//(1)是雷    --> 很遗憾炸死了	//(0)不是雷  --> 统计坐标周围有几个雷-->存储排查雷的信息到show数组,游戏继续	int x = 0;	int y = 0;	int win = 0;	while (win= 1 && x <= col && y >= 1 && y <= row)		{			if (mine[x][y] == "1")			{				printf("很遗憾,你被炸死了/n");				DisplayBoard(mine, row, col);//把怎么被炸死的显现出来				break;			}			else			{				//不是雷的话统计(x,y)坐标周围有几个雷				int count = get_mine_count(mine, x, y);				show[x][y] = count+"0";				//显示排查出的信息				DisplayBoard(show, row, col);				win++;			}		}		else		{			printf("坐标不合法,请重新输入/n");		}	}	if (win == row * col - EASY_COUNT)	{		printf("恭喜你,排雷成功!");		DisplayBoard(mine, row, col);	}	}

 test.c   —— 测试游戏 

#define _CRT_SECURE_NO_WARNINGS#include"game.h"void menu(){	printf("**********************/n");	printf("*****  1.play  *******/n");	printf("*****  0.exit  *******/n");	printf("**********************/n");}void game(){	//创建数组	char mine[ROWS][COLS] = { 0 };//存放布置好的雷的信息	char show[ROWS][COLS] = { 0 };//存放排查好的雷的信息	//初始化mine数组为全字符"0"	InitBoard(mine,ROWS,COLS,"0");	//初始化show数组为全"*"	InitBoard(show,ROWS,COLS,"*");	//打印棋盘		DisplayBoard(show, ROW, COL);//只打印9*9的内容	//布置雷	SetMine(mine, ROW, COL);	/*DisplayBoard(mine, ROW, COL);*/	//这是不给玩家看到的	//排查雷	FindMine(mine,show,ROW,COL);//从mine中排查放到show中}void test(){	int input = 0;	srand((unsigned int)time(NULL));	do	{		menu();		printf("请选择:/n");			scanf("%d", &input);			switch (input)			{			case 1:				//扫雷				game();				break;			case 0:				break;			default:				printf("选择错误");				break;			}	} while (input);}int main(){	test();	return 0;}

好了,这样我们就把扫雷游戏编写完成了

五.关于游戏的改进的思考 

 如果你玩过正宗的扫雷游戏,那你肯定知道,扫雷游戏还有两个功能:

  1. 如果不是雷并且周围没有雷-->展开一片
  2. 如果我们确定哪个位置我们可以标记雷

这就是我们以后给这个游戏的优化方案

其中第一个功能我们需要使用递归实现

这些都会再以后更新,欢迎持续关注 !

  

 

 

 

 

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/123065.html

相关文章

  • C语言入门扫雷游戏C语言实现

    摘要:条消息语言入门三子棋语言实现详细版的博客博客条消息语言入门三子棋语言实现详细版的博客博客我们将雷盘初始化为统一的符号。 目录 1.原理简介 2.分布目标及代码实现 3.总结 1.原理简介  首先我们需要一个空的雷盘,在其中随机埋入十枚雷,当我们排这颗雷时,若此位置为雷,则游戏失败,若不...

    caige 评论0 收藏0
  • C语言/入门游戏扫雷完整版(包含标记,安全保护及展开)

    摘要:有雷则返回雷数难度设置其实实现思路比较简单,可以再设置和。 知识提要(自主编写游戏所需要的知识): 1.函数的基本实现; 2.二维数组; 目录 扫雷 1.基本界面的实现 2.初始化棋盘(二维数组) 3.棋盘的打印 4.布置雷 5.安全保护 6.雷数显示 7.排查雷 8.标记雷 9.展开 10...

    0x584a 评论0 收藏0
  • [ C语言 ] 扫雷 ------> 用C语言实现game2

    摘要:函数游戏菜单请选择扫雷游戏退出游戏选择错误解析函数内部利用时间戳,形成随机数,主要目的是实现游戏中地雷的随机埋放。 前言 本篇文章使用C语言实现简单小游戏---扫雷。(文章最后有完整代码链接) 想必大多数人都玩过或者了解过扫雷的游戏规则,但是在这里,我们在一起重温一下扫雷的游戏规则,也更好...

    I_Am 评论0 收藏0
  • C语言实现游戏】(二)扫雷(递归实现排雷)

    摘要:玩家选择开始游戏后,出现雷盘,并且随机布置雷。雷盘的数组大小为,方便计算扫雷时周围雷的数量,并防止数组越界。放置布置的雷的信息放置排查出雷的信息初始化雷盘初始化展示界面打印展示界面效果如下布置雷随机在数组中让十个变成作为雷。 目录 前言 一、游戏思路 二、游戏框架 1.菜单界面 1.菜单:...

    U2FsdGVkX1x 评论0 收藏0
  • 扫雷游戏C语言实现

    摘要:写在前面我们已经写过了三子棋小游戏肯定没玩过瘾,我们再写个扫雷小游戏吧目录写在前面认识游戏游戏规则游戏框架游戏实现效果展示全部代码文件文件文件认识游戏相信大家对扫雷都不陌生每台电脑必备的小游戏游戏规则就是在规定的时间将 ...

    Coding01 评论0 收藏0

发表评论

0条评论

nevermind

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<