C语言:扫雷小游戏

news2024/11/29 9:41:28

文接上一篇博文C语言:三子棋小游戏。本篇博文是使用C语言来实现扫雷小游戏的。这里不对扫雷的规则进行赘述。玩家通过键盘输入坐标来探雷。博主在实现扫雷之前从未看过扫雷实现的相关视频,所以这里实现的扫雷完全是博主的原生思路,具有逻辑性。下面详细介绍一下如何实现扫雷。

(建议在阅读过上一篇博文再阅读本文,因为再本文中对重复的问题不会再次解读。)

步骤一:制定框架

框架是什么?如何制定框架?这些问题在三子棋的实现中就已经解答了,这里也不多讲。这里的框架与三子棋的框架完全相同。

#include"detect.h"
int main()
{
	srand((unsigned)time(NULL));//这里设置了随机种子,为了之后随机生成雷
	int n = 0;
	do
	{
		menu();
		printf("your choice:\n");
		scanf("%d", &n);
		switch (n)
		{
		case 1:
			system("cls");
			game();
			break;
		case 0:
			system("cls");
			printf("exit game\n");
			break;
		default:
			printf("input error,again:\n");
			Sleep(1000);
			system("cls");
		}
	} while (n);
	return 0;
}

menu是什么在三子棋实现中也提过,这里使用了Sleep函数(程序暂停运行多少毫秒)和system("cls")(清屏)是为了更好的游戏体验。这里的detect.h代码如下:

#pragma once
#define ROW 10
#define COL 10
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<windows.h>
void menu();
void game();

步骤二:实现game函数

跟三子棋的game函数一样,我们需要事先想好整个game的流程。

分析过程:既然有雷,我们需要将雷的位置记录下来,那我们就需要一个字符二维数组,雷用大写字符'O'表示,雷的位置就初始化为'O',其他位置为空格。另外,开局时我们一个地方都没探测,我们难道要将带雷的数组直接打印上去吗?显然这样雷就直接被打印出来了。我们可以想到用第二个字符二维数组,里面初始时全是空格字符,这个数组是用来打印的。我们在这个数组中进行探测。

结束条件:如果探的是雷,那么直接宣告失败,结束本次游戏;如果这一次避开了所有的雷,那么直接宣告成功,结束本次游戏;如果这一次没探到雷而且没有结束,那么显示此处旁边雷的个数

那我们怎么知道探出的是不是雷?其实很简单,在数组一中此处如果是雷,说明这次探到雷了

下面是game的代码

void game()
{
	char map1[ROW][COL] = { 0 };
	char map2[ROW][COL] = { 0 };
	mapInit(map1, ROW, COL);//真正存储炸弹
	mapInit(map2, ROW, COL);//用来打印
	BoomInit(map1, ROW, COL);
	system("cls");
	showMap(map2, ROW, COL);
	while (1)
	{
		int ret=playerMove(map1, map2, ROW, COL,ROW*COL/8);
		if (ret==1)//炸了
		{
			system("cls");
			showMap(map1, ROW, COL);
			printf("game over\n");
			system("pause");
			break;
		}
		else if (ret== 2)//排除了所有炸弹
		{
			system("cls");
			showMap(map1, ROW, COL);//展示所有炸弹位置
			printf("detect successfully\n");
			Sleep(2000);
			break;
		}
		system("cls");
		showMap(map2, ROW, COL);
	}
}

当然只是代码还是很模糊的,下面依然需要对game中的各个部分进行讲解。

map1:即数组一,用来存放炸弹的

map2:即数组二,用来打印的

ROW,COL:宏定义,这个宏定义在"detect.h"中,之前已经给出

mapInit:用来初始化两个数组,将两个数组的每一个元素变成空格字符

BoomInit:用来将map1的随机位置放上炸弹

showMap:将map2打印出来(连带格子的线条,之后会详细实现)

playerMove:返回值为int类型,玩家在map2中的一个位置进行探测,如果在map1中相应位置是炸弹就返回1,避开所有炸弹就返回2,其他情况返回0;

 步骤三:实现game中的函数

​
​
void mapInit(char map[ROW][COL], int row, int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			map[i][j] = ' ';
		}
	}
}//这个函数很简单,不作讲解
void BoomInit(char map[ROW][COL], int row, int col)
{
	int boomNum = row * col / 6;//6分之一是炸弹
	//设置炸弹进map
	int curNum = 0;
	int x = 0;
	int y = 0;
	while (curNum != boomNum)
	{
		 x = rand() % row;
		 y = rand() % col;
		if (map[x][y] == ' ')//如果是空格才能正常放入,如果已经是炸弹就不放,重新生成一个坐标
		{
			map[x][y] = 'O';
			curNum++;
		}
	}
}

void showMap(char map[ROW][COL], int row, int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			printf(" %c ", map[i][j]);
			if (j < col - 1)
				printf("|");
		}
		printf("\n");
		if (i < row - 1)
		{
			for (int x = 0; x < col; x++)
			{
				printf("---");
				if (x < col - 1)
					printf("|");
			}
			printf("\n");
		}//这一段其实是将画格子线和棋子一并画出,
         //需要自己动手操作一下才能明白这段代码每一句是在做什么
         //不动手再怎么讲都不会弄明白
	}
}
//warning函数是为了完成playerMove函数而写的,请先看playerMove函数
char warning(char map[ROW][COL], int row, int col, int x, int y)
{
	int countBoom = 0;//最大为8,加上'0'变成字符
	for (int i = x - 1; i <= x + 1;i++)
	{
		for (int j = y - 1; j <= y + 1; j++)
		{
			if (i >= 0 && i <= row && j >= 0 && j <= col)//越界了就不判断是不是雷
			{
				if (map[i][j] == 'O')
					countBoom++;
			}
		}
	}
	return countBoom +'0';
}
int playerMove(char map1[ROW][COL],char map2[ROW][COL], int row, int col,int boomNum)
{
	int x = 0;
	int y = 0;
	static count = 0;//静态局部变量,记录用户一共开了几个格子
	while (1)
	{
		printf("input x:\n");
		scanf("%d", &x);
		printf("input y:\n");
		scanf("%d", &y);
		x--;
		y--;//用户输入的1就是第一个位置,数组下标就是0
		if (x < 0 || x >= row || y < 0 || y >= col || map2[x][y] != ' ')
		{
			printf("wrong place,again\n");//非法坐标,重新输入
		}
		else
		{
			break;//合法,退出循环
		}
	}
    //如果探到雷了,map2的该位置就改成'O',没探到雷就显示旁边有几个雷
    //这里的warning函数就是用来给出map1的相应位置旁边有几个雷,返回值是char类型
	map2[x][y] = map1[x][y]=='O'?'O':warning(map1,ROW,COL,x,y);
	if (map2[x][y] == 'O')
		return 1;//探到雷了,返回1
	else//判断是否排除完
	{
		count++;
		if (count == col * row - boomNum)
		{
			count = 0;//归零,下一次进行游戏count还是从0开始计数,否则count还是之前的值
			return 2;//避开了所有的雷,返回2
		}
	}
	return 0;//正常进行下一次探测,返回0
}

​

​

 到这里为止,所有的工作就完成了,我们来看看效果

测试:

 配合清屏和睡眠函数效果还是不错的,只是和原版的扫雷少了一个功能。我们知道,原版的扫雷在探到一个格子旁边没有一个炸弹时,也就这里实现的扫雷显示'0'时,会自动将旁边的格子显示出来,只是这个功能实现起来有点困难。当时想过用递归解决这个问题,就是说如果map2中探到一个0雷格,将旁边八个格子打开,如果这八个格子还有0雷格,就会进行递归,继续将旁边的格子打开,只是这样会有一个问题,0雷格挨在一起的话会陷入死递归。个人感觉这个问题使用递归是最好解决的,之后想到了解决方案会更新博文。

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

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

相关文章

用python开发一个炸金花小游戏

众所周知&#xfeff;扑克牌可谓是居家旅行、桌面交友的必备道具&#xff0c; 今天我们用 Python 来实现一个类似炸金花的扑克牌小游戏&#xff0c;先来看一下基本的游戏规则。 炸&#xff08;诈&#xff09;金花又叫三张牌&#xff0c;是在全国广泛流传的一种民间多人纸牌游戏…

乐信仍面临资产质量下降和拖欠率上升风险

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 公司介绍 乐信(LX)成立于2013年10月&#xff0c;是中国领先的新消费数字科技服务商。旗下业务包括线上分期购物商城分期乐&#xff0c;全场景信用消费产品乐花卡&#xff0c;新型分期购物平台买吖&#xff0c;助力金融机构…

广告、政府、IT三重合作:凭爱校对轻松搞定文本质量

在广告创意、政府政策和IT开发这三个看似不相关的领域中&#xff0c;有一个共同的需求&#xff1a;高质量的文本内容。本文将探讨如何通过使用“爱校对”工具&#xff0c;在这三个行业内确保文本质量&#xff0c;从而提高工作效率和准确性。 广告行业&#xff1a;语境与创意的完…

EDM邮件营销:使用EDM代发实现更高发送率

虽然现在进入数字时代&#xff0c;但电子邮件依然是企业跟客户之间沟通最有效的方式之一。为了吸引并且留存目标用户&#xff0c;各大企业都在努力做好EDM&#xff08;Electronic Direct Mail&#xff09;邮件营销。但是通常用电子邮箱发送外贸邮件会有发送数量和自动化的限制&…

固定资产管理怎么写报告

撰写固定资产管理报告时&#xff0c;需要考虑以下几个维度的数据&#xff1a;  资产总量和分类&#xff1a;列出公司的固定资产总量、种类以及各类型资产的数量。  资产使用情况&#xff1a;统计各类型资产的使用率、闲置率、报废率等数据&#xff0c;以及不同部门的资产使…

西电Latex毕业模板使用时的小技巧

西电Latex毕业模板 配置的环境&#xff1a;textlivetextstudio \qqad 空格 参考文献先设置成bib&#xff0c;放到tex文件下&#xff0c;然后如下操作就可以将参考文献加载进去 如果搜不到相关文献的bib格式&#xff0c;可以用zotero软件将下载好的文件导出为bib格式&#xf…

43、Flink之Hive 读写及详细验证示例

Flink 系列文章 1、Flink 部署、概念介绍、source、transformation、sink使用示例、四大基石介绍和示例等系列综合文章链接 13、Flink 的table api与sql的基本概念、通用api介绍及入门示例 14、Flink 的table api与sql之数据类型: 内置数据类型以及它们的属性 15、Flink 的ta…

在线客服如何与客户进行有效沟通?

在今天的“互联网”时代&#xff0c;越来越多的服务都开始向线上转移&#xff0c;其中最受欢迎的莫过于在线客服。在线客服不仅可以提供7x24小时的在线咨询服务&#xff0c;还可以提高企业的服务效率和满意度。然而&#xff0c;有时候在线客服与客户之间的沟通效果却不太令人满…

EMERSON A6500-CC 机架接口模块 AMS参数

EMERSON A6500-CC 机架接口模块 AMS参数 ModBus和机架接口模块设计用于工厂的高可靠性 最关键的旋转机械。它从所有AMS A6500 ATG模块读取参数 并通过ModBus TCP/IP和/或ModBus RTU&#xff08;串行&#xff09;输出这些参数。 此外&#xff0c;OPC UA可用于向第三方系统传输数…

sentinel1.8.6中的blockHandler/blockHandlerClass和fallback/fallbackClass

官网介绍 简单的说blockHandler/blockHandlerClass是给限流降级用的&#xff0c;异常为BlockException&#xff0c;fallback/fallbackClass是给除BlockException之外的业务异常兜底用的。 官方文档还说明。1.6.0 之前的版本 fallback 函数只针对降级异常&#xff08;DegradeEx…

Leetcode125. 验证回文串

力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后&#xff0c;短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。 字母和数字都属于字母数字字符。 给你一个字符串 s&…

软件测试/测试开发丨Web自动化测试 关键数据记录

点此获取更多相关资料 本文为霍格沃兹测试开发学社学员学习笔记分享 原文链接&#xff1a;https://ceshiren.com/t/topic/27105 记录关键数据的作用 内容作用日志1、记录代码执行情况&#xff0c;方便复现场景&#xff0c;也可以作为bug依据截图1、断言失败或成功的截图&#…

cesium开发入门(vue2)

一、cesium介绍 Cesium是国外一个基于JavaScript编写的使用WebGL的地图引擎。Cesium支持3D,2D,2.5D形式的地图展示&#xff0c;可以自行绘制图形&#xff0c;高亮区域&#xff0c;并提供良好的触摸支持&#xff0c;且支持绝大多数的浏览器和mobile。 中文文档 官网 二、创建…

transformer位置编码最详细的解析

位置编码positional encoding 1. 位置编码是什么&#xff0c;为什么需要它&#xff1f;2. transformer提出的位置编码方法3. 直觉4. 其他细节5. 相对位置6. 常见问题解答 1. 位置编码是什么&#xff0c;为什么需要它&#xff1f; 位置和词语的顺序是任何语言的重要组成部分。它…

韩老师java教程

基础知识 进制 进制首位表示方式二进制0B十进制无八进制0十六进制0X 进制转换 x进制转十进制 正常&#xff0c;没什么问题 十进制转x进制 将该数不断除以x&#xff0c;直到商为0为止&#xff0c;然后将每一步得到的余数倒过来&#xff0c;就是对应的x进制 二进制转八进…

MySQL——单行处理函数和多行处理函数

数据处理函数&#xff1a; 单行处理函数&#xff1a;一个输入对应一个输出 多行处理函数&#xff1a;多个输入对应一个输出 单行处理函数&#xff1a; 将大写转换为小写&#xff1a;lower(); select lower(ename) as ename from emp; 将小写转换为大写&#xff1a;upper(); se…

软件测试工作中需要使用的工具

作为一个测试人员在日常工作中会使用到很多的工具&#xff0c;今天给大家分享一下这些工具。对软件测试、接口、自动化、性能测试和日常文档编写办公有帮助的网站。 接口测试大力推荐国产的接口测试工具&#xff1a;apipost&#xff0c;apipost还是一款很不错的接口文档生产工…

本地PC机通过SSH方式远程Jetson

1. 检测电脑是否安装openSSH 以管理员身份运行powershell终端输入以下命令&#xff1a; Get-WindowsCapability -Online | ? Name -like OpenSSH*若没有安装OpenSSH&#xff0c;会出现如下图提示&#xff1a; 输入Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.…

数智化,如何驱动高校的产教融合

高校数智驱动是指通过运用先进的技术和智能化的手段&#xff0c;推动高校的发展和创新。这包括利用大数据分析、人工智能、物联网等技术来提高高校的管理效率、教学质量和科研水平。 高校实施数智驱动考虑的几个方面 &#xff08;1&#xff09;建立数据驱动的决策机制&#xf…

计算机网络第三节物理层

一&#xff0c;第二章 物理层&#xff08;数据通信有关&#xff09; 1.物理层引入的目的 屏蔽掉传输介质的多样性&#xff0c;导致数据传输方式的不同&#xff1b;物理层的引入使得高层看到的数据都是统一的0,1构成的比特流 2.物理层如何实现屏蔽 物理层靠定义的不同的通信…