C语言小项目之扫雷(进阶版)

news2024/12/22 20:39:04

💓博主CSDN主页:杭电码农-NEO💓

⏩专栏分类:C语言学习分享⏪

🚚代码仓库:NEO的学习日记🚚

🌹关注我🫵
带你学习更多C语言知识
  🔝🔝


在这里插入图片描述

扫雷小项目

  • 1. 前期准备
  • 2. 初始化棋盘
  • 3. 打印棋盘
  • 4. 布置地雷
  • 5. 当前位置周围的雷数
  • 6. 排查地雷(非展开)
  • 7. 利用递归使棋盘展开
  • 8. 总结以及代码分享


1. 前期准备

扫雷游戏其实就是一个N×N的棋盘
可以用二维数组来模仿这个环境

值得注意的是:

当当前位置不是雷时
我们需要计算以当前位置为中心
的九宫格中有多少个雷
然后将这个数字填入当前位置中
当这个位置为棋盘边缘时,数组会越界

结论:

  • N×N的棋盘应该定义为
  • (N+2)×(N+2)
  • 打印棋盘时应该打印N×N的数组

画图理解:
在这里插入图片描述
再将所有步骤细化成:

  • 初始化棋盘- InitBoard
  • 打印棋盘- PrintBoard
  • 布置地雷- SetMine
  • 排查地雷- FindMine
  • 求坐标周围有几个雷- GetMineCount
  • 周围都没有雷时的展开- unfold

2. 初始化棋盘

假设我们用9×9的棋盘玩游戏
地雷的数量一共是10个:

#define ROW 9 //打印9×9
#define COL 9
#define ROWS ROW+2 //内部实现用11×11
#define COLS COL+2
#define MCount 10  //定义一共有10个地雷

要打印的棋盘应该和
内部实现功能的棋盘分开
所以我们定义两个数组
将打印数组初始化为’*’
埋地雷的棋盘初始化为’0’

为什么要将埋地雷棋盘初始化为0?

因为在埋地雷的时候将’0’改为’1’
没有地雷的位置就是’0’
有地雷的位置就是’1’
当我们计算一个位置的九宫格
范围内有多少个雷时就可以
直接将九宫格里所有位置加起来
得出的值就是当前位置周围雷的个数

void InitBoard(char mine[ROWS][COLS], char show[ROW][COLS], int rows, int cols)
{
	for (int i = 0; i < rows; i++)
	{
		for (int j = 0; j < cols; j++)
		{
			mine[i][j] = '0';
			show[i][j] = '*';
		}
	}
}

3. 打印棋盘

打印出来的是9×9的棋盘

在这里插入图片描述

并且在左边和上面给对应的坐标1~9

void PrintBoard(char a[ROWS][COLS], int rows, int cols)
{
	printf("最边上为行数与列数\n");
	int  i = 0;
	for (i = 0; i <= cols; i++)
	{
		printf("%d-", i);
	}
	printf("\n");
	for (i = 1; i <= rows; i++)
	{
		printf("%d ", i);
		int j = 0;
		for (j = 1; j <= cols; j++)
		{
			printf("%c ", a[i][j]);
		}
		printf("\n");
	}
}

4. 布置地雷

需要随机生成一个坐标
然后将此坐标从’0’变成’1’

(注:随机选取的位置不能已经有雷了)

void SetMine(char mine[ROWS][COLS], int rows, int cols)
{
	int count = MCount;//define宏定义的雷的个数
	while (count > 0)
	{
        int x = rand() % rows + 1;//生成1~9的随机横坐标
	    int y = rand() % cols + 1;
		if (mine[x][y] == '0')//若当前位置已经有雷了,就不执行if语句,再重新生成一个随机位置
		{
			mine[x][y] = '1';
			count--;//当前位置不是雷才进入if语句,count才减少
		}
	}
}

解释在代码块中


5. 当前位置周围的雷数

正如上面解释的一样
将以当前位置为中心的九宫格
中其他八个位置的值相加就是
当前位置雷的个数!

int GetMineCount(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] +
		mine[x + 1][y + 1] + mine[x][y + 1] + mine[x - 1][y + 1] - 8 * '0');
}

因为初始化时给的是字符’0’
所以将全部值加起来后减去八个’0’
得到的才是整数


6. 排查地雷(非展开)

排查地雷需玩家输入需要排查的坐标
然后判断这个位置是不是字符’1’
如果是就被地雷炸死了
如果不是,就将周围雷的个数打印出来

(注:当棋盘上只剩下Mcout个位置时
也就是除了地雷外所有位置都被排查了
代表玩家胜利了!)

void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int rows, int cols)
{
	int x, y;
	int winC = 0;//当winC等于棋盘数减去雷数时,游戏胜利!
	while (winC < ROW * COL - MCount)
	{
		printf("请输入要排查的坐标:");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= cols && y >= 1 && y <= rows)
		{
			if (mine[x][y] == '1')
			{
				printf("很遗憾,你被炸死了!");
				PrintBoard(mine, rows, cols);
				break;
			}
			else if (mine[x][y] == '0')
			{
				winC++;
				mine[x][y] = GetMineCount(mine,x,y);
				PrintBoard(show, rows, cols);
			}
		}
		else
		{
			printf("坐标输入错误");
		}
		if (winC == rows * cols - MCount)
		{
			printf("恭喜你,排雷成功\n");
			PrintBoard(mine, ROW, COL);
		}

	}
}

7. 利用递归使棋盘展开

电脑上的扫雷游戏有这样的功能:
当前位置不是地雷并且周围也没有雷时
它会将这一区域展开:

在这里插入图片描述

只有当打印棋盘的当前位置
是字符’*',并且横纵坐标没有越界时递归

void unfold(char mine[ROWS][COLS], char show[ROWS][COLS],int x, int y,int rows,int cols)
{
	if (GetMineCount(mine,x,y) == 0)//如果当前位置周围雷数为0
	{
		show[x][y]=' ';//像上面的图片一样将这个位置变成空格
		for (int i = x - 1; i < x + 1; i++)//递归左上,正上,右上,正左,正右...八个位置
		{
			for (int j = y - 1; j < y + 1; j++)
			{
				if (show[i][j] == '*' && i > 0 && i <= rows && j > 0 && j <= cols)
				{
					unfold(mine, show, i, j, rows, cols);//递归
				}
			}
		}
	}
	else
	{
		show[x][y] = GetMineCount(mine, x, y) + '0';
	}
}

在这里插入图片描述


8. 总结以及代码分享

完成一个规范的项目
少不了定义多个头文件和.c文件
要想你的工程变得规范,容易理解
应该将各个部分分开来实现

把所有代码的链接分享给大家:

gitee代码仓库

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

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

相关文章

phpRedis扩展安装以及session redis存储

1.下载redis扩展&#xff08;redis扩展各个版本下载地址&#xff1a;https://pecl.php.net/package/redis&#xff09; wget https://pecl.php.net/get/redis-3.1.6.tgz 2.解压下载的redis扩展 tar zxvf redis-3.1.6.tgz 3.用phpize生成configure配置文件 phpize 4.查找p…

账号安全总结-业务安全测试实操(27)

电子邮件账号泄露事件 电子邮箱业务基于计算机和通信网的信息传递业务,利用电信号传递和存储信息,为用户传送电子信函、文件数字传真、图像和数字化语音等各类型的信息。电子邮件最大的特点是,人们可以在任何地方、任何时间收、发信件,解决了时空的限制,大大提高了工作效…

深度学习编译器汇总

深度学习的发展对个科学领域产生了深远的影响。它不仅在自然语言处理&#xff08;NLP&#xff09;和计算机视觉&#xff08;CV&#xff09;等人工智能领域显示出显著的价值&#xff0c;而且在电子商务、智慧城市和药物发现等更广泛的应用领域也取得了巨大的成功。随着卷积神经网…

Django学习笔记-VS Code本地运行项目

截止到上一章节&#xff1a;Django 学习笔记-Web 端授权 AcWing 一键登录&#xff0c;我们的项目一直是部署在云服务器上&#xff0c;包括编写代码以及调试运行也是在云服务器上&#xff0c;现在我们尝试将其放回本地运行。 CONTENTS 1. 将项目传到本地2. 虚拟环境配置3. 修改项…

如何录音转文字?这份录音转文字教程你必须知道

在现代快节奏的工作环境中&#xff0c;电脑会议录音转文字成为了一项非常重要的任务。但是很多人不知道电脑会议录音转文字怎么转&#xff1f;如果你也正有这样的疑问&#xff0c;那么你就来对地方了&#xff01;在本篇文章中&#xff0c;我们将为你介绍几款备受推崇的录音转文…

联想校招雇品年轻化:硬科技「校招+雇品」的创新打法

联想计划3年内增加12,000名研发人才&#xff0c;并明确20%的New Hire将来自校园招聘。 人才梯队的构成预示着企业未来的发展方向与加速度。联想对年轻人才关注与吸引从未放慢脚步&#xff0c;始终相信年轻即代表未来。更多年轻科技人才加入&#xff0c;会为企业注入创新活力&a…

LeetCode 75 —— 62. 不同路径

LeetCode 75 —— 62. 不同路径 一、题目描述&#xff1a; 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &…

Appium之xpath定位详解

目录 一、基础定位 二、contains模糊定位 三、组合定位 四、层级定位 前面也说过appium也是以webdriver为基的&#xff0c;对于元素的定位也基本一致&#xff0c;只是增加一些更适合移动平台的独特方式&#xff0c;下面将着重介绍xpath方法&#xff0c;这应该是UI层元素定位…

前端系列20集-vue3,微信小程序,brew,redis,WebSocket

onShow() {uni.checkSession({success: (data) > {this.getSessionId()},fail: () > {this.getSessionId()}}) }, // 获取用户的手机号 getPhoneNumber(info) {let wxAuth {encryptedData: info.detail.encryptedData,iv: info.detail.iv,sessionId: uni.getStorageSync…

Java反射源码学习之旅 | 京东云技术团队

1 背景 前段时间组内针对“拷贝实例属性是应该用BeanUtils.copyProperties&#xff08;&#xff09;还是MapStruct”这个问题进行了一次激烈的battle。支持MapStruct的同学给出了他嫌弃BeanUtils的理由&#xff1a;因为用了反射&#xff0c;所以慢。 这个理由一下子拉回了我遥…

青岛农商与中电金信鲸Bot RPA的一次紧密合作

260%、350%、313%、400%、1200%&#xff0c;这些都是青岛农商银行近期通过鲸Bot RPA跑出来的各个业务流程的ROI&#xff0c;原来选择合适的RPA真的这么有用&#xff01;青岛农商还亲切地给RPA起了一个昵称&#xff1a;小鑫&#xff0c;从此小鑫就是青岛农商第一位正式的数智员工…

群晖安装、卸载、停用套件

安装套件 点击套件中心 点击所有套件&#xff0c;选中需要安装的套件&#xff0c;店家安装套件&#xff0c;或者试用&#xff0c;等待安装完成即可 卸载套件 点击已安装 点击图标或者文字&#xff0c;注意&#xff1a;不要点打开 点击向下的箭头 点击停用&#xff0c;或者卸载…

puppeteer实现文件下载

puppeteer实现文件下载 puppeteer版本&#xff1a; "puppeteer": "^20.7.3",脚本需要的其他依赖 const axios require(axios); const FormData require(form-data); const fs require(fs);本脚本测试数据网站&#xff1a;https://unsplash.com/photo…

基于Java民宿管理系统设计实现(源码+lw+部署文档+讲解等)

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

【机器学习】数据预处理 - 归一化和标准化

「作者主页」&#xff1a;士别三日wyx 「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」&#xff1a;对网络安全感兴趣的小伙伴可以关注专栏《网络安全入门到精通》 数据预处理 一、数据预处理API二、准备数据集三、归…

没有u盘,怎么将电脑上的便签文件拷贝到手机上?

在如今数字化的时代&#xff0c;便签软件已经成为我们工作和生活中很重要的一部分&#xff0c;在便签中我们会记录很多重要事项或者重要文件。有时候&#xff0c;我们可能会遇到这样的问题&#xff1a;当我们在电脑便签上保存了一些重要文件&#xff0c;想要将文件拷贝到手机上…

【Redis常见命令】 —— 关于Redis的一点儿知识

&#x1f4a7; 【 R e d i s 常见命令】——关于 R e d i s 的一点儿知识 \color{#FF1493}{【Redis常见命令】 —— 关于Redis的一点儿知识} 【Redis常见命令】——关于Redis的一点儿知识&#x1f4a7; &#x1f337; 仰望天空&#xff0c;妳我亦是行人.✨ &#x1f…

Java框架学习(二)SSM体系:Spring、SpringMVC、MybatisPlus

文章目录 SpringIoC控制反转DI 依赖注入BeanBean基础配置namescope Bean实例化方式Bean的生命周期 依赖注入方式依赖自动装配 Mybatis-Plus配置BaseMapper通用Service常用注解TableNameTableId雪花算法 TableFieldTableLogic 条件构造器和常用接口QueryWrapperUpdateWrapper 插…

【数据库原理与实践】知识点归纳(下)

第6章 规范化理论 一、关系模式设计中存在的问题 关系、关系模式、关系数据库、关系数据库的模式 关系模式看作三元组&#xff1a;R < U,F >&#xff0c;当且仅当U上的一个关系r满足F时&#xff0c;r称为关系模式R < U,F >的一个关系 第一范式&#xff08;1NF&…

一步一步学OAK之七:通过OAK相机实现特征跟踪

目录 特征跟踪Setup 1: 创建文件Setup 2: 安装依赖Setup 3: 导入需要的包Setup 4: 定义FeatureTrackerDrawer类定义变量定义onTrackBar方法定义trackFeaturePath方法定义drawFeatures方法定义FeatureTrackerDrawer类的构造函数 Setup 5: 创建pipelineSetup 6: 创建节点创建相机…