目录
游戏需求文档:
打开扫雷后进入初始化界面,输入生成的雷的数量并按下回车确认完成地图初始化
地图大小默认为10*10
输入按下回车确认后进入游戏,在10*10的地图的左侧和上测标注坐标,地图未探索区域用’#’表示,每次输入需要先确定操作码,1代表扫雷,0代表标记,例如对(0,7)点标记:
按下回车确认操作后:
被标记点显示为’!’表是该点被标记,若再次对该点进行标记操作则会撤销标记.
若想要扫雷(2,1)点则需使用操作码1:
按下回车确认操作后:
若被扫的点为附近没有地雷则会自动将其上下左右四个方向为探索地区探开,若被探开的点位周围有雷则会停止探索并显示其附近的雷数。
失败:若扫雷位置刚好有地雷则游戏失败
胜利:点开整张地图所有不是地雷的格子(若被标记点实际并不是地雷,则无法胜利)
C++实现:
#include<iostream>
#include<time.h>
#include<stdlib.h>
//修改Max可以设置地图大小
#define Max 10
using namespace std;
//初始化答案地图,并设置炸弹数量
void initMap(int map[Max][Max],int boomNum)
{
int i,j,z,x,y;
int a[8] = {-1,-1,-1,0,1,1,1,0};
int b[8] = {-1,0,1,1,1,0,-1,-1};
srand((unsigned int)time(NULL));
for(i=0;i<Max;++i)
for(j=0;j<Max;++j)
map[i][j] = 0;
for(z=0;z<boomNum;++z)
{
i = rand()%Max;
j = rand()%Max;
if(map[i][j] == 9) ++boomNum;
else map[i][j] = 9;
}
for(i=0;i<Max;++i)
for(j=0;j<Max;++j)
{
if(map[i][j] == 9) continue;
for(z=0;z<8;++z)
{
x = i + a[z];
y = j + b[z];
if(x >= 0 && x < Max && y >=0 && y < Max && map[x][y] == 9)
++map[i][j];
}
}
}
//初始化玩家视角地图(全部置9,显示的时候9代表未探索)
void initPlayerViewMap(int playerViewMap[Max][Max])
{
int i,j;
for(i=0;i<Max;++i)
for(j=0;j<Max;++j)
playerViewMap[i][j] = 9;
}
//打印玩家视角下的地图
void printViewMap(int playerViewMap[Max][Max],int map[Max][Max])
{
int i,j;
cout<<" ";
for(i=0;i<Max;++i)
cout<<i%10<<" ";
cout<<endl;
for(i=0;i<Max;++i)
{
cout<<" "<<i%10<<" ";
for(j=0;j<Max;++j)
{
if(playerViewMap[i][j] == 9) cout<<"# ";
else if(playerViewMap[i][j] == -1) cout<<"! ";
else cout<<map[i][j]<<" ";
}
cout<<endl;
}
cout<<"操作码:1->扫雷 0->标记"<<endl;
}
//点击空白位置时递归探索附近所有非雷区域
void pathFinding(int i,int j,int playerViewMap[Max][Max],int map[Max][Max])
{
//递归结束判断
if(i < 0 || i >= Max || j < 0 || j >= Max || playerViewMap[i][j] == 0) return ;
//探索开玩家视角地图
playerViewMap[i][j] = map[i][j];
if(map[i][j] != 0) return ;
//递归探索上面
pathFinding(i-1,j,playerViewMap,map);
//递归探索右面
pathFinding(i,j+1,playerViewMap,map);
//递归探索下面
pathFinding(i+1,j,playerViewMap,map);
//递归探索左面
pathFinding(i,j-1,playerViewMap,map);
}
//操作1(扫雷)
bool operate_1(int i,int j,int playerViewMap[Max][Max],int map[Max][Max])
{
if(map[i][j] == 9) return true;
else if(map[i][j] > 0 && map[i][j] < 9)
playerViewMap[i][j] = map[i][j];
else if(map[i][j] == 0)
pathFinding(i,j,playerViewMap,map);
return false;
}
//选择操作0(标记)
void operate_0(int i,int j,int playerViewMap[Max][Max])
{
if(playerViewMap[i][j] == -1) playerViewMap[i][j] = 9;
else if(playerViewMap[i][j] == 9) playerViewMap[i][j] = -1;
}
//判断是否获胜
bool isWin(int playerViewMap[Max][Max],int map[Max][Max])
{
int i,j;
for(i=0;i<Max;++i)
for(j=0;j<Max;++j)
if(map[i][j] != 9 && (playerViewMap[i][j] == 9 || playerViewMap[i][j] == -1))
return false;
return true;
}
//打印答案地图
void printMap(int map[Max][Max])
{
int i,j;
cout<<" ";
for(i=0;i<Max;++i)
cout<<i%10<<" ";
cout<<endl;
for(i=0;i<Max;i++)
{
cout<<" "<<i%10<<" ";
for(j=0;j<Max;++j)
{
cout<<map[i][j]<<" ";
}
cout<<endl;
}
}
int main()
{
int map[Max][Max];
int playerViewMap[Max][Max];
int i,j,boomNum,operate;
bool lose = false;
cout<<"#->未探索 0~8->附近的雷数 !->标记点 9->雷"<<endl;
cout<<"请输入要生成的雷的数量:";
cin>>boomNum;
initMap(map,boomNum);
initPlayerViewMap(playerViewMap);
system("cls");
while(true)
{
printViewMap(playerViewMap,map);
cout<<"请输入操作码以及要操作的点位坐标:";
cin>>operate>>i>>j;
if(operate == 1) lose = operate_1(i,j,playerViewMap,map);
else if(operate == 0) operate_0(i,j,playerViewMap);
if(lose) break;
if(isWin(playerViewMap,map)) break;
system("cls");
}
system("cls");
printMap(map);
if(lose) cout<<"你输了!"<<endl;
else cout<<"你赢了!"<<endl;
system("pause");
return 0;
}