c语言——扫雷游戏(简易版)

news2024/11/23 7:10:24

目录

  • 前言
  • 游戏设计

前言

什么是扫雷游戏?
游戏目标是在最短的时间内根据点击格子出现的数字找出所有非雷格子,同时避免踩雷,踩到一个雷即全盘皆输。
这个游戏对于c语言的初学者来说难度还是挺大的,那我就实现一个初学者也能快速学会的初级版扫雷游戏。

游戏设计

我们先创建三个文件

  1. game.h、game.c(游戏逻辑的实现)
    2.test.c(游戏功能测试)

这些是我们需要实现的游戏功能

//初始化棋盘
void InitBoard(char arr[ROWS][COLS], int rows, int cols, char set);
//打印棋盘
void DisPlayBoard(char arr[ROWS][COLS], int row, int col);
//布置雷
void SetMine(char arr[ROWS][COLS],int row, int col);
//排查雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row,int col);

再次之前,我们在测试文件里先创建游戏菜单

//test.c
void meun()
{
	printf("******************\n");
	printf("***** 1.play  ****\n");
	printf("***** 0.exit  ****\n");
	printf("******************\n");
}

之后再实现菜单功能

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

游戏规则:

1.如果这个位置是雷,那么游戏结束
2.如果把不是雷的位置都找出来了,那么游戏结束
3.如果这个位置不是雷,就计算这个位置的周围的8个格子有几个雷,并显示出雷的个数

我以一个9*9的的棋盘为例,在棋盘中,雷为1,非雷为0,如果我选中非雷,并且周围雷的数量为1,那么我如何区分呢?
其实创建两个棋盘就能解决了,一个棋盘放置雷的信息,一个棋盘给玩家展示,就能很好的解决。
在这里插入图片描述

//test.c
void game()
{
	//mine数组中存放布置好雷的信息
	char mine[ROWS][COLS] = { 0 };//数组全部初始化为字符'0'
	//show数组中存放排查出雷的信息
	char show[ROWS][COLS] = { 0 };//数组全部初始化为'*'
	//初始化棋盘
	InitBoard(mine, ROWS, COLS, '0');
	InitBoard(show, ROWS, COLS, '*');  
	//布置雷
	SetMine(mine, ROWS, COLS);
	
	//打印棋盘
	//DisPlayBoard(mine, ROW, COL);
	DisPlayBoard(show, ROW, COL);
	
	//排查雷
	FindMine(mine, show, ROWS, COLS);
}

然后我们初始化棋盘

//game.c
#include "game.h"//记得包含头文件
void InitBoard(char arr[ROWS][COLS], int rows, int cols, char set)
{
	int i = 0;
	for (i = 0; i < rows; i++)
	{
		int j = 0;
		for (j = 0; j < cols; j++)
		{
			arr[i][j] = set;
		}
	}
}

打印棋盘

void DisPlayBoard(char arr[ROWS][COLS], int row, int col)
{
	int i = 0;
	printf("-------扫雷游戏--------\n");
	for (i = 0; i <= col; i++)//打印列
	{
		printf("%d ", i);
	}
	printf("\n");
	for (i = 1; i <= row; i++)
	{
		int j = 0;
		printf("%d ", i);//打印行
		for (j = 1; j <= col; j++)
		{
			printf("%c ", arr[i][j]);	
		}
		printf("\n");
	}
}

如果我们不打印行和列等会就无法定位坐标

在这里插入图片描述
然后就可以开始布置雷了
我们先实现简单版

//game.h
//行和列
#define ROW 9
#define COL 9

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

#define EASY_COUNT 10//雷的数量 

这里用rand因为是想随机布置雷,rand如何使用大家可以顺便了解一下

rand()和srand()的关系
rand()和srand()要一起使用,其中srand()用来初始化随机数种子,rand()用来产生随机数。
因为默认情况下随机数种子为1,而相同的随机数种子产生的随机数是一样的,失去了随机性的意义,所以为使每次得到的随机数不一样,用函数srand()初始化随机数种子。srand()的参数,用time函数值(即当前时间),因为两次调用rand()函数的时间通常是不同的,这样就可以保证随机性了。

//布置雷
void SetMine(char arr[ROWS][COLS], int row, int col)
{
	int count = EASY_COUNT;
	while (count)
	{
		int x = rand() & row + 1;
		int y = rand() & col + 1;
		if (arr[x][y] == '0')
			arr[x][y] = '1';
		count--;
	}
}
//test.c
void test()
{
	int input = 0;
	srand((unsigned int)(time(NULL)));
	do {
		meun();
		printf("请选择:>");
		scanf("%d", &input);
		switch(input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("游戏结束,退出游戏\n");
			break;
		default:
			printf("输入错误,请重新选择\n");
			break;
		}
	} while (input);
}

排查地雷

//game.c
/*第一种方法
int GetMineCount(char arr[ROWS][COLS],int x, int y)
{
	int count = 0;
	for (int i = x - 1; i <= x + 1; x++)
	{
		for (int j = y - 1; j <= y + 1; j++)
		{
			count += (arr[x][y] - '0');
		}
	}
	return count;
}*/
//第二种
int GetMineCount(char mine[ROWS][COLS], int x, int y)
{
	return mine[x + 1][y] + mine[x - 1][y] +
		mine[x][y + 1] + mine[x][y - 1] +
		mine[x + 1][y + 1] + mine[x - 1][y + 1] +
		mine[x - 1][y - 1] + mine[x + 1][y - 1] - 8 * '0';
}
//排查雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int win = 0;
	int x = 0;
	int y = 0;
	while (win < row * col - EASY_COUNT)
	{
		printf("请输入要查找的坐标:");
		scanf("%d %d", &x, &y);
		//检查坐标的有效性
		if (x > 1 && x <= row && y > 1 && y <=col)
		{
			if (show[x][y] == '*')
			{
				if (mine[x][y] == '1')
				{
					printf("倒霉鬼,你被炸死了");
					DisPlayBoard(mine, ROW, COL);
					break;
				}
				else
				{
					//该坐标不是雷,统计附近的雷的数量
					int count = GetMineCount(mine, x, y);
					show[x][y] = count + '0';
					DisPlayBoard(show, ROW, COL);
					win++;
				}
			}
			else
			{
				printf("该坐标已经被排查了,重新输入坐标\n");
			}
		}
		else
		{
			printf("请重新输入,坐标错误:");
		}
	}
	if (win == row * col - EASY_COUNT)
	{
		printf("恭喜你,排雷成功!");
		DisPlayBoard(mine, ROW, COL);
	}

}

源码:
game.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 EASY_COUNT 10//雷的数量 
//初始化棋盘
void InitBoard(char arr[ROWS][COLS], int rows, int cols, char set);
//打印棋盘
void DisPlayBoard(char arr[ROWS][COLS], int row, int col);
//布置雷
void SetMine(char arr[ROWS][COLS],int row, int col);
//排查雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row,int col);

game.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void InitBoard(char arr[ROWS][COLS], int rows, int cols, char set)
{
	int i = 0;
	for (i = 0; i < rows; i++)
	{
		int j = 0;
		for (j = 0; j < cols; j++)
		{
			arr[i][j] = set;
		}
	}
}

void DisPlayBoard(char arr[ROWS][COLS], int row, int col)
{
	int i = 0;
	printf("-------扫雷游戏--------\n");
	for (i = 0; i <= col; i++)
	{
		printf("%d ", i);
	}
	printf("\n");
	for (i = 1; i <= row; i++)
	{
		int j = 0;
		printf("%d ", i);
		for (j = 1; j <= col; j++)
		{
			printf("%c ", arr[i][j]);	
		}
		printf("\n");
	}
}
//布置雷
void SetMine(char arr[ROWS][COLS], int row, int col)
{
	
	int count = EASY_COUNT;
	while (count)
	{
		int x = rand() & row + 1;
		int y = rand() & col + 1;
		if (arr[x][y] == '0')
			arr[x][y] = '1';
		count--;
	}
}

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


int GetMineCount(char arr[ROWS][COLS],int x, int y)
{
	int count = 0;
	for (int i = x - 1; i <= x + 1; x++)
	{
		for (int j = y - 1; j <= y + 1; j++)
		{
			count += (arr[x][y] - '0');
		}
	}
	return count;
}
//排查雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int win = 0;
	int x = 0;
	int y = 0;
	while (win < row * col - EASY_COUNT)
	{
		printf("请输入要查找的坐标:");
		scanf("%d %d", &x, &y);
		//检查坐标的有效性
		if (x > 1 && x <= row && y > 1 && y <=col)
		{
			if (show[x][y] == '*')
			{
				if (mine[x][y] == '1')
				{
					printf("倒霉鬼,你被炸死了");
					DisPlayBoard(mine, ROW, COL);
					break;
				}
				else
				{
					//该坐标不是雷,统计附近的雷的数量
					int count = GetMineCount(mine, x, y);
					show[x][y] = count + '0';
					DisPlayBoard(show, ROW, COL);
					win++;
				}
			}
			else
			{
				printf("该坐标已经被排查了,重新输入坐标\n");
			}
		}
		else
		{
			printf("请重新输入,坐标错误:");
		}
	}
	if (win == row * col - EASY_COUNT)
	{
		printf("恭喜你,排雷成功!");
		DisPlayBoard(mine, ROW, COL);
	}

}

test.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "game.h"
void meun()
{
	printf("******************\n");
	printf("***** 1.play  ****\n");
	printf("***** 0.exit  ****\n");
	printf("******************\n");
}
void game()
{
	//mine数组中存放布置好雷的信息
	char mine[ROWS][COLS] = { 0 };//数组全部初始化为字符'0'
	//show数组中存放排查出雷的信息
	char show[ROWS][COLS] = { 0 };//数组全部初始化为'*'
	//初始化棋盘
	InitBoard(mine, ROWS, COLS, '0');
	InitBoard(show, ROWS, COLS, '*');  //这里是你字母打错了  现在可以了哦
	//布置雷
	SetMine(mine, ROWS, COLS);
	
	//打印棋盘
	//DisPlayBoard(mine, ROW, COL);
	DisPlayBoard(show, ROW, COL);
	
	//排查雷
	FindMine(mine, show, ROWS, COLS);
}
void test()
{
	int input = 0;
	srand((unsigned int)(time(NULL)));
	do {
		meun();
		printf("请选择:>");
		scanf("%d", &input);
		switch(input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("游戏结束,退出游戏\n");
			break;
		default:
			printf("输入错误,请重新选择\n");
			break;
		}
	} while (input);
}
int main()
{
	test();

	return 0;
}

运行效果:
在这里插入图片描述
希望这篇博客对你有所帮助!!!

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

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

相关文章

C++ 55 之 多继承

#include <iostream> #include <string> using namespace std;class Base08_1{ public:int m_a;Base08_1(){this->m_a 10;} };class Base08_2{ public:// int m_b;int m_a;Base08_2(){// this->m_b 20;this->m_a 30;} };// 多继承 继承的类型都要…

sort使用

具体使用 bool myfunction(int i, int j) { return (i < j); }class my_function { public:bool operator()(int i, int j) { return (i < j); } }; int main() {int array[] { 4,1,8,5,3,7,0,9,2,6 };// 默认按照小于比较&#xff0c;排出来结果是升序std::sort(array…

汉邦高科防监控初始化恢复方法

汉邦高科算是安防市场上的三线品牌&#xff0c;产品不算多&#xff0c;但在某些地域有一定的市场份额。下面我们看下汉邦高科安防监控格式化后如何恢复数据&#xff1a; 故障存储:ST300VM002 故障现象: 由于各种原因录像机被初始化&#xff0c;导致数据全部丢失&#xff0c;…

逻辑斯蒂回归与最大熵

知识树 感知机的缺陷 修补感知机缺陷-逻辑斯蒂回归 下面这两个值是强制给的,不是推导的 最大熵 最大熵的一个小故事 最大熵模型 我们最终目标是要求P(Y|X) 书上写的是H,但是2我们认为H(Y|X)更合适 咱们最终的目的是要用拉格朗日乘数法,所以需要约束 总结 感觉深度之眼比较模…

xinput1_3.dll怎么安装,关于xinput1_3.dll的多种修复方法分享

在电脑使用过程中&#xff0c;我们可能会遇到一些错误提示&#xff0c;其中之一就是“找不到xinput1_3.dll”。那么&#xff0c;xinput13.dll到底是什么&#xff1f;为什么会出现找不到的情况&#xff1f;它对电脑有什么影响&#xff1f;本文将为您详细解析xinput1_3.dll的含义…

【stm32-新建工程】

stm32-新建工程 ■ 下载相关STM32Cube官方固件包&#xff08;F1&#xff0c;F4&#xff0c;F7&#xff0c;H7&#xff09;■ 1. ST官方搜索STM32Cube■ 2. 搜索 STM32Cube■ 3. 点击获取软件■ 4. 选择对应的版本下载■ 5. 输入账号信息■ 6. 出现下载弹框&#xff0c;等待下载…

【SpringBoot项目常见细化错误】(保姆级教程)Result Maps collection already contains value for

SpringBoot项目常见错误 1.当Mybatis报错 Result Maps collection already contains value for一、重复点击Mybatis-Generator导致配置文件重复生成XML二、正确配置Yml仔细检查有没有多了或者少了一个空格三、spring boot mybatis四、应该用resultMap来接收返回值&#xff0c;…

2024数据库期末综合解析(部分题)

目录 第4关&#xff1a;数据记录修改 任务描述 补充 答案&#xff1a; 第6关&#xff1a;数据查询二 任务描述 补充 答案&#xff1a; 第4关&#xff1a;数据记录修改 任务描述 湖南人口hnpeople数据表如下所示 各字段含义如下 cs&#xff08;城市)、qx(区县)、rk(人口)、man(男…

workhome 2024.06.16 math-6

数学分析语句断句&#xff0c;分析&#xff0c;画画做图&#xff0c;逻辑&#xff0c;解析&#xff0c;计算过程&#xff0c;严谨&#xff0c;我们程序出错多数是因为不够严谨&#xff0c;少了漏了可能出现的情况。 1&#xff09; https://download.csdn.net/download/spencer_…

基于JSP技术的个人网站系统

开头语&#xff1a; 你好呀&#xff0c;我是计算机学长猫哥&#xff01;如果有相关需求&#xff0c;文末可以找到我的联系方式。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;JSP JavaBeans Servlet 工具&#xff1a;Eclipse、MySQL Workbench、…

使用STL算法函数有效提升STL列表的搜索速度(附源码)

STL(Standard Templete Library)活动模板库已被广泛地应用于各种C++程序的开发中,STL中vector、list、map等列表极大地方便了我们日常的开发,不再需要我们去实现链表等数据结构,使用这些列表能基本能解决开发过程中遇到的各种问题。网上关于STL的文章比较多,今天我们就来…

购物车店铺列表查询流程

购物车店铺列表查询流程 购物车结算流程图

力扣54. 螺旋矩阵

给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]] 输出&#xff1a;[1,2,3,6,9,8,7,4,5] 示例 2&#xff1a; 输入&#xff1a;matrix [[1,2…

system与excel族函数区别

1.system #include<stdlib.h> int system(const char *command); comand是命令的路径&#xff0c;一般我们用绝对路径 system函数会创建新的进程&#xff0c;新的进程执行完返回原来的进程&#xff0c;原来的进程则继续执行后面的代码段。 如我们创建一个sys.cpp文件…

JUC并发编程第十三章——读写锁、邮戳锁

本章路线总纲 无锁——>独占锁——>读写锁——>邮戳锁 1 关于锁的面试题 你知道Java里面有那些锁你说说你用过的锁&#xff0c;锁饥饿问题是什么&#xff1f;有没有比读写锁更快的锁StampedLock知道吗&#xff1f;&#xff08;邮戳锁/票据锁&#xff09;ReentrantR…

部署大模型LLM

在autodl上部署大模型 windows运行太麻烦&#xff0c;环境是最大问题。 选择云上服务器【西北B区 / 514机】 cpp (c c plus plus) 纯 C/C 实现&#xff0c;无需外部依赖。针对使用 ARM NEON、Accelerate 和 Metal 框架的 Apple 芯片进行了优化。支持适用于 x86 架构的 AVX、…

跟着刘二大人学pytorch(第---10---节课之卷积神经网络)

文章目录 0 前言0.1 课程链接&#xff1a;0.2 课件下载地址&#xff1a; 回忆卷积卷积过程&#xff08;以输入为单通道、1个卷积核为例&#xff09;卷积过程&#xff08;以输入为3通道、1个卷积核为例&#xff09;卷积过程&#xff08;以输入为N通道、1个卷积核为例&#xff09…

浅谈赚钱的四个级别,你在哪一层呢

一谈到赚钱&#xff0c;很多人都会扯到&#xff1a;智商、情商、人脉、资源、背景等等&#xff0c;类似“小钱靠勤&#xff0c;中钱靠智&#xff0c;大钱靠德”这样的经典语录都会脱口而出&#xff0c;其实从本质上来讲&#xff0c;都没有错&#xff0c;但这样的说法太缥缈&…

算法工程师 | 如何快速 了解,掌握一个算法!脚踏实地,迎着星辰,向前出发 ~

本文是一些碎碎念 希望对正在迈向 算法工程师道路的你 有所裨益 一般来说&#xff0c;代码 中会有很多 算法实现的细节&#xff0c;但论文可能并没有体现&#xff0c;所以能够尝试自己 仔细阅读论文&#xff0c;手动复现代码&#xff0c;基本上来说对 这个 算法 你有了全…

UltraISO制作U盘系统盘安装openEuler22.03和搭建cuda环境

1.下载openEuler镜像 https://repo.openeuler.org/openEuler-22.03-LTS/ISO/x86_64/ 选择下载&#xff1a;openEuler-22.03-LTS-x86_64-dvd.iso 2.用软碟通将 U 盘制作为启动盘 点击左上方 文件 –> 打开 然后找到下载的 ISO 镜像后&#xff0c;打开 打开后如下 找到菜单…