废话不多说,直接上代码,看官们先去试试,然后回来看分析
分析文章见:
https://blog.youkuaiyun.com/ycczbasd/article/details/103511457
#include <iostream>
#include <windows.h>
#include <time.h>
#include <vector>
using namespace std;
void GameInit();
void GameRun();
void GameDraw();
void GameLogic();
void GameEnd();
void SetThunderPosition();
void CountThunder();
void Spread(int index);
void ShowCompleteMap();
HANDLE hOutput;
COORD coord = { 0,0 };
int MapW = 0;
int MapH = 0;
int MapS = 0;
//0空白;
//1代表该位置附近有1颗雷,最多有8颗
//9代表该位置有雷
//-9代表该位置的雷被排除了
char* Map; //地图动态数组
char* DisplayMap;//屏幕展示出来的地图
int* ThunderIndex; //雷位置索引动态数组
int difficult = 0;
bool isRun = true;
int ThunderNum = 0; //雷数量
//Game光标
int CursonX = 0;
int CursonY = 0;
char pic[][3] = { "□","①","②","③","④","⑤","⑥","⑦","⑧","⊕","▶","■","↖" };
//游戏状态 0:开始场景 1:难度选择场景 2:游戏运行场景 3:胜利场景 4:失败场景 5:游戏结束场景
int status = 0;
void main()
{
int input;
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
//隐藏缓冲区的光标
CONSOLE_CURSOR_INFO cci;
cci.bVisible = 0;
cci.dwSize = 1;
SetConsoleCursorInfo(hOutput, &cci);
while (isRun)
{
system("cls");
if (status == 0)
{
cout << "请选择:\n" << "1.开始\n" << "2.退出\n" << "请选择:" << endl;
cin >> input;
if (input == 1)
status = 1;
if (input == 2)
status = 5;
}
else if (status == 1)
{
cout << "难度选择:\n" << "1.简单\n" << "2.容易\n" << "3.困难\n" << "4.退出\n" << "请选择:" << endl;
cin >> input;
if (input >= 1 && input <= 3)
{
status = 2;
difficult = input;
GameInit();
}
if (input == 4)
status = 5;
}
else if (status == 2)
{
GameRun();
}
else if (status == 3) //win界面,可以扩展
{
ShowCompleteMap();
cout << " You Win!!!!!!!";
Sleep(2000);
status = 5;
}
else if (status == 4) //failed界面,可以扩展
{
ShowCompleteMap();
cout << " You Failed!!!!!!!";
Sleep(2000);
status = 5;
}
else if (status == 5) //结束界面,可以扩展
{
isRun = false;
GameEnd();
}
}
system("pause");
}
void GameInit()
{
if (difficult == 1)
{
MapW = 11;
MapH = 11;
ThunderNum = 15;
}
else if (difficult == 2)
{
MapW = 15;
MapH = 15;
ThunderNum = 23;
}
else if (difficult == 3)
{
MapW = 19;
MapH = 19;
ThunderNum = 31;
}
MapS = MapW * MapH;
//初始化地图
Map = new char[MapS];
memset(Map, 0, MapS);
DisplayMap = new char[MapS];
memset(DisplayMap, 11, MapS);
ThunderIndex = new int[ThunderNum];
SetThunderPosition();
CountThunder();
}
void GameRun()
{
GameDraw();
GameLogic();
}
void GameDraw()
{
for (int i = 0; i < MapS; ++i)
{
if (CursonX + CursonY * MapW == i)
cout << pic[12];
else
cout << pic[DisplayMap[i]];
if (i % MapW == MapW - 1)
cout << endl;
}
/*for (int i = 0; i < MapH; ++i)
{
coord.Y = i;
SetConsoleCursorPosition(hOutput, coord);
for (int j = 0; j < MapW; ++j)
{
if (CursonX == j && CursonY == i)
cout << pic[12];
else
cout << pic[DisplayMap[i]];
}
}
Sleep(50);*/
}
void GameLogic()
{
//输赢判断
int n = 0; //统计雷个数
for (int i = 0; i < MapS; ++i)
{
if (DisplayMap[i] != Map[i])
{
n++;
if (n > ThunderNum)
break;
}
}
if (n == ThunderNum) //赢了
{
status = 3;
return;
}
//光标移动
if (GetAsyncKeyState(VK_LEFT) & 0x8000 && CursonX > 0)
{
CursonX--;
}
else if (GetAsyncKeyState(VK_RIGHT) & 0x8000 && CursonX < MapW - 1)
{
CursonX++;
}
else if (GetAsyncKeyState(VK_UP) & 0x8000 && CursonY > 0)
{
CursonY--;
}
else if (GetAsyncKeyState(VK_DOWN) & 0x8000 && CursonY < MapH - 1)
{
CursonY++;
}
else if (GetAsyncKeyState(VK_SPACE) & 0x8000)
{
//只能在未展示的地图上按键
int index = CursonX + CursonY * MapW;
if (DisplayMap[index] == 11)
{
if (Map[index] == 0)
Spread(index);
else if (Map[index] > 0 && Map[index] < 9)
DisplayMap[index] = Map[index];
else if (Map[index] == 9)
{
status = 4;
return;
}
}
}
}
void GameEnd()
{
if (Map != nullptr)
{
delete[]Map;
Map = nullptr;
}
if (ThunderIndex != nullptr)
{
delete[]ThunderIndex;
ThunderIndex = nullptr;
}
}
void SetThunderPosition()
{
int num = 0;
//srand((unsigned)time(0));
vector<int> vPosition;
for (int i = 0; i < MapS; ++i)
{
vPosition.push_back(i);
}
while (num < ThunderNum)
{
int index = rand() % vPosition.size();
Map[vPosition[index]] = 9;
ThunderIndex[num] = vPosition[index];
vPosition.erase(vPosition.begin() + index);
num++;
}
}
void CountThunder()
{
const int dir[8] = { -1, -1 - MapW, -MapW, 1 - MapW, 1, 1 + MapW, MapW, -1 + MapW };
for (int i = 0; i < ThunderNum; ++i)
{
for (int j = 0; j < 8; ++j)
{
int CountPosition = dir[j] + ThunderIndex[i];
if (CountPosition < 0 || CountPosition >= MapS)
continue;
int Difference_W = CountPosition % MapW - ThunderIndex[i] % MapW;
int Difference_H = CountPosition / MapW - ThunderIndex[i] / MapW;
if (Difference_W >= -1 && Difference_W <= 1 && Difference_H >= -1 && Difference_H <= 1)
{
if (Map[CountPosition] == 9)
continue;
Map[CountPosition]++;
}
}
}
}
//扩散
void Spread(int index)
{
const int dir[8] = { -1, -1 - MapW, -MapW, 1 - MapW, 1, 1 + MapW, MapW, -1 + MapW };
vector<int> vecSpread; //没学过的可以先看看,或者用长度大一点的数组
vecSpread.push_back(index);
DisplayMap[index] = 0;
for (int i = 0; i < vecSpread.size(); ++i)
{
if (DisplayMap[vecSpread[i]] != 0)
continue;
for (int j = 0; j < 8; ++j)
{
int temp_index = vecSpread[i] + dir[j];
if (temp_index < 0 || temp_index >= MapS) //越界
continue;
int Difference_W = temp_index % MapW - vecSpread[i] % MapW;
int Difference_H = temp_index / MapW - vecSpread[i] / MapW;
if (Difference_W >= -1 && Difference_W <= 1 && Difference_H >= -1 && Difference_H <= 1) //相邻判断
{
if (DisplayMap[temp_index] != 11) //记录过的无法再记录
continue;
if (Map[temp_index] >= 0 && Map[temp_index] <= 8)
{
vecSpread.push_back(temp_index);
DisplayMap[temp_index] = Map[temp_index];
}
}
}
}
}
void ShowCompleteMap()
{
for (int i = 0; i < MapS; ++i)
{
if (CursonX + CursonY * MapW == i)
cout << pic[12];
else
cout << pic[Map[i]];
if (i % MapW == MapW - 1)
cout << endl;
}
}