C语言小游戏的实现——扫雷(使用C语言基础语法)

news2024/12/23 17:42:01

 

前言

结合前边我们所学的C语言知识,本期我们将使用C语言实现一个简单的小游戏——扫雷


 

目录

前言

总体框架设计

多文件分装程序

各功能模块化实现

初始化棋盘

 棋盘打印

 

埋雷

 判赢与排雷

游戏逻辑安排

总结


 

总体框架设计

和三子棋相同,游戏开始时不需要任何判断与操作直接进入游戏(符合我们所学的do…while结构),然后再根据菜单选择,开始游戏和退出游戏,这部分的操作与三子棋较为类似,这里不再详细讲解(详请看三子棋那期博客)。

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

 菜单打印部分也是相同

void menu()
{
	printf("******************************\n");
	printf("*********   1.play   *********\n");
	printf("*********   0.exit   *********\n");
	printf("******************************\n");
}

多文件分装程序

当然根据之前的方法,我将程序分装到多文件,.h文件用于声明函数,test.c文件用于程序设计,game.c文件用于函数定义

注意:函数的定义和声明是不同的(详细请看函数那期内容)

函数声明(在.h文件中)

//初始化棋盘
void InitBoard(char board[ROWS][COLS], char set);

 函数定义(在函数实现.c文件中)

void InitBoard(char board[ROWS][COLS], char set)
{
}

各功能模块化实现

接下来是最重要的部分,game()游戏部分的实现。游戏开始首先我们需要布置棋盘,设置雷的个数,和三子棋有所不同,这里我们最好是创建两个二维数组来存放我们的棋盘信息,一个棋盘用于玩家下棋棋盘,另外一个用于存放雷的信息。

初始化棋盘

    InitBoard(mine,'0');//埋雷棋盘
	InitBoard(show,'*');//玩家棋盘

 棋盘初始化和二维数组初始化相同

void InitBoard(char board[ROWS][COLS], char set)//字符型变量用于接收传入的字符
{
	for (int i = 0; i < ROWS; i++) {//为了便于更改棋盘大小这里需要定义字符型常量
		for (int j = 0; j < COLS; j++) {
			board[i][j] = set;
		}
	}
}

 棋盘打印

棋盘的打印没有三子棋那么难,如果想要美化棋盘也是可以使用与三子棋结合的棋盘。

效果图如下:

bb23a7e453fe4ea5b1ed8885322e7a74.png

 这里我们采用上图的效果进行讲解

void DisPlaybroad(char board[ROWS][COLS])
{
	printf("------------------扫雷游戏------------------\n");//棋盘分割线
	printf("  ");                                           //与行打印对齐
	for (int i = 1; i <=COL; i++) {                         //打印列数序号1~9
		printf(" %d  ", i);
	}
	printf("\n");         //打印完一行及时换行
	printf("  -----------------------------------");//列与棋盘分割线
	printf("\n");
	for (int i = 1; i <= ROW; i++) {             //打印行数序号
		printf("%d ",i);
		for (int j = 1; j <= COL; j++) {        //与三子棋打印一样" %c |"为一次循环进行打印
			printf(" %c ", board[i][j]);
			if (j < COL) {                      
				printf("|");
			}
		}
		printf("\n");
		if (i < ROW) {
			for (int i = 1; i <=ROW; i++) {
				if (i ==1) {
					printf("  ");          //空出第一列用于打印序列号
			}
				printf("---");
				if (i < ROW) {           //---|---|---为一个整体(一次循环)循环打印
					printf("|");
				}
			}
			printf("\n");
		}
	}
}

 

埋雷

首先我们需要了解扫雷的规则,玩家选择一个坐标,然后检测该坐标附近8个坐标是否有雷,然后在玩家棋盘中显示附近雷的个数,简单的9*9的棋盘在边缘检测时比较复杂,那么我们就可以采用11*11的棋盘去初始化,埋雷的位置限制在9*9的棋盘中,这样就可以避免许多没必要的判断。

void SetMine(char board[ROWS][COLS]) {
	int count = N;//雷的个数
	while (count) {
		int x = rand() % ROW + 1;//使用随机数来进行埋雷,与srand配合使用来实现真正的随机。
		int y = rand() % COL + 1;//COL,ROW等于9,随机数与9求余范围是0~8,加一范围就变成了1~9
		if (board[x][y] == '0') {//确保雷的位置不重复布置
			board[x][y] = '1';//用1来表示雷
			count--;//布置之后雷的数量减一
		}
	}
}

 字符型常量定于如下:

#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define N 10

 判赢与排雷

这部分特别需要注意的是两个棋盘之间的联系。判断雷的数量在埋雷的棋盘中进行,打印输出雷的信息在show这个数组展现。

void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS]) {
	int x = 0;
	int y = 0;
	int win = 0;
	while (win<COL*ROW-N) //判赢
	{
		printf("请输入要排查的位置>:\n");
		scanf("%d%d", &x, &y);
		if (x >= 1 && x <= 9 && y >= 1 && y <= 9) {
			if (mine[x][y] == '1') {
				printf("很遗憾,你踩到了雷,游戏结束!\n");
				DisPlaybroad(mine);            //游戏结束打印埋雷棋盘
				break;
			}
			else {
				show[x][y] = Get_Mine(mine, x, y) + '0';//扫雷部分函数返回值是一个数字,而打印时是以字符的形式打印数字,所以加上‘0’转变为对应的ascll值,注意这里将埋雷棋盘的排雷信息通过函数返回给show棋盘。
				DisPlaybroad(show);//没有踩到雷继续打印棋盘
				win++;//计数
			}
		}
		else {
			printf("坐标非法,请重新输入!\n");
		}
	}
	if (win == ROW * COL - N) {//9*9的棋盘埋10个雷,那需要走71步才能将雷扫完。
		printf("恭喜你排雷成功!\n");
		DisPlaybroad(mine);
	}
}
int Get_Mine(char mine[ROWS][COLS], int x, int y)//排雷
{//在ascll表中数字都有对应的ascll值,且是10个连续的,对应0~9,数字字符
	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');
}//判断附近8个位置中雷的个数,1是字符不是数字有对应的ascll值,-8*‘0’减去8个字符0的ascll值

 以上便是游戏各模块的实现。

游戏逻辑安排

游戏的各个模块我们已经基本实现,接下来我们需要将各个模块进行组装,使游戏顺利运行。

void game()
{
	char mine[ROWS][COLS];
	char show[ROWS][COLS];
	//初始化棋盘
	InitBoard(mine,'0');
	InitBoard(show,'*');
	//埋雷
	SetMine(mine);
	//打印棋盘
	DisPlaybroad(show);
	//排雷+判赢
	FindMine(mine,show);
}

 首先我们创建了两个二维数组,游戏开始需要先初始化棋盘,游戏开始前我们需要先进行埋雷操作,然后才是打印棋盘,最后就是判赢。这就是游戏大概整体逻辑。

以下便是整体代码的呈现:

用于声明的头文件(.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 N 10
//初始化棋盘
void InitBoard(char board[ROWS][COLS], char set);
//打印棋盘
void DisPlaybroad(char board[ROWS][COLS]);
//埋雷
void SetMine(char board[ROWS][COLS]);
//排雷
void FindMine(char mine[ROWS][COLS],char show[ROWS][COLS]);

 函数定义文件(.c文件)

#include"game1.h"
void InitBoard(char board[ROWS][COLS], char set)
{
	for (int i = 0; i < ROWS; i++) {
		for (int j = 0; j < COLS; j++) {
			board[i][j] = set;
		}
	}
}
void DisPlaybroad(char board[ROWS][COLS])
{
	printf("------------------扫雷游戏------------------\n");
	printf("  ");
	for (int i = 1; i <=COL; i++) {
		printf(" %d  ", i);
	}
	printf("\n");
	printf("  -----------------------------------");
	printf("\n");
	for (int i = 1; i <= ROW; i++) {
		printf("%d ",i);
		for (int j = 1; j <= COL; j++) {
			printf(" %c ", board[i][j]);
			if (j < COL) {
				printf("|");
			}
		}
		printf("\n");
		if (i < ROW) {
			for (int i = 1; i <=ROW; i++) {
				if (i ==1) {
					printf("  ");
			}
				printf("---");
				if (i < ROW) {
					printf("|");
				}
			}
			printf("\n");
		}
	}
}
void SetMine(char board[ROWS][COLS]) {
	int count = N;
	while (count) {
		int x = rand() % ROW + 1;
		int y = rand() % COL + 1;
		if (board[x][y] == '0') {
			board[x][y] = '1';
			count--;
		}
	}
}
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS]) {
	int x = 0;
	int y = 0;
	int win = 0;
	while (win<COL*ROW-N) //判赢
	{
		printf("请输入要排查的位置>:\n");
		scanf("%d%d", &x, &y);
		if (x >= 1 && x <= 9 && y >= 1 && y <= 9) {
			if (mine[x][y] == '1') {
				printf("很遗憾,你踩到了雷,游戏结束!\n");
				DisPlaybroad(mine);
				break;
			}
			else {
				show[x][y] = Get_Mine(mine, x, y) + '0';
				DisPlaybroad(show);
				win++;
			}
		}
		else {
			printf("坐标非法,请重新输入!\n");
		}
	}
	if (win == ROW * COL - N) {
		printf("恭喜你排雷成功!\n");
		DisPlaybroad(mine);
	}
}
int Get_Mine(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');
}

 游戏主体(.c文件)

#include"game1.h"
void menu()
{
	printf("******************************\n");
	printf("*********   1.play   *********\n");
	printf("*********   0.exit   *********\n");
	printf("******************************\n");
}
void game()
{
	char mine[ROWS][COLS];
	char show[ROWS][COLS];
	//初始化棋盘
	InitBoard(mine,'0');
	InitBoard(show,'*');
	//埋雷
	SetMine(mine);
	//打印棋盘
	DisPlaybroad(show);
	//排雷+判赢
	FindMine(mine,show);
}
int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do {
		menu();
		printf("请选择>:\n");
		scanf("%d", &input);
		switch (input) {
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏!\n");
			break;
		default:
			printf("输入错误请重新输入>:\n");
			break;
		}
	} while (input);
	return 0;
}

 


 

总结


      以上就是今天要讲的内容,本文仅仅使用简单的C语言基础语法来实现的扫雷小游戏,希望可以对你有所帮助,感谢阅读!

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/570583.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

109.(cesium篇)cesium椎体上下跳动+旋转

地图之家总目录(订阅之前请先查看该博客) 地图之家:cesium+leaflet+echart+地图数据+地图工具等相关内容的介绍 文章末尾处提供保证可运行完整代码包,运行如有问题,可“私信”博主。 效果如下所示: 下面献上完整代码,代码重要位置会做相应解释 <html lang="en…

python+django高校疫情防控管理系统vue

随着信息化时代的到来&#xff0c;管理系统都趋向于智能化、系统化&#xff0c;高校疫情防控管理系统也不例外&#xff0c;但目前国内的有些学校仍都使用人工管理&#xff0c;学校规模越来越大&#xff0c;同时信息量也越来越庞大&#xff0c;人工管理显然已无法应对时代的变化…

屏幕挂灯是不是智商税?明基ScreenBar Halo屏幕挂灯初体验

目录 一、屏幕挂灯是不是智商税&#xff1f;二、文心一言眼里的屏幕挂灯1、明基ScreenBar Halo屏幕挂灯2、屏幕挂灯和普通台灯哪个好&#xff1f; 三、屏幕挂灯初体验四、使用体验五、无线控制器六、专业角度分析1、屏幕工作照明&#xff0c;不是随便一盏灯就可以2、引导光线照…

记录--超长溢出头部省略打点,坑这么大,技巧这么多?

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 在业务中&#xff0c;有这么一种场景&#xff0c;表格下的某一列 ID 值&#xff0c;文本超长了&#xff0c;正常而言会是这样&#xff1a; 通常&#xff0c;这种情况都需要超长省略溢出打点&#xff0…

2023网络安全工程师面试宝典(附答案)

2023年即将过去一半&#xff0c;先来灵魂三连问&#xff1a; 年初定的目标完成多少了&#xff1f;薪资涨了吗&#xff1f;女朋友找到了吗&#xff1f; ​好了&#xff0c;不扎大家的心了&#xff0c;接下来进入正文。 1、SQL注入的原理是什么&#xff1f; SQL注入攻击是通过将…

1722_PolySpace Bug Finder的几种启动方式

全部学习汇总&#xff1a; GreyZhang/g_matlab: MATLAB once used to be my daily tool. After many years when I go back and read my old learning notes I felt maybe I still need it in the future. So, start this repo to keep some of my old learning notes servral …

【算法】使用数位算法生成0至某个数之间的整数(for循环之外的另一种实现方式,蛮长见识的)

导入&#xff1a; 对某个整数进行遍历&#xff0c;按常规的编程思维都是 for(int i0;i<number;i){} 但是如果这个数比较大&#xff0c;大到无法的话&#xff0c;可能使用普通for循环方式进行遍历就有些吃力了。 那么针对这个问题&#xff0c;可以考虑深度搜索算法dfs来辅助完…

Linux--ServerProgramming--(1)TCP\IP协议族

1.TCP/IP 协议族 1.1 TCP/IP协议族及主要协议 TCP/IP 协议族是一个四层协议系统。自上而下为&#xff08;如下图所示&#xff09;&#xff1a;应用层传输层网络层数据链路层 应用层负责处理应用程序逻辑&#xff0c;在用户空间实现。&#xff08;少数服务器程序在内核中实现。…

快速上手kettle(一)壶之简介

Linux核心命令系列文章目录 快速上手kettle&#xff08;一&#xff09;&#xff1a;壶之简介 快速上手kettle&#xff08;二&#xff09;&#xff1a;Kettle初体验&#xff08;博主正在玩命更新中&#xff09; 快速上手kettle&#xff08;三&#xff09;&#xff1a;Kettle转换…

艾迪普发布新一代国产化“3D引擎+工具+平台”,加速释放数字内容生产力

‍数据智能产业创新服务媒体 ——聚焦数智 改变商业 艾迪普的2023新产品发布会在5月20日在北京隆重举行&#xff0c;该发布会以"向新出发 智见未来"为主题&#xff0c;艾迪普重磅推出了新一代实时三维图形图像引擎IDP Engine 4.0、iVis无代码编程数字孪生应用开发工…

谷歌云开启GPU算力狂飙,驱动AIGC时代加速到来

‍数据智能产业创新服务媒体 ——聚焦数智 改变商业 随着人工智能的飞速发展&#xff0c;尤其是大型AI模型、AIGC的崛起&#xff0c;对AI算力产生了巨大的需求。以GPU为核心的算力供给&#xff0c;已经成为大模型、AIGC乃至整个智能产业发展的关键基础设施。因此&#xff0c;对…

springboot+vue基于java的用户行为的个性化新闻推荐系统

使用个性化新闻服务平台相对传统个性化新闻服务方式具备很多优点&#xff1a;首先可以大幅提高个性化新闻服务信息检索&#xff0c;只需输入新闻相关信息就能在数秒内反馈想要的结果&#xff1b;其次可存储大量的个性化新闻服务信息&#xff0c;同时个性化新闻服务安全性有更高…

Java内存模型 JMM

并发编程模型的两个关键问题 线程之间如何通信及线程之间如何同步。 线程之间如何通信&#xff1a;共享内存&#xff0c;消息传递线程之间如何同步通信是指线程之间以何种机制来 交换信息同步是指程序中用于控制不同线程间 操作发生相对顺序 的机制在共享内存的并发模型里&a…

案例21:Java农产品供求信息系统设计与实现开题报告

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

腾讯、头条 | 算法岗详细面经

作者 | 常青czq 整理 | NewBeeNLP 面试锦囊之面经分享系列&#xff0c;持续更新中 赶紧后台回复"面试"加入讨论组交流吧 写在前面 本硕华南某985&#xff0c;有过两段实习经历&#xff0c;一段是大厂的算法实习&#xff0c;另一段是招行Fintech实习&#xff0c;虽然…

如何在Linux桌面上创建快捷方式?

以下内容源于网络资源的学习与整理&#xff0c;如有侵权请告知删除。 一般而言&#xff0c;Linux环境下在命令行上通过软件包管理工具安装软件&#xff0c;或者从网站直接下载已经编译好的二进制软件包&#xff0c;软件安装好之后不会在桌面上创建快捷方式。接下来如果想要在桌…

iOS推送播放语音播报更新

接上篇如何让iOS推送播放语音&#xff0c;之前的结论是iOS如果需要送审商店只能播放本地的mp3文件&#xff0c;这里更新一下&#xff1a; 更新 语音的播放&#xff0c;最终调用的方法是UNNotificationSound(named: xxx)&#xff0c;而这个方法官方文档注释如下&#xff1a; // …

chatgpt赋能python:Python写Kafka:介绍及优势

Python写Kafka&#xff1a;介绍及优势 Kafka是目前互联网企业使用最广泛的消息队列系统之一&#xff0c;广泛应用于应用程序之间的异步通信、数据采集、日志收集等领域。Python作为一门通用且易学易用的编程语言&#xff0c;在和Kafka结合时也展现出了其独特的优势。本文将介绍…

我C,最好用的AI工具居然是它!

这几天写了两篇自己的AI实践&#xff1a; 《程序员&#xff0c;如何借力ChatGPT&#xff1f;》&#xff1b; 《普通人&#xff0c;如何借力ChatGPT&#xff1f;》&#xff1b; 很多朋友在后台留言&#xff0c;问我用的是哪一款AI工具。 先说结论。 我最终在ChatGPT&#xff0c;…

超大规模数据库集群保稳系列之二:数据库攻防演练建设实践

总第562篇 2023年 第014篇 本文整理自美团技术沙龙第75期的主题分享《美团数据库攻防演练建设实践》&#xff0c;系超大规模数据库集群保稳系列&#xff08;内含4个议题的PPT及视频&#xff09;的第2篇文章。 本文首先介绍了美团当前数据库运维现状、遇到的问题&#xff0c;以及…