当前位置: 首页 > news >正文

【C语言】扫雷小游戏


🚀 作者简介:一名在后端领域学习,并渴望能够学有所成的追梦人。
🐌 个人主页:蜗牛牛啊
🔥 系列专栏:初出茅庐C语言
☀️ 学习格言:眼泪终究流不成海洋,人总要不断成长!
🌹 欢迎进来的小伙伴,如果小伙伴们在学习的过程中,发现有需要纠正的地方,烦请指正,希望能够与诸君一同成长! 🌹


文章目录

  • 一、扫雷
    • 1.演示效果
    • 2.完整代码
  • 二、代码解析
    • 1.初始化雷盘
    • 2.打印雷盘
    • 3.布置雷
    • 4.排雷
    • 5.游戏函数主体
    • 6.菜单函数
    • 7.头文件、宏定义及主函数

一、扫雷

扫雷小游戏主要是利用字符数组、循环语句和函数实现。
📕设计思路:雷盘大小为9*9,但是为了后续能更好的统计出雷的个数在定义数组的时候定义大小为11*11,先定义两个字符数组,一个用来记录雷的位置,另一个用来展现给玩家,初始化雷盘,将两个字符数组分别全部赋值为字符0和字符*,打印棋盘,随机设置雷所在位置,根据玩家输入的坐标排查上下左右8个格子中的雷,并判断输入坐标处是否有雷。
🗡玩法:玩家选择开始游戏之后,输入坐标,如果坐标处有雷,输入坐标处标记为$,并打印出来游戏结束重新选择;如果坐标处没有雷,统计出附近8个格子中雷的个数并在输入坐标处展现出来;如果输入坐标已经被排查过了,则提示已排查过。

1.演示效果

为了更好的演示,将雷的个数设置为79个,同时将显示出雷的位置的雷盘也展现出来。
具体效果如下:

扫雷游戏演示

2.完整代码

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define ROW 9//展现出来的行
#define COL 9//展现出来的列

#define ROWS ROW+2//全部的行
#define COLS COL+2//全部的列

#define MINE 79//雷的个数
void Init_board(char board[ROWS][COLS], int rows, int cols, char set)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < rows; i++)
	{
		for (j = 0; j < cols; j++)
		{
			board[i][j] = set;
		}
	}
}
//打印雷盘
void Print_board(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	for (j = 0; j <= col; j++)
	{
		printf("%d ", j);//打印出来列号
	}
	printf("\n");
	for (i = 1; i <= row; i++)
	{
		printf("%d ",i);//打印出来行号
		for (j = 1; j <= row; j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("\n");
	}
}
void Set_mine(char mine[ROWS][COLS], int row, int col)
{
	int count = MINE;
	while (count)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';
			count--;
		}
	}
}
int Get_mine(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');

}
void Find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int win = 0;//走了多少步
	while(win<row*col-MINE)
	{
		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("你被炸死了,通关失败!\n");
					show[x][y] = '$';//炸死时用符号$代表所输入的坐标
					Print_board(show, row, col);
					break;
				}
				else
				{
					int count = Get_mine(mine, x, y) + '0';
					show[x][y] = count;
					Print_board(show, row, col);
					win++;
				}
			}
			else
			{
				printf("输入的坐标已被排查过,请重新输入!\n");
			}
		}
		else
		{
			printf("输入的坐标非法,请重新输入!\n");
		}
	}
	if (win == row * col - MINE)
	{
		printf("恭喜你,成功通关!\n");
		Print_board(show, row, col);
	}
}
void game()
{
	//定义两个数组,mine用来记录雷的位置,show展现给玩家
	char mine[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };
	//初始化雷盘
	//全部初始化为字符0和字符*
	Init_board(mine, ROWS, COLS,'0');
	Init_board(show, ROWS, COLS, '*');

	//打印雷盘
	//Print_board(mine, ROW, COL);
	Print_board(show, ROW, COL);

	//布置雷
	Set_mine(mine, ROW, COL);
	Print_board(mine, ROW, COL);
	
	//排雷
	Find_mine(mine, show, ROW, COL);
}
void menu()
{
	printf("************************\n");
	printf("****  1.开始游戏    ****\n");
	printf("****  0.结束游戏    ****\n");
	printf("************************\n");
}
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("游戏结束!\n");
			break;
		default:
			printf("选择错误,请重新选择!\n");
			break;
		}
	} while (input);
}

二、代码解析

1.初始化雷盘

//初始化雷盘
void Init_board(char board[ROWS][COLS], int rows, int cols, char set)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < rows; i++)
	{
		for (j = 0; j < cols; j++)
		{
			board[i][j] = set;
		}
	}
}

char set是用来接收传过来的字符。

2.打印雷盘

//打印雷盘
void Print_board(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	for (j = 0; j <= col; j++)
	{
		printf("%d ", j);//打印出来列号
	}
	printf("\n");
	for (i = 1; i <= row; i++)
	{
		printf("%d ", i);//打印出来行号
		for (j = 1; j <= row; j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("\n");
	}
}

打印雷盘时将其所在的序列号也打印了出来。

3.布置雷

void Set_mine(char mine[ROWS][COLS], int row, int col)
{
	int count = MINE;
	while (count)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';
			count--;
		}
	}
}

通过用rand函数和srand函数生成随机坐标布置雷的位置,一共布置count个雷。

4.排雷

int Get_mine(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');

}
void Find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int win = 0;//走了多少步
	while (win < row * col - MINE)
	{
		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("你被炸死了,通关失败!\n");
					show[x][y] = '$';//炸死时用符号$代表所输入的坐标
					Print_board(show, row, col);
					break;
				}
				else
				{
					int count = Get_mine(mine, x, y) + '0';
					show[x][y] = count;
					Print_board(show, row, col);
					win++;
				}
			}
			else
			{
				printf("输入的坐标已被排查过,请重新输入!\n");
			}
		}
		else
		{
			printf("输入的坐标非法,请重新输入!\n");
		}
	}
	if (win == row * col - MINE)
	{
		printf("恭喜你,成功通关!\n");
		Print_board(show, row, col);
	}
}

Get_mine函数用来计算输入坐标附近的雷的个数,通过附近字符1相加之后减去8个字符0计算出来,减去字符0是因为字符1和字符0的ASCII码值相差1,利用这个规则将字符转化为数字。Find_mine函数通过输入的坐标,判断坐标处是否为雷或展现出附近雷的个数亦或者结束游戏。

5.游戏函数主体

void game()
{
	//定义两个数组,mine用来记录雷的位置,show展现给玩家
	char mine[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };
	//初始化雷盘
	//全部初始化为字符0和字符*
	Init_board(mine, ROWS, COLS, '0');
	Init_board(show, ROWS, COLS, '*');

	//打印雷盘
	//Print_board(mine, ROW, COL);
	Print_board(show, ROW, COL);

	//布置雷
	Set_mine(mine, ROW, COL);
	Print_board(mine, ROW, COL);

	//排雷
	Find_mine(mine, show, ROW, COL);
}

6.菜单函数

void menu()
{
	printf("************************\n");
	printf("****  1.开始游戏    ****\n");
	printf("****  0.结束游戏    ****\n");
	printf("************************\n");
}

7.头文件、宏定义及主函数

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define ROW 9//展现出来的行
#define COL 9//展现出来的列

#define ROWS ROW+2//全部的行
#define COLS COL+2//全部的列

#define MINE 79//雷的个数
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("游戏结束!\n");
			break;
		default:
			printf("选择错误,请重新选择!\n");
			break;
		}
	} while (input);
}

相关文章:

  • 『Halcon与C#混合编程』011_工业相机的SDK介绍
  • 卷积核flip+transpose+cv.imread+enumerate+np.pad+tqdm
  • 【第一阶段:java基础】第1章:java概述
  • MySQL进阶之触发器、锁、InnoDB引擎和MySQL管理
  • 【Linux】虚拟机安装Ubuntu后的一些通用设置
  • [Android]使用Android打包Unity工程
  • 【STM32】PWM输出
  • 神经网络每次结果不一样,神经网络预测问题
  • Python常用命令总结【持续更新】
  • 什么样的人适合学习网络安全?
  • python作业8
  • 【css伪类选择器及透明度——附项目图片及代码】
  • Hadoop 3.x(生产调优手册)----【HDFS--存储优化】
  • SpringBoot项目的发布与运行
  • 基于Hi3861的听话的狗子
  • 【React系列】如何构建React应用程序
  • 【笔记】你不知道的JS读书笔记——Promise
  • Cookie 在前端中的实践
  • express如何解决request entity too large问题
  • JavaScript/HTML5图表开发工具JavaScript Charts v3.19.6发布【附下载】
  • Node + FFmpeg 实现Canvas动画导出视频
  • node.js
  • ubuntu 下nginx安装 并支持https协议
  • vue 个人积累(使用工具,组件)
  • VuePress 静态网站生成
  • 测试如何在敏捷团队中工作?
  • 读懂package.json -- 依赖管理
  • 基于OpenResty的Lua Web框架lor0.0.2预览版发布
  • 开放才能进步!Angular和Wijmo一起走过的日子
  • 深度学习入门:10门免费线上课程推荐
  • 腾讯优测优分享 | 你是否体验过Android手机插入耳机后仍外放的尴尬?
  • 小程序开发中的那些坑
  • const的用法,特别是用在函数前面与后面的区别
  • 阿里云服务器如何修改远程端口?
  • 翻译 | The Principles of OOD 面向对象设计原则
  • ​一文看懂数据清洗:缺失值、异常值和重复值的处理
  • #Linux杂记--将Python3的源码编译为.so文件方法与Linux环境下的交叉编译方法
  • #php的pecl工具#
  • #基础#使用Jupyter进行Notebook的转换 .ipynb文件导出为.md文件
  • #设计模式#4.6 Flyweight(享元) 对象结构型模式
  • (1)无线电失控保护(二)
  • (CPU/GPU)粒子继承贴图颜色发射
  • (附源码)php投票系统 毕业设计 121500
  • (附源码)springboot宠物医疗服务网站 毕业设计688413
  • (机器学习-深度学习快速入门)第一章第一节:Python环境和数据分析
  • (九)c52学习之旅-定时器
  • (七)Java对象在Hibernate持久化层的状态
  • (十一)图像的罗伯特梯度锐化
  • (原創) 系統分析和系統設計有什麼差別? (OO)
  • (转)iOS字体
  • (轉貼)《OOD启思录》:61条面向对象设计的经验原则 (OO)
  • .net(C#)中String.Format如何使用
  • .NET/C# 阻止屏幕关闭,阻止系统进入睡眠状态
  • .NET关于 跳过SSL中遇到的问题
  • @property @synthesize @dynamic 及相关属性作用探究