C语言(扫雷)

news2025/1/10 16:50:15

扫雷

  • 开发过程
  • 开发思路
  • 菜单界面
  • 游戏界面的打印
  • 雷的随机产生
  • 扫雷以及判断胜利条件
  • 代码整合

在这里插入图片描述

开发过程

  • 准备工作
  • 效果展示

准备工作:
在这里插入图片描述
game.h 一个头文件–>声明函数
test.c 为主文件
game.c 为功能函数实现文件

效果展示
在这里插入图片描述
在这里插入图片描述

开发思路

  • 菜单界面

  • 游戏界面打印(二维数组)

  • 雷的随机产生

  • 排雷(以及判断周围的雷数)

  • 胜利条件

大致思路就是这样,接下来我们一步步去分析

菜单界面

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

这里我们要不断的去 接收用户的输入,当为1时,进入游戏,为0时,退出程序
直接就想到了 条件语句判断,这里我们用switch

不断的:用户完成游戏后,可以再次打印菜单供用户选择

这个操作当然是项目的核心部分了,放在 main()函数

int main()
{
	int input = 0;
	
	//设置随机数  后面会讲
	srand((unsigned int)time(NULL));
	
	do
	{
		menu();
		printf("请输入:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏");
			break;
		default:
			printf("输入有误!!!");
			break;
		}
	} while (input);

	return 0;
}

游戏界面的打印

这里当然是用二维数组,但是我们要去考虑,如果就一个数组的话,能否起到不知情排雷的效果。
当然,一个数组是不可能的,所以我们要建立两个数组
一个是真实的,一个是展示给用户看的

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

在这里我们要先去考虑一下,该数组若是9×9,在边缘时去判断周围的雷数会越界
我们可以通过建立11×11的数组,其中最外围我们不用,只是设置为默认值

#define ROW 9
#define COL 9

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

对地图的初始化

	//mine 数组在没有布置雷的时候全为 0
	InitBoard(mine, ROWS, COLS, '0');
	//show 数组在没有排查雷的时候全为 *
	InitBoard(show, ROWS, COLS, '*');

我们的InitBoard函数为:

void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
	int i = 0, 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)
{
	int i = 0, j = 0;
	printf("-----------扫雷游戏--------------\n");
	//打印上面0~9注释
	for (j = 0; j <= col; j++)
	{
		printf("%d ", j);
	}
	
	printf("\n");
	for (i = 1; i <= row; i++)
	{
		printf("%d ", i); //打印竖着1~9的注释
		for (j = 1; j <= col; j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("\n");
	}
	printf("-----------扫雷游戏--------------\n");
}

雷的随机产生

我们很容易想到,就是产生随机数,对其数组进行更改元素值。
这就用到了 srand()函数

	//设置随机数的起始
	srand((unsigned int)time(NULL));

随机产生的函数:

我们定义EASY_COUNT(雷的数量)在头文件中

void SetMine(char board[ROWS][COLS], int row, int col)
{
	int count = EASY_COUNT;
	//横纵坐标1~9
	while (count)
	{
		int d = rand() % row + 1;
		int c = rand() % col + 1;

		//随机生成十个雷,雷:1
		if (board[d][c] == '0')
		{
			board[d][c] = '1';
			count--;
		}
	}
}

扫雷以及判断胜利条件

扫雷
让用户输入一个坐标,对其值进行判断

  • 若在 show数组内该坐标为*,则该坐标已经被排雷
  • 若在mine数组内该坐标为1则被雷炸失败
  • 否则对其周围进行判断在mine数组内有几颗雷并在show数组的该坐标上显示其数量

判断是否重复输入坐标

			if (show[x][y] != '*')
			{
				printf("该坐标已经排查过了,请重新输入:>\n");
			}

失败的代码很简单,一个判断就行了

				if (mine[x][y] == '1')	//是雷
				{
					printf("被炸死咯\n");
					DisplayBoard(mine, ROW, COL);
					break;
				}

判断周围有几颗雷的函数为
在这里插入图片描述

int get_mine_count(char board[ROWS][COLS], int x, int y)
{
	return (board[x - 1][y] +
		board[x - 1][y - 1] +
		board[x - 1][y + 1] +
		board[x][y + 1] +
		board[x][y - 1] +
		board[x + 1][y - 1] +
		board[x + 1][y] +
		board[x + 1][y + 1]- 8*'0');
}

整个操作的函数为

void FindMine(char mine[ROW][COL], char show[ROW][COL], int row, int col)
{
	int x = 0, y = 0;
	int a = 0, b = 0;
	int win = 0;
	while (win<row*col-EASY_COUNT)//判断胜利条件,win小于整体-雷数
	{
		printf("请输入排查的坐标:>\n");
		scanf("%d %d", &a, &b);
		x = a + 1;
		y = b + 1;

		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (show[x][y] != '*')
			{
				printf("该坐标已经排查过了,请重新输入:>\n");
			}
			else
			{
				if (mine[x][y] == '1')	//是雷
				{
					printf("被炸死咯\n");
					DisplayBoard(mine, ROW, COL);
					break;
				}
				else //不是雷         '0'-'0'=0     '1'-'0'=1  字符->整型   
								// ASCII码值分别为 '1':49     '0':48
				{
					int count = get_mine_count(mine, x, y);//统计该坐标周围有几颗雷
					show[x][y] = count + '0';//转换成数字字符
					//printf("%c\n", count + '0');
					DisplayBoard(show, ROW, COL);
					win++;
				}
			}
		}
		else
		{
			printf("输入坐标错误,请重新输入:>\n");
		}
	}
	if (win == row * col - EASY_COUNT)
	{
		printf("恭喜你,扫雷成功!!!\n");
		DisplayBoard(mine, ROW, COL);
	}
}

代码整合

test.c

#include "game.h"

void menu()
{
	printf("*********************\n");
	printf("*** 1.play 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(mine,ROW, COL);
	//设置雷
	SetMine(mine, ROW, COL);
	//展示
	DisplayBoard(show, ROW, COL);
	//排雷
	FindMine(mine,show,ROW,COL);
}

int main()
{
	int input = 0;
	//设置随机数
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("请输入:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏");
			break;
		default:
			printf("输入有误!!!");
			break;
		}
	} while (input);

	return 0;
}

game.c

#include "game.h"

void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
	int i = 0, 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)
{
	int i = 0, j = 0;
	printf("-----------扫雷游戏--------------\n");
	for (j = 0; j <= col; j++)
	{
		printf("%d ", j);
	}
	printf("\n");
	for (i = 1; i <= row; i++)
	{
		printf("%d ", i);
		for (j = 1; j <= col; j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("\n");
	}
	printf("-----------扫雷游戏--------------\n");
}

void SetMine(char board[ROWS][COLS], int row, int col)
{
	int count = EASY_COUNT;
	//横纵坐标1~9
	while (count)
	{
		int d = rand() % row + 1;
		int c = rand() % col + 1;

		//随机生成十个雷,雷:1
		if (board[d][c] == '0')
		{
			board[d][c] = '1';
			count--;
		}
	}
}

int get_mine_count(char board[ROWS][COLS], int x, int y)
{
	return (board[x - 1][y] +
		board[x - 1][y - 1] +
		board[x - 1][y + 1] +
		board[x][y + 1] +
		board[x][y - 1] +
		board[x + 1][y - 1] +
		board[x + 1][y] +
		board[x + 1][y + 1]- 8*'0');
}


void FindMine(char mine[ROW][COL], char show[ROW][COL], int row, int col)
{
	int x = 0, y = 0;
	int a = 0, b = 0;
	int win = 0;
	while (win<row*col-EASY_COUNT)//判断胜利条件,win小于整体-雷数
	{
		printf("请输入排查的坐标:>\n");
		scanf("%d %d", &a, &b);
		x = a + 1;
		y = b + 1;

		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (show[x][y] != '*')
			{
				printf("该坐标已经排查过了,请重新输入:>\n");
			}
			else
			{
				if (mine[x][y] == '1')	//是雷
				{
					printf("被炸死咯\n");
					DisplayBoard(mine, ROW, COL);
					break;
				}
				else //不是雷         '0'-'0'=0     '1'-'0'=1  字符->整型   
								// ASCII码值分别为 '1':49     '0':48
				{
					int count = get_mine_count(mine, x, y);//统计该坐标周围有几颗雷
					show[x][y] = count + '0';//转换成数字字符
					//printf("%c\n", count + '0');
					DisplayBoard(show, ROW, COL);
					win++;
				}
			}
		}
		else
		{
			printf("输入坐标错误,请重新输入:>\n");
		}
	}
	if (win == row * col - EASY_COUNT)
	{
		printf("恭喜你,扫雷成功!!!\n");
		DisplayBoard(mine, ROW, COL);
	}
}

game.h

#pragma once
#include <stdio.h>
#include <time.h>
#include <stdlib.h>

#define ROW 9
#define COL 9

#define ROWS ROW+2
#define COLS COL+2
#define EASY_COUNT 10  //雷


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 board[ROWS][COLS],int row,int col);

void FindMine(char mine[ROW][COL],char show[ROW][COL], int row, int col);

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

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

相关文章

二、机器人的结构设计

1 、螺丝连接的坚固性 坚固性是机器人能顺利完成指定任务的一个重要条件&#xff0c;无论我们程序设计的如何完美&#xff0c; 如果不能保证机器人具有坚固性和稳定性&#xff0c;就无法保证任务的顺利完成&#xff0c;机器人在运行时如 果发生散架和分裂都会影响其功能的实现…

阿里云的白名单规则如何实现IP限制和访问控制?

阿里云的白名单规则如何实现IP限制和访问控制&#xff1f;   [本文由阿里云代理商[聚搜云]撰写]   随着企业在云计算领域的深入应用&#xff0c;网络安全问题日益凸显。阿里云提供了一种名为“白名单”的规则&#xff0c;帮助用户实现IP限制和访问控制。本文将详细阐述阿里…

“ 最近 ” ,准备跳槽的可以看看

前两天跟朋友感慨&#xff0c;今年的铜三铁四、裁员、疫情导致好多人都没拿到offer!现在已经12月了&#xff0c;具体明年的金三银四只剩下两个月。 对于想跳槽的职场人来说&#xff0c;绝对要从现在开始做准备了。这时候&#xff0c;很多高薪技术岗、管理岗的缺口和市场需求也…

【ROS】ROS2中的概念和名词解释

1、工作空间 workspace ROS以固定的目录结构创建项目工程&#xff0c;项目根目录称为工作空间 1.1 典型工作空间结构 src&#xff1a; 代码空间&#xff1b; build&#xff1a; 编译空间&#xff0c;保存编译过程中产生的中间文件&#xff1b; install&#xff1a;安装空间…

一种在不改变源码的情况下测试看门狗复位的方法

什么是“看门狗”&#xff1f; 看门狗定时器&#xff08;WDT&#xff0c;Watch Dog Timer&#xff09;是单片机的一个组成部分&#xff0c;它实际上是一个计数器&#xff0c;一般给看门狗一个数字&#xff0c;程序开始运行后看门狗开始倒计数。如果程序运行正常&#xff0c;过…

git使用X篇_2_Git全套教程IDEA版(git、GitHub、Gitee码云、搭建公司内部GitLab、与IDEA集成等内容)

本文是根据以下视频及网上总结进行更新后的介绍git使用的博文。包含了git、GitHub、Gitee码云、搭建公司内部GitLab、与IDEA集成等内容。 笔记来源&#xff1a;【尚硅谷】5h打通Git全套教程IDEA版&#xff08;涵盖GitHub\Gitee码云\GitLab&#xff09; 文章目录 初识 Git0、内容…

vue-echarts图表的应用(总结)

vue项目中echarts图表的应用(总结) 一 . 安装echarts包 npm i echarts 二 . 放置两个图表的div&#xff0c;并给定高宽 <div class"chart"><!-- 图表 --><div ref"social" style" width: 100%; height:100% " /> </div&g…

Python入门(十五)函数(三)

函数&#xff08;三&#xff09; 1.返回值1.1 返回简单值1.2 让实参变成可选的1.3 返回字典1.4 结合使用函数和while循环 作者&#xff1a;Xiou 1.返回值 函数并非总是直接显示输出&#xff0c;它还可以处理一些数据&#xff0c;并返回一个或一组值。函数返回的值称为返回值。…

【2023】Redis主从复制模式集群

资源有限&#xff0c;本文使用Docker部署目录 &#x1f3b6;主从模式介绍&#x1f3b6; 搭建主从模式集群&#x1f3b6; 使用命令搭建主从集群&#x1f3b6; 通过配置文件搭建主从模式集群 &#x1f3b6;配置读写分离&#x1f3b6; 用心跳机制提高主从复制的可靠性&#x1f3b6…

[golang 微服务] 3. ProtoBuf认识与使用

一.protobuf简介 前言 在移动互联网时代&#xff0c; 手机流量、 电量是最为有限的资源&#xff0c;而移动端的即时通讯应用无疑必须得直面这两点。解决流量过大的基本方法就是 使用高度压缩的通信协议&#xff0c;而数据压缩后流量减小带来的自然结果也就是省电&#xff1a;因…

#Verilog HDL# Verilog设计中的竞争问题和解决办法

经过前面文章的学习&#xff0c;我们知道&#xff1a;不管是Verilog设计语言&#xff0c;还是Sytemverilog验证语言&#xff0c;标准都定义了语言调度机制&#xff0c;来规范各家编译器和仿真器的开发。今天&#xff0c;我们着重看一下Verilog 硬件设计语言中竞争问题&#xff…

算法拾遗三十一马拉车算法

算法拾遗三十一马拉车算法 回文是什么回文暴力求法 Manacher算法回文直径和回文半径最右回文边界最右回文右边界的中心C位置Manacher求解过程Manacher 题 回文是什么 一个字符串正过来念和反过来念一样&#xff0c;总的来说就是有一个对称轴可能在字符上也可能在范围上面 回文…

算法刷题总结 (十一) 二叉树

算法总结11 二叉树 一、二叉树的概念1.1、什么是二叉树&#xff1f;1.2、二叉树的常见类型1.2.1、无数值&#xff08;1&#xff09;、满二叉树&#xff08;2&#xff09;、完全二叉树 1.2.2、有数值&#xff08;3&#xff09;、二叉搜索树&#xff08;4&#xff09;、平衡二叉搜…

设置服务器ssh远程连接时超时关闭的时间

我们通过ssh远程连接服务器时&#xff0c;如果一段时间客户端没有使用&#xff0c;就会与服务器断开连接。这个断开的时间我们是可以自己的设置的。 以linux centos系统为例&#xff0c; 具体设置方法如下&#xff1a; 1、通过下面的命令编译sshd配置文件 vim /etc/ssh/sshd_…

SylixOS vutex

vutex 概念 SylixOS 引入了与 Linux futex 类似的用户快速锁 vutex&#xff08;vitual user mutex&#xff09;&#xff08;SylixOS 习惯称为“等待变量锁”&#xff09;&#xff1b;vutex 包括两个操作&#xff1a;pend 和 post&#xff0c;pend 操作用于等待期望值得到满足&…

DFS专题

题单地址&#xff1a;【237题】算法基础精选题单_ACM竞赛_ACM/CSP/ICPC/CCPC/比赛经验/题解/资讯_牛客竞赛OJ_牛客网 老子的全排列呢 dfs回溯 int n 8; int idx; int record[10]; bool vis[10];void dfs(int num) {if(numn){for(int i1;i<n;i) cout<<record[i]<…

【ONE·C++ || C++11(一)】

总言 主要介绍C11中的一些功能语法。 文章目录 总言0、思维导图1、基本情况简介2、统一的列表初始化2.1、{}的使用2.2、initializer_list2.2.1、基础介绍2.2.2、在各容器中实现说明 3、声明3.1、auto3.2、nullptr3.3、decltype 4、范围for5、智能指针6、STL中一些变化6.1、C11…

一、版本控制

1、什么是版本控制 1.1、版本控制的概念 版本控制&#xff08;Revision control&#xff09;是一种在开发的过程中用于管理我们对文件、目录或工程等内容的修改历史&#xff0c;方便查看更改历史记录&#xff0c;备份以便恢复以前的版本的软件工程技术。 1.2、版本控制的作用…

泛型方法、Function类的函数化编程与调用

0、引言 在项目开发的过程中&#xff0c;常常需要将一些高频复用的方法封装成工具类&#xff0c;例如最近学到的Redis缓存中&#xff0c;解决缓存穿透、解决缓存击穿的方法&#xff08;例如解决缓存穿透的问题的方法queryWithPassThrough&#xff09;&#xff0c;传入一个Long型…

谷粒商城:Oss endpoint can‘t be empty.问题

商品API &#xff0c;文件上传管理的时候 出现这个问题 解决两个方向 1.springBoot、alibabaCloud、springCloud、aliyunOSS 之间的版本问题&#xff0c;我的是下面的版本可以运行了。 // springBoot版本 2.7.7 <groupId>org.springframework.boot</groupId> &l…