C语言小游戏3——扫雷

news2024/10/28 10:37:10

扫雷游戏

1. 扫雷游戏的功能说明

  • 使用控制台实现经典的扫雷游戏
  • 游戏可以通过菜单实现继续玩或者退出游戏
  • 扫雷的棋盘是 9*9的格子
  • 默认随机布置 10个雷
  • 可以排查雷
  • 如果位置不是雷,就显示周围有几个雷
  • 如果位置是雷,就炸死游戏结束
  • 把除10个雷之外的所有雷都找出来,排雷成功,游戏结束

2. 游戏的分析和设计

扫雷的过程中,布置的雷和排查出的雷的信息都需要存储,所以我们需要一定的数据结构来存储这些信息。因为我们需要在 9*9的棋盘上布置雷的信息和排查雷,我们首先想到的就是创建一个 9*9的数组来存放信息。

此外,我们也需要将排查出的雷的数量信息记录存储,并打印出来,作为排雷的重要参考信息的

**问题一:**我们在棋盘上布置了雷,棋盘上雷的信息 1和非雷的信息 0,假设我们排查了某一个位置后,这个坐标处是雷 d 的 1和这个坐标的周围有1个雷的 1会产生歧义。

此处有多种办法解决,比如:雷和非雷的信息不要使用数字,使用某些字符就行,这样就避免冲突了,但是这样做棋盘上有雷和非雷的信息,还有排查出的雷的个数信息,就比较混杂,不够方便。

**解决方案:**专门给一个棋盘(对应一个数组 mine)存放布置好的雷的信息,再给另外一个棋盘(对应另外一个数组 show)存放排查出的雷的信息。这样就互不干扰了,把雷布置到 mine数组,在 mine数组中排查雷,排查出的数据存放在 show数组,并且打印 show数组的信息给后期排查参考。

show数组开始时初始化为字符 '*',为了保持两个数组的类型一致,可以使用同一套函数处理, mine数组最开始也初始化为字符 '0',布置雷改成 '1'

在这里插入图片描述
在这里插入图片描述

**问题二:**在排查的坐标位于边界处时,周围的部分坐标可能存在越界。

**解决方案:**为了防止越界,我们在设计的时候,给数组扩大一圈,雷还是布置在中间的 9*9的坐标上,周围一圈不去布置雷就行,这样就解决了越界的问题。所以我们将存放数据的数组创建成 11*11是比较合适。
在这里插入图片描述
在这里插入图片描述

3. 扫雷游戏的代码实现

game.h

#pragma once

//减少源文件中引用头文件的个数
#include<stdio.h>
#include<stdlib.h>
#include<time.h>

//便于修改棋盘的大小
#define ROW 9
#define COL 9

#define ROWS ROW + 2
#define COLS COL + 2

//便于修改雷的个数
#define MINE_NUM 10

void init_board(char arr[ROWS][COLS], int row, int col, char set);

void display_board(char arr[ROWS][COLS], int row, int col);

void set_mine(char arr[ROWS][COLS], int row, int col);

void find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

game.cpp

#include"game.h"

//初始化棋盘
void init_board(char arr[ROWS][COLS],int row, int col, char set)
{
	int i = 0, j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			//放置一个set参数,使得初始化的值由我们设定
			arr[i][j] = set;
		}
	}
}

//打印棋盘
void display_board(char arr[ROWS][COLS], int row, int col)
{
	int i = 0, j = 0;
	//打印棋盘周围的坐标
	for (i = 0; i <= row; i++)
	{
		printf("%d ", i);
	}
	printf("\n");
	for (i = 1; i <= row; i++)
	{
		printf("%d ", i);
		for (j = 1; j <= col; j++)
		{
			printf("%c ", arr[i][j]);
		}
		printf("\n");
	}
}

//布置雷
void set_mine(char arr[ROWS][COLS], int row, int col)
{
	int i = 0, j = 0;
	int count = MINE_NUM;
	while (count)
	{
		i = rand() % row + 1;
		j = rand() % col + 1;
		if (arr[i][j] == '0')
		{
			arr[i][j] = '1';
			count--;
		}
	}
}

//检测周围雷的个数
//原理:'0' + a(移动范围内的自然数) = 'a'
int get_mine_count(char arr[ROWS][COLS], int i, int j)
{
	return (arr[i - 1][j - 1] + arr[i][j - 1] + arr[i + 1][j - 1] + 
		arr[i - 1][j] + arr[i + 1][j] + arr[i - 1][j + 1] + arr[i][j + 1] + 
		arr[i + 1][j + 1] - 8 * '0');
}

//排查雷
void find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int i = 0, j = 0;
	//用于判断游戏是否成功结束的标志
	int win = 0;
	while (win < ROW * COL - MINE_NUM)
	{
		printf("请输入要排查的坐标:>\n");
		scanf("%d %d", &i, &j);
		//框定坐标的范围
		if (i > 0 && i <= row && j > 0 && j <= col)
		{
			//避免重复排查
			if (show[i][j] == '*')
			{
				if (mine[i][j] == '1')
				{
					printf("很遗憾,你被炸死了\n");
					pirntf("游戏失败");
					display_board(mine, row, col);
					break;
				}
				else
				{
					//输出周围雷的个数
					show[i][j] = '0' + get_mine_count(mine, i, j);
					display_board(show, row, col);
					win++;
				}
			}
			else
				printf("该坐标已经被排查过,请重新输入\n");
		}
		else
			printf("输入错误,请重新输入进行排查\n");
	}
	if (win == ROW * COL - MINE_NUM)
	{
		printf("恭喜你,排雷成功");
		display_board(mine, ROW, COL);
	}
}

test.cpp

#include"game.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];
	init_board(mine, ROWS, COLS, '0');
	init_board(show, ROWS, COLS, '*');
	set_mine(mine, ROW, COL);
	display_board(show, ROW, COL);
	find_mine(mine, show, ROW, COL);
}
void test()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("请输入:>");
		scanf("%d", &input);
		switch (input)
		{
		case 0:
			printf("退出游戏\n");
			break;
		case 1:
			printf("开始游戏\n");
			printf("----------  扫雷!  ---------\n");
			game();
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	} while (input);
}
int main()
{
	test();
	return 0;
}

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

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

相关文章

C语言 | Leetcode C语言题解之第514题自由之路

题目&#xff1a; 题解&#xff1a; int findRotateSteps(char* ring, char* key) {int n strlen(ring), m strlen(key);int pos[26][n], posSize[26];memset(posSize, 0, sizeof(posSize));for (int i 0; i < n; i) {int x ring[i] - a;pos[x][posSize[x]] i;}int dp…

H3C vlan和trunk配置

vlan和trunk配置实验 实验拓扑图 实验需求 1.配置pc的IP地址 2.在sw1和sw2上分别创建vlan10和vlan20&#xff0c;要求pc3和pc5输入vlan10&#xff0c;pc4和pc6属于vlan20 3.sw1和sw2相连的接口配置为trunk类型&#xff0c;运行vlan10和vlan20通过 4.测试效果&#xff0c;同…

Springboot整合原生ES依赖

前言 Springboot整合依赖大概有三种方式&#xff1a; es原生依赖&#xff1a;elasticsearch-rest-high-level-clientSpring Data ElasticsearchEasy-es 三者的区别 1. Elasticsearch Rest High Level Client 简介: 这是官方提供的 Elasticsearch 客户端&#xff0c;支持…

大语言模型数据类型与环境安装(llama3模型)

文章目录 前言一、代码获取一、环境安装二、大语言模型数据类型1、基本文本指令数据类型2、数学指令数据类型3、几何图形指令数据类型4、多模态指令数据类型5、翻译指令数据类型三、vscode配置四、相关知识内容1、理解softmax内容2、torch相关函数nn.Embedding函数torch.nn.fun…

《手写Spring渐进式源码实践》实践笔记(第十一章 AOP-基于JDK、Cglib实现对象动态代理)

文章目录 第十一章 基于JDK、Cglib实现对象动态代理背景目标设计实现代码结构类图代理案例解析案例代码运行结果拆解案例 实现步骤 测试事先准备自定义拦截方法测试用例测试结果&#xff1a; 总结 第十一章 基于JDK、Cglib实现对象动态代理 背景 到本章节我们将要从 IOC 的实现…

Java版本的基于计算机视觉的跃动小子保卫主公自动通关计划之整体思路篇

系列文章 Java版本的基于计算机视觉的跃动小子保卫主公自动通关计划之图片分割篇 图片分类篇,执行计划生成篇,执行篇等后续篇章持续更新中,欢迎关注 文章目录 系列文章Java版本的基于计算机视觉的跃动小子保卫主公自动通关计划之整体思路篇构建二维数组构建消除时形态7个元素的…

【无标题】idea 一次性切换多个项目的分支

适合一个目录下面有多个子项目&#xff0c;维护着共同的分支 勾选Settings-Version Control->Git->Executor branch operations on all roots 勾选前&#xff08;是不能一次切换多个项目的分支为同一个分支的&#xff09; 勾选此选项 勾选后&#xff08;可以一次切换多个…

纯css实现瀑布流! 附源码!!!

瀑布流用于展示图片信息,我这里用的背景颜色来代替图片 PC端效果 源码(直接复制粘贴就可以运行了!!!) <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title>PC端瀑布流</title><style>.box {w…

开发环境 —— Keil5 芯片包安装却找不到芯片

目 录 Keil 5添加芯片包一、查看芯片包名称二、下载芯片包三、安装芯片包四、安装成功却找不到芯片4.1 解压pack文件4.2 拷贝到指定路径 Keil 5添加芯片包 Keil只是一个开发平台&#xff0c;keil 5软件安装完成后&#xff0c;默认只能创建ARM芯片的工程。如果要创建其它芯片的…

网络编程_day3

#1024程序员节 #三次握手四次挥手#四次挥手#udp#recvfrom#sendto#服务器模型#客户端模型#Linux IO模型#阻塞式IO#非阻塞IO#设置非阻塞的方式 目录 【0】复习 【1】三次握手四次挥手 四次挥手 四次挥手既可以由客户端发起&#xff0c;也可以由服务器发起 【2】udp 1. 通信流程 2…

[OpenCV] 数字图像处理 C++ 学习——17轮廓发现详细讲解+附完整代码

文章目录 前言1.理论基础1.1轮廓发现1.2轮廓发现步骤1.3相关API(1)轮廓发现(find contour)(2)轮廓绘制(draw contour) 2.代码实现2.1图像预处理2.2轮廓发现2.3绘制轮廓2.4Trackbar 调整阈值 3.完整代码 前言 轮廓发现是图像处理中一个重要的操作&#xff0c;可以帮助找到图像中…

基于SSM+微信小程序的快递的管理系统(快递1)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1、项目介绍 基于SSM微信小程序的快递管理平台&#xff0c;有管理员&#xff0c;用户&#xff0c;配送员&#xff0c; 1、管理员实现了个人中心&#xff0c;用户管理&#xff0c;配送员管理&#xff0…

IDM下载器 (Internet Download Manager) v6.42.2 中文免激活绿色版

Internet Download Manager (IDM下载器) 是一款先进的下载工具,可以提升您的下载速度高达5倍,支持续传&#xff0c;IDM可以让用户自动下载某些类型的文件&#xff0c;它可将文件划分为多个下载点以更快速度下载&#xff0c;并列出最近的下载&#xff0c;方便访问文件。相对于其…

如何通过sip信令以及抓包文件分析媒体发到哪个地方

前言 问题描述&#xff1a;A的媒体没转发到B&#xff0c;B只能听到回铃音&#xff0c;没有A的说话声音&#xff0c;并且fs这边按正常的信令发送了. 分析流程 分析早期媒体发送到哪一个IP 10.19.0.1发送了一个请求给10.19.0.157这个IP&#xff0c;然而这里的SDP媒体地址&am…

Leetcode 二叉树的右视图

好的&#xff0c;我来用中文详细解释这段代码的算法思想。 问题描述 题目要求给定一个二叉树的根节点&#xff0c;从树的右侧看过去&#xff0c;按从上到下的顺序返回看到的节点值。即&#xff0c;我们需要找到每一层的最右侧节点并将其加入结果中。 算法思想 这道题可以通…

【gRPC】什么是RPC——介绍一下RPC

说起RPC&#xff0c;博主使用CPP手搓了一个RPC项目&#xff0c;RPC简单来说&#xff0c;就是远程过程调用&#xff1a;我们一般在本地传入数据进行执行函数&#xff0c;然后返回一个结果&#xff1b;当我们使用RPC之后&#xff0c;我们可以将函数的执行过程放到另外一个服务器上…

go语言中的Scanf()输入函数

Scanf() 第一种情况 package mainimport "fmt"func main() {var a intfor {fmt.Println("请输入一个整数:")fmt.Scanf("%d", &a)fmt.Println("----------------", a)} }运行结果&#xff1a; 解释&#xff1a; 出现这种现象是因…

Docker下载途径

Docker不是Linux自带的&#xff0c;需要我们自己安装 官网&#xff1a;https://www.docker.com/ 安装步骤&#xff1a;https://docs.docker.com/engine/install/centos/ Docker Hub官网(镜像仓库)&#xff1a;https://hub.docker.com/ 在线安装docker 先卸载旧的docker s…

C/C++小宇宙代码

系列目录 序号直达链接1C/C爱心代码2C/C跳动的爱心3C/C李峋同款跳动的爱心代码4C/C满屏飘字表白代码5C/C大雪纷飞代码6C/C烟花代码7C/C黑客帝国同款字母雨8C/C樱花树代码9C/C奥特曼代码10C/C圣诞树代码11C/C俄罗斯方块12C/C贪吃蛇13C/C小宇宙代码 目录 系列目录 写在前面 …

LVGL显示图片2——显示GIF图片,图片尺寸注意,图片太大无法显示

1进入图像转换网页中 https://lvgl.io/tools/imageconverter 2选择图片 3设置生成的格式 4点击生成 5复制文件&#xff0c;配置环境 6编写代码&#xff08;&#xff09; //显示一张动图 void demo_gif(){lv_obj_t* screenlv_scr_act();//声名对象LV_IMG_DECLARE(GIF_1);//创…