IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 扫雷(无flag版)—— C语言实现 -> 正文阅读

[C++知识库]扫雷(无flag版)—— C语言实现

扫雷(无🚩)—— C语言实现


1 主要功能

  1. 初始化雷区
  2. 打印雷区
  3. 布置雷区
  4. 排查雷区(递归展开)
  5. 计时器

2 代码展示

2.1 头文件

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
#define ROW 9
#define COL 9
#define EASY_COUNT 20 //设置雷的个数
#define ROWS ROW+2
#define COLS COL+2 
//初始化雷区
void Init_Board(char board[ROWS][COLS], int rows, int cols, char set);
//打印雷区
void Display_Board(char board[ROWS][COLS], int row, int col);
//布置雷区
void Set_Mine(char board[ROWS][COLS], int row, int col);
//排查雷区
void Remove_Mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
 //递归展开
void expand(char mine[ROWS][COLS], char show[ROWS][COLS], int x_coordinate

2.2 执行文件

#include "game.h" //头文件引入

2.2.1 菜单函数

void menu()//用于菜单打印
{
	printf("*********************************\n");
	printf("*********************************\n");
	printf("***** 1.PLAY        0.EXIT ******\n");
	printf("*********************************\n");
	printf("*********************************\n");
}

2.2.2 游戏执行函数

void game()
{
	char mine[ROWS][COLS] = { 0 };//设置一个数组用于布雷
	char show[ROWS][COLS] = { 0 };//设置一个数组用于展示
	Init_Board(mine, ROWS, COLS, '0');//初始化雷区全为0,11*11
	Init_Board(show, ROWS, COLS, '*');//初始化展示界面全为*,11*11
	Set_Mine(mine, ROW, COL);//在9*9范围内布雷
	//Display_Board(mine, ROW, COL);
	Display_Board(show, ROW, COL);//布雷之后打印雷区9*9展示界面,扫雷前工作准备就绪
	Remove_Mine(mine, show, ROW, COL);//开始扫雷
}
/*因考虑雷区边界对扫雷的影响,初始化雷区比真实布雷、扫雷区域大一圈*/

在这里插入图片描述

2.2.3 主函数

int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));//用于生成随机数种子,便于后续随机布雷
	do
	{
		system("cls");//清除上一次的游戏结果
		menu();
		printf("Make your choice:>");//输入选择游戏或退出
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("Game Over...");
			break;
		default:
			break;
		}
	} while (input);
	return 0;
}

2.3 主函数文件

#include "game.h" //头文件引入

2.3.1 初始化雷区

void Init_Board(char board[ROWS][COLS], int rows, int cols, char set)
    //传递一个二维数组、初始化行数、列数、初始化后每个数组元素填充的内容
{
	int i = 0;
	for (size_t i = 0; i < rows; i++)//遍历二维数组每个元素,赋值为set的内容
	{
		int j = 0;
		for (size_t j = 0; j < cols; j++)
		{
			board[i][j] = set;
		}
	}
}

2.3.2 打印雷区

void Display_Board(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	printf("-------------------\n");
	for (i = 0; i <= col; i++)
	{
		printf("%d ", i);//打印纵坐标位置
	}
	printf("|");
	printf("\n");
	for (size_t i = 1; i <= row; i++)
	{
		int j = 0;
		printf("%d ", i);//打印横坐标位置
		for (size_t j = 1; j <= col; j++)
		{
			printf("%c ", board[i][j]);//遍历数组每个元素并打印
		}
		printf("|");
		printf("\n");
	}
	printf("-------------------\n");
}

2.3.3 布置雷区

void Set_Mine(char board[ROWS][COLS], int row, int col)
{
	int count = EASY_COUNT;//待布雷的数量
	while (count)
	{
    //通过取余操作将随机坐标控制在指定的横纵坐标内。此处横纵坐标控制在0-8,为了适应操作习惯此处+1将横纵坐标范围划定在1-9内。
		int x_coordinates = rand() % row + 1;
		int y_coordinates = rand() % col + 1;
		if (board[x_coordinates][y_coordinates] != '1')//此处条件判断防止重复布雷
		{
			board[x_coordinates][y_coordinates] = '1';
			count--;//每次布雷后,count减1,直至count为0时,循环终止、布雷结束。
		}
	}
}

2.3.4 排查雷区

2.3.4.1 排雷主函数
void Remove_Mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x_coordinates = 0;
	int y_coordinates = 0;
	int win = 0;
	int show_count = 0;
	while (1)
	{
		printf("Input coordinates:>");
		scanf("%d %d", &x_coordinates, &y_coordinates);//输入雷的坐标
		if (x_coordinates >= 1 && x_coordinates <= row && y_coordinates >= 1 && y_coordinates <= col)//判断确认输入的坐标合法
		{
			if (mine[x_coordinates][y_coordinates] == '1')
			{
                //如果输入的坐标,在雷区中显示为1,那么视作踩雷
				printf("Dead!\n");
				set_time();//计算使用时间
				printf("Game Over!\n");
				Display_Board(mine, ROW, COL);
				printf("Please waiting...");
				Sleep(10000);//延迟10s后跳出循环,随后清屏,重新开始菜单选择
				break;
			}
			else
			{
                //没有踩雷,获取该坐标周围8个位置的雷数总和
				int count = Get_Mine_Count(mine, x_coordinates, y_coordinates);
                //在展示数组中,将该坐标的内容替换为周围雷数总和
				show[x_coordinates][y_coordinates] = count + '0';
                //递归展开
				expand(mine, show, x_coordinates, y_coordinates);
                //遍历展示数组,统计剩余未排雷的数量
				show_count = count_show(show);
                //当剩余雷的数量等于设置的雷的数量时,玩家胜利
				if (show_count == EASY_COUNT)
				{
					printf("You win!\n");
					set_time();//计算使用时间
					Display_Board(show, ROW, COL);
					printf("Please waiting...");
					Sleep(10000);
					break;
				}
				system("cls");//清屏
				printf("Playing...\n");
				Display_Board(show, ROW, COL);
			}
		}
		else
		{
			printf("Coordinates illegal!\n");//坐标输入超出范围后提示非法输入
		}
	}
}

2.3.4.2 获取周围雷区数量

int  Get_Mine_Count(char mine[ROWS][COLS], int x_coordinates, int y_coordinates)
{
	return (
		mine[x_coordinates - 1][y_coordinates] +
		mine[x_coordinates - 1][y_coordinates - 1] +
		mine[x_coordinates][y_coordinates - 1] +
		mine[x_coordinates + 1][y_coordinates - 1] +
		mine[x_coordinates + 1][y_coordinates] +
		mine[x_coordinates + 1][y_coordinates + 1] +
		mine[x_coordinates][y_coordinates + 1] +
		mine[x_coordinates - 1][y_coordinates + 1] - 8 * '0');
}

2.3.4.3 计算使用时间

void set_time()
{
	printf("Take %u seconds.\n", clock() / CLOCKS_PER_SEC);
}//clock函数计算调用进程使用的处理器时间,CLOCKS_PER_SEC表示一秒钟内CPU运行的时钟周期数。
//时钟函数告诉调用进程使用了多少处理器时间。以秒为单位的时间是用时钟返回值除以CLOCKS_PER_SEC常量的值来近似计算的。

2.3.4.4 递归展开

void expand(char mine[ROWS][COLS], char show[ROWS][COLS], int x_coordinates, int y_coordinates)
{
	
	int count = Get_Mine_Count(mine, x_coordinates, y_coordinates);
	if (count == 0)
	{
		show[x_coordinates][y_coordinates] = ' ';
		if (x_coordinates - 1>= 1 && x_coordinates - 1 <= ROW && y_coordinates >= 1 && y_coordinates <= COL && show[x_coordinates - 1][y_coordinates] == '*')
			expand(mine, show, x_coordinates - 1, y_coordinates);
		if (x_coordinates + 1 >= 1 && x_coordinates + 1 <= ROW && y_coordinates >= 1 && y_coordinates <= COL && show[x_coordinates + 1][y_coordinates] == '*')
			expand(mine, show, x_coordinates + 1, y_coordinates);
		if (x_coordinates >= 1 && x_coordinates <= ROW && y_coordinates + 1 >= 1 && y_coordinates + 1<= COL && show[x_coordinates][y_coordinates + 1] == '*')
			expand(mine, show, x_coordinates, y_coordinates + 1);
		if (x_coordinates >= 1 && x_coordinates <= ROW && y_coordinates - 1 >= 1 && y_coordinates - 1<= COL && show[x_coordinates][y_coordinates] - 1 == '*')
			expand(mine, show, x_coordinates, y_coordinates - 1);
	}
	else
	{
		 show[x_coordinates][y_coordinates] = count + '0';
	}
}
//当获取的坐标周边为0时,对每个坐标上下左右的位置进行递归判断,并将展示数组赋值为空格

2.3.4.5 计算展示数组未排雷部分

int count_show(char show[ROWS][COLS])
{
	int row = 0;
	int col = 0;
	int count = 0;
    //遍历数组若元素值为*则计数加1
	for (size_t row = 1; row < 10; row++)
	{
		for (size_t col = 1; col < 10; col++)
		{
			if (show[row][col] == '*')
			{
				count++;
			}
		}
	}
	return count;
}

2.4 效果展示

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


END

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-23 16:27:24  更:2021-08-23 16:27:58 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/27 5:01:34-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计