C++控制台界面扫雷程序(包含所有基本功能)

C++控制台界面扫雷程序

提示:本程序使用了ICUF_HEAD_03.h和ICUF_HEAD_06.h作为头文件。
可以参考:
ICUF_HEAD_03.h
ICUF_HEAD_06.h


开发环境:Visual Studio 2019

一、系统功能分析

系统功能分析图
地图设置功能根据所选择的难度、或者自定义的设置给地图数组赋值。地图生成功能给地图、地图状态、指针状态数组进行初始化,然后用随机数逐一布雷。扫雷操作功能可以用键盘选择各种功能进行扫雷操作,并且正下方显示了各种数据,包括最高分数以及开始时间(分数)。每进行一次操作,就进入胜负判断阶段,如果没有判断出胜或负则返回扫雷操作,如果判断出了胜负则立即停止,并弹出结束界面,如果是失败,还会在地图上显示所有雷的位置。最后从文件中读取分数记录,如果成绩更加优秀则将其存入文件。

二、各功能模块设计与分析

Main

主函数中并没有加入任何可以对程序造成实际影响的代码,因为考虑到后面的功能调用主函数功能时可能会产生不必要的输出,所以主函数设置为一个过渡的函数,后面的每个函数都单独负责一个功能。

MineSweeper

主函数通过调用初始化难度的函数选择数值对变量进行初始化,然后调用地图生成函数通过刚才初始化的数据生成地图,然后在一个无限循环中进行扫雷操作、胜负判断,在胜负判断有结果后停止并调用展示地雷、展示地图和分数功能,玩家此时可以选择继续或者退出程序。

DifficultyInit(int Set)

此函数用于选择难度,默认提供了三种难度:简单、普通、困难。简单难度下是九乘九的地图加十个地雷,普通难度是十六乘十六的地图加四十个地雷,困难难度是十六乘三十的地图加九十九个地雷。此外还提供了一个自定义的功能,可以自己输入X轴、Y轴的长度以及地雷的数量,在玩家输入数据后进行判断,如果地雷数量大于或等于X轴乘Y轴则数据无效,重新返回选择难度界面。传入值Set可以在调用此函数时通过Set值直接选择难度,但在此项目中没有使用此功能。

InitMap(int SetX,int SetY)

此功能先对默认的长数组进行整体赋值,一共设定了三个二维数组:3X3地雷数组、格子状态数组、指针位置数组。在3X3地雷数组中显示周围3X3的格子中雷的数量,数值为0到8,地雷也在这个数组中赋值为9。初始化函数给此数组所有值初始化为2,而不是0,避免指针在边缘翻开格子时因为判断未显示的数组为0而翻开右边和下边一圈的格子。指针位置二维数组一共有8种状态:0. 未翻开状态、1.指向未翻开状态、2.插旗状态、3.指向插旗状态、4.疑问状态、5.指向疑问状态、6.已翻开状态、7.指向已翻开状态。这八种状态都设定为指向时的状态值加一,在后面的移动指针时可以大幅简化代码,此函数在此阶段不初始化。格子状态二维数组只有0和1两个状态,0代表未翻开,1代表已翻开,初始化为0。然后再根据传入的地图X,Y值给三个数组在X,Y部分赋值为0,再用一个循环来逐一添加地雷,如果添加随机到了一样的X,Y坐标则此次循环不执行加一,确保能生成指定数量的地雷,然后整体计算给3X3地雷数组赋值,完成地图初始化的工作。

ShowMap(int SetX, int SetY)

此函数首先根据上面生成的数据和头文件ICUF_HEAD_03.h中的Col输出颜色功能,对游戏界面进行输出,每种状态都对应一种颜色,格子状态数组中的0. 未翻开状态对应白色1.指向未翻开状态对应紫色2.插旗状态对应红色3.指向插旗状态对应黄色4.疑问状态对应蓝色5.指向疑问状态对应淡蓝色6.已翻开状态不绘制颜色7.指向已翻开状态对应紫色。然后用_getch()不回显的获取一个键盘输入,在SWITCH中进行判断,然后执行操作,由于格子状态数组的八种状态都设定为指向时的状态值加一所以在控制指针移动时,只需要给要移动到的地方状态值加一,离开的地方状态值减一即可,省去了复杂繁琐的逐一赋值。SWITCH中除了上下左右的移动还提供了J、L、Q、E四种额外操作,J是插旗功能,L是标记疑问功能,Q是对一个已经揭开的方块根据周围插的旗判断,如果周围一圈的旗子数等于该格子上写的雷数,则翻开周围其他所有未翻开的格子。E则是用来排查问题时加入的功能,按下后会显示所有格子下的数字,再按一次关闭。

CheckZero(int tempX, int tempY)

此功能在翻开格子为0或者按下Q翻开0的格子后启动,对0周围八个格子进行判断,如果有0则继续在另一个0的坐标上执行此函数。无论周围有没有零,其附近的八个格子都会翻开,一直执行下去知道不满足条件为止。为避免两个0相邻然后无限重复执行,加入了一个判断,只有未翻开的格子且下面时0才能执行全部功能。

CheckMap()

对整个地图进行搜索,如果有翻开的地雷格子则立刻判定失败,并显示所有地雷的位置,进入结束界面。然后再判断不为雷的所有格子是否已经翻开,如果是则提示成功输出分数并进入结束界面。

ShowMine()

展示所有地雷,而不展示其他格子。

ShowMapEnd()

结束页面,输出分数。

Rank(int Fun, int goal)

对文件里的分数进行判断,是否打破纪录,是则用此分数覆盖文件里的分数,否则提示未能打破纪录。

三、系统实现

ICUF_HEAD_03.h:

//ICUF HEAD_03.H
#ifndef ICUF_HEAD_03
#define ICUF_HEAD_03
#define CRT_SECURE_NO_DEPRECATE
#define defaultFunction 0
#include<iostream>
#include<conio.h>
using namespace std;
int SystemList(int FunctionMax, int FunctionS);
int BreakWord{};
inline int NumberCheck(int FunctionMax, int Number)//检查循环数字
{
	if (Number > FunctionMax)
	{
		Number = FunctionMax;
		return Number;
	}
	else return Number;
}
inline void ExitSystem()//退出系统功能
{
	exit(1);
}
inline void Col(int ColN)//设置自定义行的背景颜色
{
	if (ColN == 0)cout << "\033[0m";//清除颜色
	else
	{
		cout << "\033[04m\033[1m\033[7m";
		if (ColN == 1)cout << "\033[31m";//红色
		else if (ColN == 2)cout << "\033[32m";//绿色
		else if (ColN == 3)cout << "\033[33m";//黄色
		else if (ColN == 4)cout << "\033[34m";//蓝色
		else if (ColN == 5)cout << "\033[35m";//紫色
		else if (ColN == 6)cout << "\033[36m";//淡蓝
		else if (ColN == 7)cout << "\033[37m";//白色
	}
}
inline int PageService(char PageWord)
{
	if (PageWord == 'Z')return 1;//上一页
	if (PageWord == 'X')return 2;//下一页
	if (PageWord == 'C')return 3;//返回
	else return 0;
}
int SystemList(int FunctionMax, int FunctionS)//FunctionMax为表格最大行数FunctionS为选择序号
{
	char CHOICE = _getch();
	switch (CHOICE)
	{
	case '1': FunctionS = NumberCheck(FunctionMax, 1); ::BreakWord = 1; break;
	case '2': FunctionS = NumberCheck(FunctionMax, 2); ::BreakWord = 1; break;
	case '3': FunctionS = NumberCheck(FunctionMax, 3); ::BreakWord = 1; break;
	case '4': FunctionS = NumberCheck(FunctionMax, 4); ::BreakWord = 1; break;
	case '5': FunctionS = NumberCheck(FunctionMax, 5); ::BreakWord = 1; break;
	case '6': FunctionS = NumberCheck(FunctionMax, 6); ::BreakWord = 1; break;
	case '7': FunctionS = NumberCheck(FunctionMax, 7); ::BreakWord = 1; break;
	case '8': FunctionS = NumberCheck(FunctionMax, 8); ::BreakWord = 1; break;
	case '9': FunctionS = NumberCheck(FunctionMax, 9); ::BreakWord = 1; break;
	case 72:
	case 'W':
	case 'w':
		if (FunctionS == 1)
		{
			FunctionS = FunctionMax;
			break;
		}
		FunctionS--;
		break;
	case 80:
	case 'S':
	case 's':
		if (FunctionS == FunctionMax)
		{
			FunctionS = 1;
			break;
		}
		FunctionS++;
		break;
	case 'z':
	case 'Z': FunctionS = 'Z'; ::BreakWord = 1; break;
	case 'x':
	case 'X': FunctionS = 'X'; ::BreakWord = 1; break;
	case 'c':
	case 'C': FunctionS = 'C'; ::BreakWord = 1; break;
	case '\r':
		::BreakWord = 1;
		break;
	}
	return FunctionS;
}
#endif

MineSweeper.cpp:

#include<iostream>
#include<fstream>
#include<conio.h>
#include<time.h>
#include<ctime>
#include"ICUF_HEAD_03.h"
const char* F1 = "ICUF_File.txt";
using namespace std;
int DifficultyInit(int Set);
int MineSweeper();
int InitMap(int SetX,int SetY);
int ShowMap(int SetX, int SetY);
void ShowMine();
void ShowMapEnd();
void Rank(int Fun, int goal);
int CheckMap();
int CheckZero(int KeyX, int KeyY);
int Difficulty{};
int mine{}, Xmax{}, Ymax{};
int Map[200][200];
int MapC[200][200];
int Key[200][200];
int AdminMode{};
int TEMP{}, end{};
int KeyX = 0, KeyY = 0;
ifstream fin;
ofstream fout;
clock_t startTime, endTime;
int main()
{
	cout << "\033[04m\033[1m\033[7m";
	cout << "\033[37m                                    " << endl;
	cout << "\033[31m          \033[37m  \033[31m  \033[37m  \033[31m        \033[37m  \033[31m        \033[37m  " << endl;
	cout << "\033[31m  \033[37m  \033[31m  \033[37m  \033[31m  \033[37m      \033[31m  \033[37m    \033[31m  \033[37m  \033[31m  \033[37m        "; Col(0); cout << "         Wild Chicken Programing TANXL" << endl;
	Col(1); cout << "\033[31m  \033[37m  \033[31m  \033[37m  \033[31m  \033[37m  \033[31m  \033[37m  \033[31m  \033[37m    \033[31m  \033[37m  \033[31m        \033[37m  "; Col(0); cout << "             WiChP 2020/11/25 00:31" << endl;
	Col(1); cout << "\033[31m  \033[37m  \033[31m  \033[37m  \033[31m  \033[37m  \033[31m  \033[37m  \033[31m  \033[37m    \033[31m  \033[37m  \033[31m  \033[37m        " << endl;
	cout << "\033[31m  \033[37m      \033[31m  \033[37m  \033[31m  \033[37m  \033[31m  \033[37m    \033[31m  \033[37m  \033[31m        \033[37m  " << endl;
	cout << "\033[37m                                    " << endl;
	cout << "\033[37m                                                                                   " << endl;
	cout << "\033[37m           \033[31m        \033[37m  \033[31m  \033[37m      \033[31m  \033[37m  \033[31m        \033[37m  \033[31m        \033[37m  \033[31m        \033[37m  \033[31m        \033[37m  \033[31m        \033[37m  " << endl;
	cout << "\033[37m           \033[31m  \033[37m        \033[31m  \033[37m  \033[31m  \033[37m  \033[31m  \033[37m  \033[31m  \033[37m        \033[31m  \033[37m        \033[31m  \033[37m    \033[31m  \033[37m  \033[31m  \033[37m        \033[31m  \033[37m    \033[31m  \033[37m  " << endl;
	cout << "\033[37m           \033[31m        \033[37m  \033[31m  \033[37m  \033[31m  \033[37m  \033[31m  \033[37m  \033[31m        \033[37m  \033[31m        \033[37m  \033[31m        \033[37m  \033[31m        \033[37m  \033[31m        \033[37m  " << endl;
	cout << "\033[37m                 \033[31m  \033[37m  \033[31m  \033[37m  \033[31m  \033[37m  \033[31m  \033[37m  \033[31m  \033[37m        \033[31m  \033[37m        \033[31m  \033[37m        \033[31m  \033[37m        \033[31m  \033[37m  \033[31m  \033[37m    " << endl;
	cout << "\033[37m           \033[31m        \033[37m  \033[31m          \033[37m  \033[31m        \033[37m  \033[31m        \033[37m  \033[31m  \033[37m        \033[31m        \033[37m  \033[31m  \033[37m  \033[31m    \033[37m  " << endl;
	cout << "\033[37m                                                                                   " << endl;
	Col(0);
	cout << "\n\n\n\n\n"; Col(1); cout << "                "; Col(1);
	system("pause"); Col(0);
	MineSweeper();
}
int MineSweeper()
{
	Difficulty = DifficultyInit(0);
	switch (Difficulty)
	{
	case 1:
		mine = 10;
		Xmax = 9;
		Ymax = 9;
		break;
	case 2:
		mine = 40;
		Xmax = 16;
		Ymax = 16;
		break;
	case 3:
		mine = 99;
		Xmax = 16;
		Ymax = 30;
		break;
	case 4:
		cout << "请输入X轴的最大值 X= ";
		cin >> Xmax;
		cout << "请输入Y轴的最大值 Y= ";
		cin >> Ymax;
		cout << "请输入地雷数量 mine= ";
		cin >> mine;
		if (mine >= Xmax * Ymax)
		{
			cout << "地雷数量不满足要求";
			MineSweeper();
		}
		break;
	default:
		cout << "功能异常";
		break;
	}
	Key[0][0] = 1;
	InitMap(Xmax, Ymax);
	while (1)
	{
		startTime = clock();
		::end = 1;
		ShowMap(Xmax, Ymax);
		if (CheckMap()==1||CheckMap() == 2)
		{
			endTime = clock();
			ShowMine();
			ShowMapEnd();
			cout << "你总计用时: " << (startTime) / CLOCKS_PER_SEC << "s" << endl;
			int TempTime = (startTime) / CLOCKS_PER_SEC;
			if (CheckMap() == 2)
				Rank(0, TempTime);
			cout << "是否继续? Y/N";
			char x = _getch();
			switch(x)
			{
			case'Y':
			case'y':
				InitMap(Xmax, Ymax);
				continue;
			case'N':
			case'n':
				BreakWord = 1;
				break;
			}
			if (BreakWord == 1)break;
		}
	}
	system("pause");
	return 0;
}
int DifficultyInit(int Set)
{
	int SystemFunction{ 1 };
	int SystemListS{ 0 };
	int CheckPage{};
	BreakWord = 0;
	while (1)
	{
		system("cls");
		switch (Set)
		{
		case 0://入口界面
			while (1)
			{
				system("cls");//此循环部分使用了ICUF_HEAD_03.h的标准模板
				Col(1); cout << "\n\n\n\n                         请选择难度  WiChP_TANXL             \n\n"; Col(0);
				if (SystemFunction == 1) Col(7);
				else Col(1);
				cout << "                简单                 \n\n"; Col(0);//1
				if (SystemFunction == 2) Col(7);
				else Col(1);
				cout << "                中等                 \n\n"; Col(0);//2
				if (SystemFunction == 3) Col(7);
				else Col(1);
				cout << "                困难                 \n\n"; Col(0);//3
				if (SystemFunction == 4) Col(7);
				else Col(1);
				cout << "               自定义                \n\n"; Col(0);//4
				CheckPage = PageService(SystemFunction);
				if (CheckPage == 1) { cout << "此页面没有上一页"; CheckPage = 0; }
				if (CheckPage == 2) { cout << "此页面没有下一页"; CheckPage = 0; }
				if (CheckPage == 3) { cout << "此页面没有前一页"; CheckPage = 0; }
				if (BreakWord == 1)break;
				SystemFunction = SystemList(4, SystemFunction);//循环赋值
			}
			return SystemFunction;
		default:
			break;
		}
		if (BreakWord == 1)break;
	}
	return 0;
}
int InitMap(int SetX,int SetY)
{
	srand(time(0));
	for (int x = 0; x < 200; x++)
	{
		for (int y = 0; y < 200; y++)
		{
			Map[x][y] = 2;
			MapC[x][y] = 1;
		}
	}
	for (int x = 0; x < SetX; x++)//生成地图
	{
		for (int y = 0; y < SetY; y++)
		{
			Map[x][y] = 0;
			MapC[x][y] = 0;
			Key[x][y] = 0;
		}
	}
	KeyX = 0;
	KeyY = 0;
	Key[KeyX][KeyY] = 1; //Key[x][y] = 1;
	for (int i = 0; i < mine;)//生成地雷
	{
		int RandomX = rand() % (SetX - 2) + 1;
		int RandomY = rand() % (SetY - 2) + 1;
		if (Map[RandomX][RandomY] != 9)
		{
			Map[RandomX][RandomY] = 9;
			i++;
		}
	}
	for (int x = 0; x < SetX; x++)//生成数字
	{
		for (int y = 0; y < SetY; y++)
		{
			if (Map[x][y] == 9)
			{
				;//检测到是地雷,不做任何操作
			}
			else
			{
				if (x == 0 && y != 0 && y != SetY - 1)//第一部分中上
				{
					if (Map[x + 1][y] == 9)Map[x][y]++;//下
					if (Map[x][y - 1] == 9)Map[x][y]++;//左
					if (Map[x][y + 1] == 9)Map[x][y]++;//右
					if (Map[x + 1][y - 1] == 9)Map[x][y]++;//左下
					if (Map[x + 1][y + 1] == 9)Map[x][y]++;//右下
				}
				else if (y == 0 && x != 0 && x != SetX - 1)//第二部分中左
				{
					if (Map[x - 1][y] == 9)Map[x][y]++;//上
					if (Map[x + 1][y] == 9)Map[x][y]++;//下
					if (Map[x][y + 1] == 9)Map[x][y]++;//右
					if (Map[x - 1][y + 1] == 9)Map[x][y]++;//右上
					if (Map[x + 1][y + 1] == 9)Map[x][y]++;//右下
				}
				else if (x == SetX - 1 && y != 0 && y != SetY - 1)//第三部分中下
				{
					if (Map[x - 1][y] == 9)Map[x][y]++;//上
					if (Map[x][y - 1] == 9)Map[x][y]++;//左
					if (Map[x][y + 1] == 9)Map[x][y]++;//右
					if (Map[x - 1][y - 1] == 9)Map[x][y]++;//左上
					if (Map[x - 1][y + 1] == 9)Map[x][y]++;//右上
				}
				else if (y == SetY - 1 && x != 0 && x != SetX - 1)//第四部分中右
				{
					if (Map[x - 1][y] == 9)Map[x][y]++;//上
					if (Map[x + 1][y] == 9)Map[x][y]++;//下
					if (Map[x][y - 1] == 9)Map[x][y]++;//左
					if (Map[x - 1][y - 1] == 9)Map[x][y]++;//左上
					if (Map[x + 1][y - 1] == 9)Map[x][y]++;//左下
				}
				else if (x == 0 && y == 0)//第六部分左上
				{
					if (Map[x + 1][y] == 9)Map[x][y]++;//下
					if (Map[x][y + 1] == 9)Map[x][y]++;//右
					if (Map[x + 1][y + 1] == 9)Map[x][y]++;//右下
				}
				else if (x == 0 && y == SetY - 1)//第六部分右上
				{
					if (Map[x + 1][y] == 9)Map[x][y]++;//下
					if (Map[x][y - 1] == 9)Map[x][y]++;//左
					if (Map[x + 1][y - 1] == 9)Map[x][y]++;//左下
				}
				else if (x == SetX - 1 && y == 0)//第六部分左下
				{
					if (Map[x - 1][y] == 9)Map[x][y]++;//上
					if (Map[x][y + 1] == 9)Map[x][y]++;//右
					if (Map[x - 1][y + 1] == 9)Map[x][y]++;//右上
				}
				else if (x == SetX - 1 && y == SetY - 1)//第六部分右下
				{
					if (Map[x - 1][y] == 9)Map[x][y]++;//上
					if (Map[x][y - 1] == 9)Map[x][y]++;//左
					if (Map[x - 1][y - 1] == 9)Map[x][y]++;//左上
				}
				else if (x > 0 && x < SetX - 1 && y>0 && y < SetY - 1)//第五部分中间
				{
					if (Map[x - 1][y] == 9)Map[x][y]++;//上
					if (Map[x + 1][y] == 9)Map[x][y]++;//下
					if (Map[x][y - 1] == 9)Map[x][y]++;//左
					if (Map[x][y + 1] == 9)Map[x][y]++;//右
					if (Map[x - 1][y - 1] == 9)Map[x][y]++;//左上
					if (Map[x - 1][y + 1] == 9)Map[x][y]++;//右上
					if (Map[x + 1][y - 1] == 9)Map[x][y]++;//左下
					if (Map[x + 1][y + 1] == 9)Map[x][y]++;//右下
				}
			}
		}
	}
	return 0;
}
int ShowMap(int SetX, int SetY)
{
	system("cls");
	Col(3); cout << "操作方法:WASD或↑↓←→移动指针,J插旗L标记 回车键翻开格子";
	Col(0);
	cout << endl << "Wild_Chicken_Programing TANXL 2020/11/25 00:31" << endl;
	Col(3); cout << "额外功能 Q:3X3方格自动点开 E:展示所有数字 Z:返回";
	Col(0); cout << endl << endl << "X" << endl;
	for (int x = 0; x < SetX; x++)//输出地图
	{
		cout << x + 1 << "\t";
		for (int y = 0; y < SetY; y++)
		{
			if (Map[x][y] >= 0 && Map[x][y] <= 9)
			{
				//Key[x][y] == 0;//空白状态
				//Key[x][y] == 1;//指针当前位置
				//Key[x][y] == 2;//插旗状态
				//Key[x][y] == 3;//指向插旗状态
				//Key[x][y] == 4;//疑问状态
				//Key[x][y] == 5;//指向疑问状态
				//Key[x][y] == 6;//已翻开状态
				//Key[x][y] == 7;//指向已翻开状态
				if (Key[x][y] == 1)Col(5);
				else if (Key[x][y] == 2)Col(1);
				else if (Key[x][y] == 3)Col(3);
				else if (Key[x][y] == 4)Col(4);
				else if (Key[x][y] == 5)Col(6);
				else if (Key[x][y] == 6)Col(2);
				else Col(7);
				if (MapC[x][y] == 1)cout << "\033[0m";
				if (Key[x][y] == 1)Col(5);
				cout << " ";
				if (AdminMode == 1)cout << Map[x][y] << " ";
				else if (MapC[x][y] == 1)cout << Map[x][y] << " ";
				else cout << "  ";
			}
		}
		Col(0);
		cout << endl;
	}
	cout << endl << endl << endl;
	cout << "\t\t指针坐标 X:" << KeyX + 1 << "\tY:" << KeyY + 1 << endl;
	cout << "\t\t当前格子状态: ";
	if (MapC[KeyX][KeyY] == 1)cout << "指向翻开状态";
	else if(Key[KeyX][KeyY] == 1)cout << "指向未翻开状态";
	if (Key[KeyX][KeyY] == 3)cout << "指向插旗状态";
	if (Key[KeyX][KeyY] == 5)cout << "指向疑问状态";
	if (Key[KeyX][KeyY] == 7)cout << "指向已翻开状态";
	cout << endl << "\t\t所使用的时间:" << (startTime) / CLOCKS_PER_SEC << "s" << endl;
	cout << "\t\t最短完成时间: "; Rank(1, 0);
	char movekey = _getch();
	switch (movekey)
	{
		// 使用颜色重叠实现
	case 72:
	case 'W':
	case 'w':
		if (KeyX == 0)break;
		if (Key[KeyX - 1][KeyY] == 9)break;
		Key[KeyX - 1][KeyY] ++;
		if (Key[KeyX][KeyY] == 1)Key[KeyX][KeyY]--;
		if (Key[KeyX][KeyY] == 3)Key[KeyX][KeyY]--;
		if (Key[KeyX][KeyY] == 5)Key[KeyX][KeyY]--;
		if (Key[KeyX][KeyY] == 7)Key[KeyX][KeyY]--;
		KeyX--;
		break;
	case 80:
	case 'S':
	case 's':
		if (KeyX == SetX - 1)break;
		if (Key[KeyX + 1][KeyY] == 9)break;
		Key[KeyX + 1][KeyY] ++;
		if (Key[KeyX][KeyY] == 1)Key[KeyX][KeyY]--;
		if (Key[KeyX][KeyY] == 3)Key[KeyX][KeyY]--;
		if (Key[KeyX][KeyY] == 5)Key[KeyX][KeyY]--;
		if (Key[KeyX][KeyY] == 7)Key[KeyX][KeyY]--;
		KeyX++;
		break;
	case 75:
	case'A':
	case'a':
		if (KeyY == 0)break;
		if (Key[KeyX][KeyY - 1] == 9)break;
		Key[KeyX][KeyY - 1] ++;
		if (Key[KeyX][KeyY] == 1)Key[KeyX][KeyY]--;
		if (Key[KeyX][KeyY] == 3)Key[KeyX][KeyY]--;
		if (Key[KeyX][KeyY] == 5)Key[KeyX][KeyY]--;
		if (Key[KeyX][KeyY] == 7)Key[KeyX][KeyY]--;
		KeyY--;
		break;
	case 77:
	case'D':
	case'd':
		if (KeyY == SetY - 1)break;
		if (Key[KeyX][KeyY + 1] == 9)break;
		Key[KeyX][KeyY + 1] ++;
		if (Key[KeyX][KeyY] == 1)Key[KeyX][KeyY]--;
		if (Key[KeyX][KeyY] == 3)Key[KeyX][KeyY]--;
		if (Key[KeyX][KeyY] == 5)Key[KeyX][KeyY]--;
		if (Key[KeyX][KeyY] == 7)Key[KeyX][KeyY]--;
		KeyY++;
		break;
	case'J':
	case'j':
		//插旗子
		if (Key[KeyX][KeyY] == 1 && MapC[KeyX][KeyY] == 0)Key[KeyX][KeyY] = 3;
		else Key[KeyX][KeyY] = 1;
		break;
	case'L':
	case'l':
		//做标记
		if (Key[KeyX][KeyY] == 1 && MapC[KeyX][KeyY] == 0)Key[KeyX][KeyY] = 5;
		else Key[KeyX][KeyY] = 1;
		break;
	case'\r':
		//确认选择
		MapC[KeyX][KeyY] = 1;
		if (Map[KeyX][KeyY] == 0)CheckZero(KeyX, KeyY);
		if (Key[KeyX][KeyY] == 3) { MapC[KeyX][KeyY] = 0; break; }
		break;
	case'Q':
	case'q':
		if (MapC[KeyX][KeyY] == 0)break;
		TEMP = 0;
		if (Key[KeyX - 1][KeyY] == 2)TEMP++;//上
		if (Key[KeyX + 1][KeyY] == 2)TEMP++;//下
		if (Key[KeyX][KeyY - 1] == 2)TEMP++;//左
		if (Key[KeyX][KeyY + 1] == 2)TEMP++;//右
		if (Key[KeyX - 1][KeyY - 1] == 2)TEMP++;//左上
		if (Key[KeyX - 1][KeyY + 1] == 2)TEMP++;//右上
		if (Key[KeyX + 1][KeyY - 1] == 2)TEMP++;//左下
		if (Key[KeyX + 1][KeyY + 1] == 2)TEMP++;//右下
		cout << Key[KeyX][KeyY] << "  " << TEMP;
		if (Map[KeyX][KeyY] == TEMP)
		{
			if (Key[KeyX][KeyY] == 0 || Key[KeyX][KeyY] == 5)
			{
				MapC[KeyX][KeyY] = 1;
				CheckZero(KeyX, KeyY);
			}
			if (Key[KeyX - 1][KeyY] == 0 || Key[KeyX - 1][KeyY] == 5)
			{
				MapC[KeyX - 1][KeyY] = 1;
				CheckZero(KeyX - 1, KeyY);
			}
			if (Key[KeyX + 1][KeyY] == 0 || Key[KeyX + 1][KeyY] == 5)
			{
				MapC[KeyX + 1][KeyY] = 1;
				CheckZero(KeyX + 1, KeyY);
			}
			if (Key[KeyX][KeyY - 1] == 0 || Key[KeyX][KeyY - 1] == 5)
			{
				MapC[KeyX][KeyY - 1] = 1;
				CheckZero(KeyX, KeyY - 1);
			}
			if (Key[KeyX][KeyY + 1] == 0 || Key[KeyX][KeyY + 1] == 5)
			{
				MapC[KeyX][KeyY + 1] = 1;
				CheckZero(KeyX, KeyY + 1);
			}
			if (Key[KeyX - 1][KeyY - 1] == 0 || Key[KeyX - 1][KeyY - 1] == 5)
			{
				MapC[KeyX - 1][KeyY - 1] = 1;
				CheckZero(KeyX - 1, KeyY - 1);
			}
			if (Key[KeyX - 1][KeyY + 1] == 0 || Key[KeyX - 1][KeyY + 1] == 5)
			{
				MapC[KeyX - 1][KeyY + 1] = 1;
				CheckZero(KeyX - 1, KeyY + 1);
			}
			if (Key[KeyX + 1][KeyY - 1] == 0 || Key[KeyX + 1][KeyY - 1] == 5)
			{
				MapC[KeyX + 1][KeyY - 1] = 1;
				CheckZero(KeyX + 1, KeyY - 1);
			}
			if (Key[KeyX + 1][KeyY + 1] == 0 || Key[KeyX + 1][KeyY + 1] == 5)
			{
				MapC[KeyX + 1][KeyY + 1] = 1;
				CheckZero(KeyX + 1, KeyY + 1);
			}
		}
		break;
	case'E':
	case'e':
		//展示所有数字
		if (AdminMode == 0)AdminMode = 1;
		else AdminMode = 0;
		break;
	case'Z':
	case'z':
		//返回
		MineSweeper();
		break;
	}
	return 0;
}
int CheckZero(int tempX, int tempY)
{
	MapC[tempX][tempY] = 1;
	if (Map[tempX][tempY] == 0 && tempX >= 1)//X-1 Y
	{
		if (MapC[tempX - 1][tempY] == 0)
		{
			MapC[tempX - 1][tempY] = 1;
			if (Map[tempX - 1][tempY] == 0)
				CheckZero(tempX - 1, tempY);
		}
	}
	if (Map[tempX][tempY] == 0 && tempX <= Xmax - 1)//X+1 Y
	{
		if (MapC[tempX + 1][tempY] == 0)
		{
			MapC[tempX + 1][tempY] = 1;
			if (Map[tempX + 1][tempY] == 0)
				CheckZero(tempX + 1, tempY);
		}
	}
	if (Map[tempX][tempY] == 0 && tempY >= 1)//X Y-1
	{
		if (MapC[tempX][tempY - 1] == 0)
		{
			MapC[tempX][tempY - 1] = 1;
			if (Map[tempX][tempY - 1] == 0)
				CheckZero(tempX, tempY - 1);
		}
	}
	if (Map[tempX][tempY] == 0 && tempY <= Ymax - 1)//X Y+1
	{
		if (MapC[tempX][tempY + 1] == 0)
		{
			MapC[tempX][tempY + 1] = 1;
			if (Map[tempX][tempY + 1] == 0)
				CheckZero(tempX, tempY + 1);
		}
	}
	if (Map[tempX][tempY] == 0 && tempX >= 1 && tempY <= Ymax - 1)//X-1 Y+1
	{
		if (MapC[tempX - 1][tempY + 1] == 0)
		{
			MapC[tempX - 1][tempY + 1] = 1;
			if (Map[tempX - 1][tempY + 1] == 0)
				CheckZero(tempX - 1, tempY + 1);
		}
	}
	if (Map[tempX][tempY] == 0 && tempX >= 1 && tempY >= 1)//X-1 Y-1
	{
		if (MapC[tempX - 1][tempY - 1] == 0)
		{
			MapC[tempX - 1][tempY - 1] = 1;
			if (Map[tempX - 1][tempY - 1] == 0)
				CheckZero(tempX - 1, tempY - 1);
		}
	}
	if (Map[tempX][tempY] == 0 && tempX <= Xmax - 1 && tempY >= 1)//X+1 Y-1
	{
		if (MapC[tempX + 1][tempY - 1] == 0)
		{
			MapC[tempX + 1][tempY - 1] = 1;
			if (Map[tempX + 1][tempY - 1] == 0)
				CheckZero(tempX + 1, tempY - 1);
		}
	}
	if (Map[tempX][tempY] == 0 && tempX <= Xmax - 1 && tempY <= Ymax - 1)//X+1 Y+1
	{
		if (MapC[tempX + 1][tempY + 1] == 0)
		{
			MapC[tempX + 1][tempY + 1] = 1;
			if (Map[tempX + 1][tempY + 1] == 0)
				CheckZero(tempX + 1, tempY + 1);
		}
	}
	return 0;
}
int CheckMap()
{
	int count{};
	for (int x = 0; x < Xmax; x++)
	{
		for (int y = 0; y < Ymax; y++)
		{
			if (Map[x][y] == 9 && MapC[x][y] == 1)
			{
				cout << endl << endl << "失败!" << endl;
				::end = 2;
				return 1;
			}
			if (Map[x][y] != 9 && MapC[x][y] == 0)
			{
				count++;
			}
		}
	}
	if (count == 0)
	{
		cout << endl << endl << "成功!" << endl;
		::end = 1;
		return 2;
	}
	return 0;
}
void ShowMine()
{
	for (int x = 0; x < Xmax; x++)
	{
		for (int y = 0; y < Ymax; y++)
		{
			if (Map[x][y] == 9)MapC[x][y] = 1;
		}
	}
}
void ShowMapEnd()
{
	system("cls");
	cout << endl << endl << endl;
	Col(0); cout << endl << endl << "X" << endl;
	for (int x = 0; x < Xmax; x++)//输出地图
	{
		cout << x + 1 << "\t";
		for (int y = 0; y < Ymax; y++)
		{
			if (Map[x][y] >= 0 && Map[x][y] <= 9)
			{
				if (Key[x][y] == 1)Col(5);
				else if (Key[x][y] == 2)Col(1);
				else if (Key[x][y] == 3)Col(3);
				else if (Key[x][y] == 4)Col(4);
				else if (Key[x][y] == 5)Col(6);
				else if (Key[x][y] == 6)Col(2);
				else Col(7);
				if (MapC[x][y] == 1)cout << "\033[0m";
				if (Key[x][y] == 1)Col(5);
				cout << " ";
				if (AdminMode == 1)cout << Map[x][y] << " ";
				else if (MapC[x][y] == 1)cout << Map[x][y] << " ";
				else cout << "  ";
			}
		}
		Col(0);
		cout << endl;
	}
}
void Rank(int Fun, int goal)
{
	int Fgoal;
	if (Fun == 1)
	{
		fin.open(F1);
		fin >> Fgoal;
		fin.close();
		if (Fgoal < 0)Fgoal = 999;
		cout << Fgoal;
	}
	else
	{
		fin.open(F1);
		fin >> Fgoal;
		fin.close();
		if (Fgoal < 0)Fgoal = 999;
		if (Fgoal < goal)
		{
			cout << "未能打破纪录";
		}
		else
		{
			cout << "成功打破纪录";
			Fgoal = goal;
			fout.open(F1);
			fout << goal;
			fout.close();
		}
	}
}

开始界面

开始界面

难度选择

难度选择

运行阶段

展示所有数字功能(9为雷)
在这里插入图片描述
红色为插旗,蓝色为疑问
在这里插入图片描述
失败界面
在这里插入图片描述
翻开后的反应
在这里插入图片描述
2020/12/1 23:20 纠正了188行的错误
Key[x][y] = 1; (Key[KeyX][KeyY] = 1;)


四、2021/7/7 更新 使用ICUF_HEAD_06.h版本的扫雷

简介

2021/7/7的更新将老版本的编号03控制台输出头文件换成了最新的06版本,同时老版本扫雷中的大量问题得以解决。

1、老版本将地图分为9个区块的“田字形”用以检测边界,在此版本中分为2个区块的“回字形”,大大简化了计算,但是数组会因此变大。
2、界面主题换成了蓝色。
3、解决了文件流的问题。
4、修复了胜负判断错误的问题。
5、失败时显示地雷的阶段,地雷的背景颜色从无改为更明显的蓝色。
6、删除少量冗余代码。

ICUF_HEAD_06.h

//ICUF_HEAD_06.H

#ifndef ICUF_HEAD_06
#define ICUF_HEAD_06
#include <iostream>
#include <string>
#include <fstream>
#include <conio.h>
#include <iomanip>
using namespace std;
ofstream fout;
ifstream fin;
const char* HeadFile = "HeadFile.txt";
inline void Col(int ColN)//设置自定义行的背景颜色
{
	if (ColN == 0)cout << "\033[0m";//清除颜色
	else
	{
		cout << "\033[4;1;7m";
		if (ColN == 1)cout << "\033[31m";//背景红色
		else if (ColN == 2)cout << "\033[32m";//背景绿色
		else if (ColN == 3)cout << "\033[33m";//背景黄色
		else if (ColN == 4)cout << "\033[34m";//背景蓝色
		else if (ColN == 5)cout << "\033[35m";//背景紫色
		else if (ColN == 6)cout << "\033[36m";//背景淡蓝
		else if (ColN == 7)cout << "\033[37m";//背景白色
		else if (ColN == 8)Col((rand() % 6) + 1);//随机颜色(1-7)
		else if (ColN == 11)cout << "\033[41m";//字体红色
		else if (ColN == 12)cout << "\033[42m";//字体绿色
		else if (ColN == 13)cout << "\033[43m";//字体黄色
		else if (ColN == 14)cout << "\033[44m";//字体蓝色
		else if (ColN == 15)cout << "\033[45m";//字体紫色
		else if (ColN == 16)cout << "\033[46m";//字体淡蓝
		else if (ColN == 17)cout << "\033[47m";//字体白色
		else if (ColN == 18)Col((rand() % 6) + 11);//随机颜色(11-17)
	}
}
class FunctionList
{
public:int Page{ 1 };
public:int Times{};//用于计算某一函数的执行次数,同时用于限定某些代码只执行一次
public:int TempTimes{};
public:int FunctionNumbers = 0;//表示类中含有的字符串数量
public:virtual void SetCol(int ColS, int ColU, int ColD = 7)
{
	this->SelectedCol = ColS;
	this->UnSelectedCol = ColU;
	this->DefaultCol = ColD;
}
public:void RecoverTimes()//复原被转移的Times值
{
	this->Times += ++this->TempTimes;
	this->TempTimes = 0;
}
public:void ResetTimes()//将Times的值转移到TempTimes
{
	this->TempTimes += ++this->Times;
	this->Times = 0;
}
public:void InitList(int Start = 0)//列表初始化函数,默认初始化第一个选项为选定状态
{
	for (int i = 0; i < FunctionNumbers; i++)
	{
		ListStatus[i] = 0;
	}
	for (int i = FunctionNumbers; i < 50; i++)
	{
		ListStatus[i] = -1;
	}
	ListStatus[Start] = 1;
}
public:virtual void DisplayList(int LStart = 0, int LEnd = 9, int Switch = 0)//显示列表 ICUF_H_06中添加两个默认参数,可用于显示指定行
{
	int Start = (Page - 1) * LimitListEachPage;
	int End = Start + LimitListEachPage;
	int UnSeCol = UnSelectedCol;
	if (Switch == 1)//Switch值为1时 显示此页面的各种基本信息
		cout << "FunId: " << CheckCurrent() << "  Limit: " << LimitListEachPage << "  Page: " << Page << "  Start: " << Start << "  End: " << End << endl << endl;
	if (Switch == 2)//Switch值为2时 输出子页面的列表 且使用子页面的颜色
		UnSeCol = TempCol;
	for (int i = Start + LStart; i < End + (LEnd - LimitListEachPage); i++)
	{
		if (ListStatus[i] != -1)
		{
			if (ListStatus[i] == 1)
				Col(SelectedCol);
			else
				Col(UnSeCol);
			cout << setw(23) << List[i] << setw(16) << " " << endl;
			if (Switch != 2)
				cout << endl;
			Col(0);
		}
	}
	if (Switch == 2)
		cout << endl;
}
public:int InsertAction()//输入控制
{
	char Key;
	int Temp;
	Key = _getch();
	if (Key == 'c' || Key == 'C')//如果输入了大小写的C则返回上一级
		return 3;
	if (FunctionNumbers == 0)
		return 0;
	if ((int)(Key - 48) > 0 && (int)(Key - 48) <= 9)//判断是否是从零到九的数字
	{
		if ((int)(Key - 48) > FunctionNumbers)//如果是,且小于等于选项总数则直接指定这个选项
			InitList(FunctionNumbers - 1);
		else
			InitList((int)(Key - 48) - 1);//如果超出了最大值,则指向最大值
		return 4;
	}
	else if (Key == 'w' || Key == 'W' || Key == 72)//如果输入了大小写的W或者上箭头,则执行MoveUp函数
	{
		MoveUp();
		return 0;
	}
	else if (Key == 's' || Key == 'S' || Key == 80)//如果输入了大小写的S或者下箭头,则执行MoveDown函数
	{
		MoveDown();
		return 0;
	}
	else if (Key == 'a' || Key == 'A' || Key == 75)//如果输入了大小写的A或者左箭头,则执行向上翻页函数
	{
		if (Page == GetPages() && GetPages() == 1)
		{
			Temp = CheckCurrent();
			ListStatus[Temp] = 0;
			ListStatus[0] = 1;
		}
		else if (Page != 1)
		{
			Page--;
			Temp = CheckCurrent();
			ListStatus[Temp] = 0;
			ListStatus[Temp - LimitListEachPage] = 1;
		}
		else
		{
			Page = GetPages();
			Temp = CheckCurrent();
			ListStatus[Temp] = 0;
			ListStatus[(Page - 1) * LimitListEachPage] = 1;
		}
		return 0;
	}
	else if (Key == 'd' || Key == 'D' || Key == 77)//如果输入了大小写的D或者右箭头,则执行向下翻页函数
	{
		if (Page == GetPages() && GetPages() == 1)
		{
			Temp = CheckCurrent();
			ListStatus[Temp] = 0;
			ListStatus[FunctionNumbers - 1] = 1;
		}
		else if (Page != GetPages())
		{
			Page++;
			Temp = CheckCurrent();
			ListStatus[Temp] = 0;
			if (Temp + LimitListEachPage >= FunctionNumbers - 1)
				ListStatus[FunctionNumbers - 1] = 1;
			else
				ListStatus[Temp + LimitListEachPage] = 1;
		}
		else
		{
			Page = 1;
			Temp = CheckCurrent();
			ListStatus[Temp] = 0;
			ListStatus[Temp % LimitListEachPage] = 1;
		}
		return 0;
	}
	else if (Key == 'z' || Key == 'Z')//保留原功能的情况下,预留两个用户自定义返回值
	{
		return 1;
	}
	else if (Key == 'x' || Key == 'X')
	{
		return 2;
	}
	else if (Key == '\r')//回车确认
		return 4;
	return 0;
}
public:void MoveUp()//选项上移
{
	int i = CheckCurrent();//找到当前指向的选项
	if (i == 0 && FunctionNumbers == 1)//如果只有一个选项则不变
		ListStatus[i] = 1;
	else if (i == 0 && FunctionNumbers != 1)//如果指向第一个且不止包含一个选项,则改为指向最下方的选项
	{
		ListStatus[i] = 0;
		Page = GetPages();
		ListStatus[FunctionNumbers - 1] = 1;
	}
	else if ((i + 1) % LimitListEachPage == 1)//如果指向某一页面的第一项则翻页,并指向前一页的最后一项
	{
		if (Page != 1)
		{
			Page--;
			ListStatus[i] = 0;
			ListStatus[i - 1] = 1;
		}
		else
		{
			Page = GetPages();
			ListStatus[i] = 0;
			ListStatus[FunctionNumbers - 1] = 1;
		}
	}
	else//正常情况
	{
		ListStatus[i] = 0;
		ListStatus[i - 1] = 1;
	}
}
public:void MoveDown()//选项下移
{
	int i = CheckCurrent();//找到当前指向的选项
	if (i == 0 && FunctionNumbers == 1)//如果只有一个选项则不变
		ListStatus[i] = 1;
	else if (i != 0 && i == FunctionNumbers - 1)//如果指向最后一个且不止包含一个选项,则改为指向最上方的选项
	{
		ListStatus[FunctionNumbers - 1] = 0;
		Page = 1;
		ListStatus[0] = 1;
	}
	else if ((i + 1) % LimitListEachPage == 0)//如果指向某一页面的最后一项则翻页,并指向下一页的第一项
	{
		if (Page != GetPages())
		{
			Page++;
			ListStatus[i] = 0;
			ListStatus[i + 1] = 1;
		}
		else
		{
			Page = 1;
			ListStatus[i] = 0;
			ListStatus[0] = 1;
		}
	}
	else//正常情况
	{
		ListStatus[i] = 0;
		ListStatus[i + 1] = 1;
	}
}
public:int CheckCurrent()//找到当前指向的选项  当找不到时返回-1
{
	for (int j = 0; j < FunctionNumbers; j++)
	{
		if (ListStatus[j] == 1)
			return j;
	}
	return -1;
}
public:void Append(string FunctionName, int Times = 1)//List数组添加String成员
{
	if (Times != 0)
		return;
	List[FunctionNumbers] = FunctionName;
	FunctionNumbers += 1;//成员计数器
}
public:void SetMaxList(int List)
{
	LimitListEachPage = List;
}
public:void RemoveAll()//移除所有成员(在04.h版本中为重要功能,05.h中被Times计数器取代)
{
	for (int i = 0; i < 10; i++)
	{
		List[i] = {};
		FunctionNumbers = 0;
	}
}
public:int GetPages()//获取总页面数
{
	if (FunctionNumbers % LimitListEachPage != 0)
		Pages = FunctionNumbers / LimitListEachPage + 1;
	else
		Pages = FunctionNumbers / LimitListEachPage;
	return Pages;
}
public:int GetLimitList()
{
	return LimitListEachPage;
}
private:int Pages{ 1 };
private:int LimitListEachPage{ 9 };
private:string List[50]{};//存放选项名称
private:int ListStatus[50]{ -1 };//存放选项状态
private:int TempCol{ 6 };
private:int SelectedCol{ 7 };
private:int UnSelectedCol{ 1 };
public:int DefaultCol{ 1 };
};
inline void Free(FunctionList* Fun)//释放指针
{
	delete Fun;
	Fun = NULL;
}
struct ICUF_Function//函数指针
{
	FunctionList Fun_Name;
	void (*Fun)();
};
#endif

MineSweeper2.cpp

#include <ctime>
#include"ICUF_HEAD_06.h"
const char* F1 = "ICUF_File.txt";
using namespace std;
const int DifficultyInit();
int MineSweeper();
const void InitMap(int SetX, int SetY);
int ShowMap(int SetX, int SetY);
void ShowMine();
void ShowMapEnd();
void Rank(int Fun, int goal);
int CheckMap();
int CheckZero(int SetX, int SetY, int tempX, int tempY);
int mine{}, Xmax{}, Ymax{}, AdminMode{}, TEMP{}, end{}, KeyX{}, KeyY{};
int Map[200][200],MapC[200][200],Key[200][200];
clock_t startTime;
FunctionList MainPage;
int main()
{
	system("cls");
	Col(7); cout << "                                    " << endl; Col(0);
	Col(4); cout << "          "; Col(7); cout << "  "; Col(4); cout << "  "; Col(7); cout << "  "; Col(4); cout << "        "; Col(7); cout << "  "; Col(4); cout << "        "; Col(7); cout << "  " << endl; Col(0);
	Col(4); cout << "  "; Col(7); cout << "  "; Col(4); cout << "  "; Col(7); cout << "  "; Col(4); cout << "  "; Col(7); cout << "      "; Col(4); cout << "  "; Col(7); cout << "    "; Col(4); cout << "  "; Col(7); cout << "  "; Col(4); cout << "  "; Col(7); cout << "        "; Col(0); cout << "         Wild Chicken Programing TANXL" << endl;
	Col(4); cout << "  "; Col(7); cout << "  "; Col(4); cout << "  "; Col(7); cout << "  "; Col(4); cout << "  "; Col(7); cout << "  "; Col(4); cout << "  "; Col(7); cout << "  "; Col(4); cout << "  "; Col(7); cout << "    "; Col(4); cout << "  "; Col(7); cout << "  "; Col(4); cout << "        "; Col(7); cout << "  "; Col(0); cout << "             WiChP 2021 / 7 / 7 00:53" << endl;
	Col(4);cout<<"  "; Col(7);cout<<"  "; Col(4);cout<<"  "; Col(7);cout<<"  "; Col(4);cout<<"  "; Col(7);cout<<"  "; Col(4);cout<<"  "; Col(7);cout<<"  "; Col(4);cout<<"  "; Col(7);cout<<"    "; Col(4);cout<<"  "; Col(7);cout<<"  "; Col(4);cout<<"  "; Col(7);cout<<"        " << endl;
	Col(4);cout<<"  "; Col(7);cout<<"      "; Col(4);cout<<"  "; Col(7);cout<<"  "; Col(4);cout<<"  "; Col(7);cout<<"  "; Col(4);cout<<"  "; Col(7);cout<<"    "; Col(4);cout<<"  "; Col(7);cout<<"  "; Col(4);cout<<"        "; Col(7);cout<<"  " << endl;
	Col(7);cout<<"                                    " << endl;
	Col(7);cout<<"                                                                                   " << endl;
	Col(7);cout<<"           "; Col(4);cout<<"        "; Col(7);cout<<"  "; Col(4);cout<<"  "; Col(7);cout<<"      "; Col(4);cout<<"  "; Col(7);cout<<"  "; Col(4);cout<<"        "; Col(7);cout<<"  "; Col(4);cout<<"        "; Col(7);cout<<"  "; Col(4);cout<<"        "; Col(7);cout<<"  "; Col(4);cout<<"        "; Col(7);cout<<"  "; Col(4);cout<<"        "; Col(7);cout<<"  " << endl;
	Col(7);cout<<"           "; Col(4);cout<<"  "; Col(7);cout<<"        "; Col(4);cout<<"  "; Col(7);cout<<"  "; Col(4);cout<<"  "; Col(7);cout<<"  "; Col(4);cout<<"  "; Col(7);cout<<"  "; Col(4);cout<<"  "; Col(7);cout<<"        "; Col(4);cout<<"  "; Col(7);cout<<"        "; Col(4);cout<<"  "; Col(7);cout<<"    "; Col(4);cout<<"  "; Col(7);cout<<"  "; Col(4);cout<<"  "; Col(7);cout<<"        "; Col(4);cout<<"  "; Col(7);cout<<"    "; Col(4);cout<<"  "; Col(7);cout<<"  " << endl;
	Col(7);cout<<"           "; Col(4);cout<<"        "; Col(7);cout<<"  "; Col(4);cout<<"  "; Col(7);cout<<"  "; Col(4);cout<<"  "; Col(7);cout<<"  "; Col(4);cout<<"  "; Col(7);cout<<"  "; Col(4);cout<<"        "; Col(7);cout<<"  "; Col(4);cout<<"        "; Col(7);cout<<"  "; Col(4);cout<<"        "; Col(7);cout<<"  "; Col(4);cout<<"        "; Col(7);cout<<"  "; Col(4);cout<<"        "; Col(7);cout<<"  " << endl;
	Col(7);cout<<"                 "; Col(4);cout<<"  "; Col(7);cout<<"  "; Col(4);cout<<"  "; Col(7);cout<<"  "; Col(4);cout<<"  "; Col(7);cout<<"  "; Col(4);cout<<"  "; Col(7);cout<<"  "; Col(4);cout<<"  "; Col(7);cout<<"        "; Col(4);cout<<"  "; Col(7);cout<<"        "; Col(4);cout<<"  "; Col(7);cout<<"        "; Col(4);cout<<"  "; Col(7);cout<<"        "; Col(4);cout<<"  "; Col(7);cout<<"  "; Col(4);cout<<"  "; Col(7);cout<<"    " << endl;
	Col(7);cout<<"           "; Col(4);cout<<"        "; Col(7);cout<<"  "; Col(4);cout<<"          "; Col(7);cout<<"  "; Col(4);cout<<"        "; Col(7);cout<<"  "; Col(4);cout<<"        "; Col(7);cout<<"  "; Col(4);cout<<"  "; Col(7);cout<<"        "; Col(4);cout<<"        "; Col(7);cout<<"  "; Col(4);cout<<"  "; Col(7);cout<<"  "; Col(4);cout<<"    "; Col(7);cout<<"  " << endl;
	Col(7);cout<<"                                                                                   " << endl;Col(0);
	cout << "\n\n\n\n\n"; Col(4); cout << "                "; Col(4);
	system("pause"); Col(0);
	MineSweeper();
}
int MineSweeper()
{
	int Difficulty = DifficultyInit();
	switch (Difficulty)
	{
	case 0:
		mine = 10;
		Xmax = 9;
		Ymax = 9;
		break;
	case 1:
		mine = 40;
		Xmax = 16;
		Ymax = 16;
		break;
	case 2:
		mine = 99;
		Xmax = 16;
		Ymax = 30;
		break;
	case 3:
		Col(4); cout << "请输入X轴的最大值 X= ";
		cin >> Xmax;
		Col(4); cout << "请输入Y轴的最大值 Y= ";
		cin >> Ymax;
		Col(4); cout << "请输入地雷数量 mine= ";
		cin >> mine;
		Col(0);
		if (mine >= Xmax * Ymax || mine == 0)
		{
			Col(4); cout << "地雷数量不满足要求";
			MineSweeper();
		}
		break;
	default:
		Col(4); cout << "功能异常";
		break;
	}
	InitMap(Xmax, Ymax);
	while (1)
	{
		int BreakWord{};
		startTime = clock();
		::end = 1;
		ShowMap(Xmax, Ymax);
		if (CheckMap() == 1 || CheckMap() == 2)
		{
			ShowMine();
			ShowMapEnd();
			cout << "你总计用时: " << (startTime) / CLOCKS_PER_SEC << "s" << endl;
			int TempTime = (startTime) / CLOCKS_PER_SEC;
			if (CheckMap() == 2)
				Rank(0, TempTime);
			cout << "是否继续? Y/N";
			startTime = 0;
			while (1)
			{
				char x = _getch();
				switch (x)
				{
				case'Y':
				case'y':
					InitMap(Xmax, Ymax);
					BreakWord = 2;
					break;
				case'N':
				case'n':
					BreakWord = 1;
					break;
				}
				if (BreakWord == 1|| BreakWord == 2)break;
			}
			if (BreakWord == 1)
			{
				BreakWord = 0;
				break;
			}
			if (BreakWord == 2)
			{
				BreakWord = 0;
				continue;
			}
		}
	}
	system("pause");
	return 0;
}
const int DifficultyInit()
{
	MainPage.SetCol(7, 4);
	MainPage.Append(" 简单 ", MainPage.Times);
	MainPage.Append(" 中等 ", MainPage.Times);
	MainPage.Append(" 困难 ", MainPage.Times);
	MainPage.Append("自定义", MainPage.Times++);
	MainPage.InitList();
	while (1)
	{
		system("cls");
		Col(4); cout << "\n\n\n\n                         请选择难度  WiChP_TANXL             \n\n"; Col(0);
		MainPage.DisplayList();
		int i = MainPage.InsertAction();
		if (i == 3)
			main();
		else if (i == 4)
		{
			int i = MainPage.CheckCurrent();
			return i;
		}
	}
}
const void InitMap(int SetX, int SetY)
{
	srand(time(0));
	for (int x = 0; x < SetX + 2; x++)
	{
		for (int y = 0; y < SetY + 2; y++)
		{
			Map[x][y] = 2;
			MapC[x][y] = 1;
		}
	}
	for (int x = 0; x < SetX + 2; x++)//生成地图
	{
		for (int y = 0; y < SetY + 2; y++)
		{
			if (x == 0 || y == 0 || x == SetX + 1 || y == SetY + 1)
			{
				Map[x][y] = 9;
				MapC[x][y] = 1;
				Key[x][y] = 0;
			}
			Map[x][y] = 0;
			MapC[x][y] = 0;
			Key[x][y] = 0;
		}
	}
	KeyX = 1;
	KeyY = 1;
	Key[KeyX][KeyY] = 1; //Key[x][y] = 1;
	for (int i = 0; i < mine;)//生成地雷
	{
		int RandomX = rand() % (SetX - 1) + 1;
		int RandomY = rand() % (SetY - 1) + 1;
		if (Map[RandomX][RandomY] != 9)
		{
			Map[RandomX][RandomY] = 9;
			i++;
		}
	}
	for (int x = 1; x < SetX + 1; x++)//生成数字
	{
		for (int y = 1; y < SetY + 1; y++)
		{
			if (Map[x][y] == 9)
			{
				if (Map[x - 1][y] != 9)Map[x - 1][y]++;
				if (Map[x][y - 1] != 9)Map[x][y - 1]++;
				if (Map[x - 1][y - 1] != 9)Map[x - 1][y - 1]++;
				if (Map[x + 1][y] != 9)Map[x + 1][y]++;
				if (Map[x][y + 1] != 9)Map[x][y + 1]++;
				if (Map[x + 1][y + 1] != 9)Map[x + 1][y + 1]++;
				if (Map[x + 1][y - 1] != 9)Map[x + 1][y - 1]++;
				if (Map[x - 1][y + 1] != 9)Map[x - 1][y + 1]++;
			}
		}
	}
}
int ShowMap(int SetX, int SetY)
{
	system("cls");
	Col(4); cout << "操作方法:WASD或↑↓←→移动指针,J插旗L标记 回车键翻开格子";Col(0);
	cout << endl << "Wild_Chicken_Programing TANXL 2021/7/7 00:53" << endl;
	Col(4); cout << "额外功能 Q:3X3方格自动点开 E:展示所有数字 Z:返回";Col(0);
	cout << endl << endl << "X" << endl;
	for (int x = 1; x < SetX + 1; x++)//输出地图
	{
		cout << x  << "\t";
		for (int y = 1; y < SetY + 1; y++)
		{
			if (Map[x][y] >= 0 && Map[x][y] <= 9)
			{
				if (Key[x][y] == 1)Col(5);
				else if (Key[x][y] == 2)Col(1);
				else if (Key[x][y] == 3)Col(3);
				else if (Key[x][y] == 4)Col(4);
				else if (Key[x][y] == 5)Col(6);
				else if (Key[x][y] == 6)Col(2);
				else Col(7);
				if (MapC[x][y] == 1)Col(0);
				if (Key[x][y] == 1)Col(5);
				cout << " ";
				if (AdminMode == 1)cout << Map[x][y] << " ";
				else if (MapC[x][y] == 1)cout << Map[x][y] << " ";
				else cout << "  ";
			}
		}
		Col(0);
		cout << endl;
	}
	cout << endl << endl << endl;
	cout << "\t\t指针坐标 X:" << KeyX << "\tY:" << KeyY << endl;
	cout << "\t\t当前格子状态: ";
	if (MapC[KeyX][KeyY] == 1)cout << "指向翻开状态";
	else if (Key[KeyX][KeyY] == 1)cout << "指向未翻开状态";
	if (Key[KeyX][KeyY] == 3)cout << "指向插旗状态";
	if (Key[KeyX][KeyY] == 5)cout << "指向疑问状态";
	if (Key[KeyX][KeyY] == 7)cout << "指向已翻开状态";
	cout << endl << "\t\t所使用的时间:" << (startTime) / CLOCKS_PER_SEC << "s" << endl;
	cout << "\t\t最短完成时间: "; Rank(1, 0); cout << "s";
	char movekey = _getch();
	switch (movekey)
	{
		// 使用颜色重叠实现
	case 72:
	case 'W':
	case 'w':
		if (KeyX == 1)break;
		Key[KeyX - 1][KeyY] ++;
		if (Key[KeyX][KeyY] == 1)Key[KeyX][KeyY]--;
		if (Key[KeyX][KeyY] == 3)Key[KeyX][KeyY]--;
		if (Key[KeyX][KeyY] == 5)Key[KeyX][KeyY]--;
		if (Key[KeyX][KeyY] == 7)Key[KeyX][KeyY]--;
		KeyX--;
		break;
	case 80:
	case 'S':
	case 's':
		if (KeyX == SetX)break;
		Key[KeyX + 1][KeyY] ++;
		if (Key[KeyX][KeyY] == 1)Key[KeyX][KeyY]--;
		if (Key[KeyX][KeyY] == 3)Key[KeyX][KeyY]--;
		if (Key[KeyX][KeyY] == 5)Key[KeyX][KeyY]--;
		if (Key[KeyX][KeyY] == 7)Key[KeyX][KeyY]--;
		KeyX++;
		break;
	case 75:
	case'A':
	case'a':
		if (KeyY == 1)break;
		Key[KeyX][KeyY - 1] ++;
		if (Key[KeyX][KeyY] == 1)Key[KeyX][KeyY]--;
		if (Key[KeyX][KeyY] == 3)Key[KeyX][KeyY]--;
		if (Key[KeyX][KeyY] == 5)Key[KeyX][KeyY]--;
		if (Key[KeyX][KeyY] == 7)Key[KeyX][KeyY]--;
		KeyY--;
		break;
	case 77:
	case'D':
	case'd':
		if (KeyY == SetY)break;
		Key[KeyX][KeyY + 1] ++;
		if (Key[KeyX][KeyY] == 1)Key[KeyX][KeyY]--;
		if (Key[KeyX][KeyY] == 3)Key[KeyX][KeyY]--;
		if (Key[KeyX][KeyY] == 5)Key[KeyX][KeyY]--;
		if (Key[KeyX][KeyY] == 7)Key[KeyX][KeyY]--;
		KeyY++;
		break;
	case'J':
	case'j':
		//插旗子
		if (Key[KeyX][KeyY] == 1 && MapC[KeyX][KeyY] == 0)Key[KeyX][KeyY] = 3;
		else Key[KeyX][KeyY] = 1;
		break;
	case'L':
	case'l':
		//做标记
		if (Key[KeyX][KeyY] == 1 && MapC[KeyX][KeyY] == 0)Key[KeyX][KeyY] = 5;
		else Key[KeyX][KeyY] = 1;
		break;
	case'\r':
		//确认选择
		MapC[KeyX][KeyY] = 1;
		if (Map[KeyX][KeyY] == 0)CheckZero(SetX, SetY, KeyX, KeyY);
		if (Key[KeyX][KeyY] == 3) { MapC[KeyX][KeyY] = 0; break; }
		break;
	case'Q':
	case'q':
		if (MapC[KeyX][KeyY] == 0)break;
		TEMP = 0;
		if (Key[KeyX - 1][KeyY] == 2)TEMP++;//上
		if (Key[KeyX + 1][KeyY] == 2)TEMP++;//下
		if (Key[KeyX][KeyY - 1] == 2)TEMP++;//左
		if (Key[KeyX][KeyY + 1] == 2)TEMP++;//右
		if (Key[KeyX - 1][KeyY - 1] == 2)TEMP++;//左上
		if (Key[KeyX - 1][KeyY + 1] == 2)TEMP++;//右上
		if (Key[KeyX + 1][KeyY - 1] == 2)TEMP++;//左下
		if (Key[KeyX + 1][KeyY + 1] == 2)TEMP++;//右下
		if (Map[KeyX][KeyY] == TEMP)
		{
			if (Key[KeyX][KeyY] == 0 || Key[KeyX][KeyY] == 5)
			{
				MapC[KeyX][KeyY] = 1;
				CheckZero(SetX, SetY, KeyX, KeyY);
			}
			if (Key[KeyX - 1][KeyY] == 0 || Key[KeyX - 1][KeyY] == 5)
			{
				MapC[KeyX - 1][KeyY] = 1;
				CheckZero(SetX, SetY, KeyX - 1, KeyY);
			}
			if (Key[KeyX + 1][KeyY] == 0 || Key[KeyX + 1][KeyY] == 5)
			{
				MapC[KeyX + 1][KeyY] = 1;
				CheckZero(SetX, SetY, KeyX + 1, KeyY);
			}
			if (Key[KeyX][KeyY - 1] == 0 || Key[KeyX][KeyY - 1] == 5)
			{
				MapC[KeyX][KeyY - 1] = 1;
				CheckZero(SetX, SetY, KeyX, KeyY - 1);
			}
			if (Key[KeyX][KeyY + 1] == 0 || Key[KeyX][KeyY + 1] == 5)
			{
				MapC[KeyX][KeyY + 1] = 1;
				CheckZero(SetX, SetY, KeyX, KeyY + 1);
			}
			if (Key[KeyX - 1][KeyY - 1] == 0 || Key[KeyX - 1][KeyY - 1] == 5)
			{
				MapC[KeyX - 1][KeyY - 1] = 1;
				CheckZero(SetX, SetY, KeyX - 1, KeyY - 1);
			}
			if (Key[KeyX - 1][KeyY + 1] == 0 || Key[KeyX - 1][KeyY + 1] == 5)
			{
				MapC[KeyX - 1][KeyY + 1] = 1;
				CheckZero(SetX, SetY, KeyX - 1, KeyY + 1);
			}
			if (Key[KeyX + 1][KeyY - 1] == 0 || Key[KeyX + 1][KeyY - 1] == 5)
			{
				MapC[KeyX + 1][KeyY - 1] = 1;
				CheckZero(SetX, SetY, KeyX + 1, KeyY - 1);
			}
			if (Key[KeyX + 1][KeyY + 1] == 0 || Key[KeyX + 1][KeyY + 1] == 5)
			{
				MapC[KeyX + 1][KeyY + 1] = 1;
				CheckZero(SetX, SetY, KeyX + 1, KeyY + 1);
			}
		}
		break;
	case'E':
	case'e':
		//展示所有数字
		if (AdminMode == 0)AdminMode = 1;
		else AdminMode = 0;
		break;
	case'Z':
	case'z':
		//返回
		MineSweeper();
		break;
	}
	return 0;
}
int CheckZero(int SetX, int SetY, int tempX, int tempY)
{
	if (tempX == 0 || tempX == SetX + 1 || tempY == 0 || tempY == SetY + 1)
		return 0;
	MapC[tempX][tempY] = 1;
	if (Map[tempX][tempY] == 0 && tempX >= 1)//X-1 Y
	{
		if (MapC[tempX - 1][tempY] == 0)
		{
			MapC[tempX - 1][tempY] = 1;
			if (Map[tempX - 1][tempY] == 0)
				CheckZero(SetX, SetY, tempX - 1, tempY);
		}
	}
	if (Map[tempX][tempY] == 0 && tempX <= Xmax - 1)//X+1 Y
	{
		if (MapC[tempX + 1][tempY] == 0)
		{
			MapC[tempX + 1][tempY] = 1;
			if (Map[tempX + 1][tempY] == 0)
				CheckZero(SetX, SetY, tempX + 1, tempY);
		}
	}
	if (Map[tempX][tempY] == 0 && tempY >= 1)//X Y-1
	{
		if (MapC[tempX][tempY - 1] == 0)
		{
			MapC[tempX][tempY - 1] = 1;
			if (Map[tempX][tempY - 1] == 0)
				CheckZero(SetX, SetY, tempX, tempY - 1);
		}
	}
	if (Map[tempX][tempY] == 0 && tempY <= Ymax - 1)//X Y+1
	{
		if (MapC[tempX][tempY + 1] == 0)
		{
			MapC[tempX][tempY + 1] = 1;
			if (Map[tempX][tempY + 1] == 0)
				CheckZero(SetX, SetY, tempX, tempY + 1);
		}
	}
	if (Map[tempX][tempY] == 0 && tempX >= 1 && tempY <= Ymax - 1)//X-1 Y+1
	{
		if (MapC[tempX - 1][tempY + 1] == 0)
		{
			MapC[tempX - 1][tempY + 1] = 1;
			if (Map[tempX - 1][tempY + 1] == 0)
				CheckZero(SetX, SetY, tempX - 1, tempY + 1);
		}
	}
	if (Map[tempX][tempY] == 0 && tempX >= 1 && tempY >= 1)//X-1 Y-1
	{
		if (MapC[tempX - 1][tempY - 1] == 0)
		{
			MapC[tempX - 1][tempY - 1] = 1;
			if (Map[tempX - 1][tempY - 1] == 0)
				CheckZero(SetX, SetY, tempX - 1, tempY - 1);
		}
	}
	if (Map[tempX][tempY] == 0 && tempX <= Xmax - 1 && tempY >= 1)//X+1 Y-1
	{
		if (MapC[tempX + 1][tempY - 1] == 0)
		{
			MapC[tempX + 1][tempY - 1] = 1;
			if (Map[tempX + 1][tempY - 1] == 0)
				CheckZero(SetX, SetY, tempX + 1, tempY - 1);
		}
	}
	if (Map[tempX][tempY] == 0 && tempX <= Xmax - 1 && tempY <= Ymax - 1)//X+1 Y+1
	{
		if (MapC[tempX + 1][tempY + 1] == 0)
		{
			MapC[tempX + 1][tempY + 1] = 1;
			if (Map[tempX + 1][tempY + 1] == 0)
				CheckZero(SetX, SetY, tempX + 1, tempY + 1);
		}
	}
	return 0;
}
int CheckMap()
{
	int count{}, Mcount{};
	for (int x = 1; x < Xmax + 1; x++)
	{
		for (int y = 1; y < Ymax + 1; y++)
		{
			if (Map[x][y] == 9 && MapC[x][y] == 1)
			{
				Mcount++;
			}
			if (Map[x][y] != 9 && MapC[x][y] == 0)
			{
				count++;
			}
		}
	}
	if (count == 0)
	{
		cout << endl << endl << "成功!" << endl;
		::end = 1;
		return 2;
	}
	if (Mcount != 0)
	{
		cout << endl << endl << "失败!" << endl;
		::end = 2;
		return 1;
	}
	return 0;
}
void ShowMine()
{
	for (int x = 1; x < Xmax + 1; x++)
	{
		for (int y = 1; y < Ymax + 1; y++)
		{
			if (Map[x][y] == 9)
			{
				Key[x][y] = 4;
			}
		}
	}
}
void ShowMapEnd()
{
	system("cls");
	cout << endl << endl << endl;
	Col(0); cout << endl << endl << "X" << endl;
	for (int x = 1; x < Xmax + 1; x++)//输出地图
	{
		cout << x << "\t";
		for (int y = 1; y < Ymax + 1; y++)
		{
			if (Map[x][y] >= 0 && Map[x][y] <= 9)
			{
				if (Key[x][y] == 1)Col(5);
				else if (Key[x][y] == 2)Col(1);
				else if (Key[x][y] == 3)Col(3);
				else if (Key[x][y] == 4)Col(4);
				else if (Key[x][y] == 5)Col(6);
				else if (Key[x][y] == 6)Col(2);
				else Col(7);
				if (MapC[x][y] == 1)Col(0);
				if (Key[x][y] == 1)Col(5);
				cout << " ";
				if (AdminMode == 1)cout << Map[x][y] << " ";
				else if (MapC[x][y] == 1)cout << Map[x][y] << " ";
				else cout << "  ";
			}
		}
		Col(0);
		cout << endl;
	}
}
void Rank(int Fun, int goal)
{
	int Fgoal{};
	fin.open(F1);
	fin >> Fgoal;
	fin.close();;
	if (Fun == 1)
	{
		if (Fgoal == 0)
			Fgoal = 999;
		cout << Fgoal;
		fout.open(F1);
		fout << Fgoal;
		fout.close();
	}
	else
	{
		if (Fgoal < goal)
		{
			cout << "未能打破纪录";
		}
		else
		{
			cout << "成功打破纪录";
			fout.open(F1);
			fout << goal;
			fout.close();
		}
	}
}

运行截图

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
2021/7/10 22:17 修复一处胜负判定输入错误导致死循环的问题。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WiChP

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值