#include <iostream>
#include <conio.h>
#include<time.h>
#include<fstream>//这里采用c++的文件输入输出试一下。c语言的我也不太会以后写写
using namespace std;
//定义一个10*10的扫雷地图
int GameMap[12][12] = {
{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
{-1,0,0,0,0,0,0,0,0,0,0,-1},
{-1,0,0,0,0,0,0,0,0,0,0,-1},
{-1,0,0,0,0,0,0,0,0,0,0,-1},
{-1,0,0,0,0,0,0,0,0,0,0,-1},
{-1,0,0,0,0,0,0,0,0,0,0,-1},
{-1,0,0,0,0,0,0,0,0,0,0,-1},
{-1,0,0,0,0,0,0,0,0,0,0,-1},
{-1,0,0,0,0,0,0,0,0,0,0,-1},
{-1,0,0,0,0,0,0,0,0,0,0,-1},
{-1,0,0,0,0,0,0,0,0,0,0,-1},
{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, };
int Boomnum = 0;//存在的已探测地区数量
int safe=0;
void printmap()//打印地图
{
cout << "地雷数:" << Boomnum << "已探测格子数:" << safe<<" (当全部非地雷格子已经探测时胜利)" << endl;
for (int i = 0; i < 12; i++)
{
cout <<" " << endl;
for (int j = 0; j < 12; j++)
switch (GameMap[i][j])
{
case -1:cout << "墙"; break;
case 0:cout << " "; break;
case -2:case -3:cout << "雷"; break;//-2是没有揭开的地雷,-3是揭开的地雷
case -4:case-5:case-6:case-7:cout << "0 "; break;
case -10:case-11:cout << "标"; break;
default:
cout << GameMap[i][j]<<" ";
break;
}
}
}
fstream range;//定义一个文件对象range
void BoomEmerger()//地雷生成
{
cout << "输入要生成的地雷数" << endl;
cin >> Boomnum;
int i;
int j;
for (int k = 0; k < Boomnum; k++)//生成输入个数个雷
{
i = 1+rand()%10;
j = 1+rand()%10;
if (GameMap[i][j] != -2)
GameMap[i][j] = -2;
else
k--;
}
}
void scanboomnum(int input1,int input2)//扫描周围雷的数量
{
if(GameMap[input1][input2]==0)
{
for (int i = input1 - 1; i <= input1 + 1; i++)//探测本格周围雷的数量
for (int j = input2 - 1; j <= input2 + 1; j++)
if (GameMap[i][j] == -2)
GameMap[input1][input2]++;//有一个就+1
safe++;//探测一次,已探测格子+1
}
if (GameMap[input1][input2] == 0)
GameMap[input1][input2] = -4;//-4表示该格周围没有地雷
}
void scanzero(int input1,int input2)//扫描0的数量
{
for (int i = input1 - 1; i <= input1 + 1; i++)//探测本格周围雷的数量
for (int j = input2 - 1; j <= input2 + 1; j++)
{
if(GameMap[i][j]==0)//只对没有探测过的格子探测,减少操作
scanboomnum(i, j);
}
if (GameMap[input1 + 1][input2] == -4)//如果本格的上面周围也没有雷
{
GameMap[input1][input2]--;//为本格做一个标记防止下一个空白格又探测本格,互相探测形成死循环
scanzero(input1 + 1, input2);//对上面的周围进行探测,后面同理
}
if (GameMap[input1 - 1][input2] == -4)
{
GameMap[input1][input2]--;scanzero(input1 - 1, input2);
}
if (GameMap[input1][input2+1] == -4)
{
GameMap[input1][input2]--;scanzero(input1, input2 + 1);
}
if (GameMap[input1 ][input2-1] == -4)
{
GameMap[input1][input2]--;scanzero(input1, input2 - 1);
}
}
int main()
{
cout << " 欢迎来到周恺祺扫雷游戏:按任意键开始:" << endl;
srand(time(nullptr));
bool startgame = 1;//控制游戏开始还是结束
int op=0;//用来判断是做标记还是扫雷
int input1=0;//用于选择的行和列
int input2=0;
cin >> input1;//没作用,就是给个看主页的作用
BoomEmerger();//生成地雷
while (startgame)
{
system("CLS");
printmap();
if ( safe == (100 - Boomnum))//判断胜利触发器
{
cout <<endl<< "游戏胜利!!" << endl;
startgame = 0;
cout << "请输入你的名字";
char name[100];
cin >> name;
range.open("C:\\Users\\24060\\Desktop\\c++项目算法训练\\ScanBoom\\Range.txt", ios_base::app);//追加到文件尾 注:这里我写的绝对路径!!!你们自己改一下就好!!
if (!range.is_open())
{
cout << "查看失败1" << endl;
}
range << name <<" 地雷数:"<<Boomnum<<" " << endl ;
range.close();
range.open("C:\\Users\\24060\\Desktop\\c++项目算法训练\\ScanBoom\\Range.txt", ios_base::in);//读取
if (!range.is_open())
{
cout << "查看失败" << endl;
}
else
{
char ch;
while (range.good())
{
range >> ch;
cout << ch;
}
}
range.close();
break;
}
cout << endl << "请输入要进行的操作" << endl << "1、探测格子" << endl << "2、排雷(对已经排雷格子使用会取消排雷)" << endl << "" << endl;
cin >> op;
switch (op)
{
case 1:
cout<< "行数和列数:(空格隔开,回车确定)" << endl;
cin >> input1 >> input2;
if (GameMap[input1][input2] == -2)//踩到雷了
//因为地雷在没点开之前是空白,我原本还想着两个地图,一个是展示地图一个是实际数据地图
//但是我后来想了一个,只有踩雷的时候显示出所有的雷不就好了吗。
{
system("CLS");
cout << " 踩到雷了!!游戏失败!!!" << endl;
for (int i = 1; i < 12; i++)
{
for (int j = 1; j < 12; j++)
if (GameMap[i][j] == -2)
GameMap[i][j] = -3;
}
printmap();
startgame = 0;
break;
}
scanboomnum(input1, input2);
if (GameMap[input1][input2] == -4)//如果还是0的话,就将周围8格的内容都展示出来
scanzero(input1, input2);
break;
case 2://标记地雷操作
{
cout << "行数和列数:(空格隔开,回车确定)" << endl;
cin >> input1 >> input2;
if (GameMap[input1][input2] == -2)//如果是地雷则为正确标记-10
GameMap[input1][input2] = -10;
else if (GameMap[input1][input2] == 0)
GameMap[input1][input2] = -11;//错误标记-11
else if (GameMap[input1][input2] == -10)//标记还原操作
GameMap[input1][input2] = -2;//标记正确还原地雷
else if (GameMap[input1][input2] == -11)
GameMap[input1][input2] = 0;//标记错误还原为未探测状态
else//如果是已探测目标就报错
cout << "无法标记!" << endl;
}
default://查看排行榜操作
break;
}
if (input1 == 27)
startgame = 0;
//没有踩到雷,就显示周围雷的数量
}
}
//这个项目写扫雷
有问题可以随时问我,代码中的注释写的算是很清楚了。