#include<iostream>
#include<stdlib.h>
#include<time.h>
#define rows 11 //行数、列数+2,避免计算坐标位置周围雷的个数时
#define cols 11 //系统报错
#define Count 10 //雷的个数
using namespace std;
class landmine{
private:
char mine[rows][cols]; //定义两个数组,一个是让我们扫雷的矩阵 (不显示)
char show[rows][cols]; //一个是显示某一个地方的周围的雷的总个数的矩阵(显示的)
int x;
int y;
public:
landmine(); //构造函数,将两个矩阵初始化
void set_mine();//设置雷的位置
int get_num(int a,int b);//计算雷的个数
void display_mine(); //打印雷阵
void display_show(); //打印show矩阵
int autoopen(int a,int b); //无雷区自动翻开
int Sweep();//开始扫雷
};
landmine::landmine() //构造函数,将两个矩阵初始化
{
int get_num(int &a,int &b);
for (int i = 0; i < rows - 1; i++)
{
for (int j = 0; j < cols - 1; j++)
{
mine[i][j] = '0';
show[i][j] = 'x';
}
}
x=0;
y=0;
}
//设置雷的位置
void landmine::set_mine()
{
int count = Count; //雷的个数
int x = 0;
int y = 0;
srand((unsigned)time(NULL));
while (count)
{
x = rand() % 9 + 1;
y = rand() % 9 + 1; //随机取count个坐标作为雷区
if (mine[x][y] == '0')//使用该if语句,能避免重复选取同一雷区,
{ //导致雷的数目减少
mine[x][y] = '*';
count--;
}
}
}
//计算雷的个数
//遍历目标单位上下左右共八个格子
int landmine::get_num(int a,int b)
{
int count = 0;
if (mine[a - 1][b - 1] == '*')//左上方
{
count++;
}
if (mine[a- 1][b] == '*')//左边
{
count++;
}
if (mine[a - 1][b+ 1] == '*')//左下方
{
count++;
}
if (mine[a][b- 1] == '*')//上方
{
count++;
}
if (mine[a][b+ 1] == '*')//下方
{
count++;
}
if (mine[a + 1][b - 1] == '*')//右上方
{
count++;
}
if (mine[a+ 1][b] == '*')//右方
{
count++;
}
if (mine[a+ 1][b + 1] == '*')//右下方
{
count++;
}
return count;
}
void landmine::display_mine()
{
int i = 0;
int j = 0;
cout<<" ";
for (i = 1; i < cols - 1; i++)
{
cout<<" "<<i<<" "; //打印横轴
}
cout<<endl;
for (i = 1; i < rows - 1; i++)
{
cout<<i; //打印纵轴
for (j = 1; j < cols - 1; j++)
{
cout<<" "<<mine[i][j]<<" "; //打印矩阵
}
cout<<endl;
}
}
void landmine::display_show()
{
int i = 0;
int j = 0;
cout<<" ";
for (i = 1; i < cols - 1; i++)
{
cout<<" "<<i<<" "; //打印横轴
}
cout<<endl;
for (i = 1; i < rows - 1; i++)
{
cout<<i; //打印纵轴
for (j = 1; j < cols - 1; j++)
{
cout<<" "<<show[i][j]<<" "; //打印矩阵
}
cout<<endl;
}
}
int landmine::autoopen(int a,int b) //无雷区自动翻开
{
int num=0; //使用num记录翻开的格子数
if(get_num( a, b)==0) //如果周围雷数是0
{
for(int i=-1;i<2;i++)
for(int j=-1;j<2;j++) //对它周围八个格子
{
if((a+i>0)&&(a+i<rows-1)&&(b+j>0)&&(b+j<cols-1)&&(a+i!=i||b+j!=j)&&(show[a+i][b+j]=='x'))
{ //舍去隐藏边界的格子和中间的格子和已翻开的格子
num++;
show[a+i][b+j] =get_num(a+i, b+j)+'0';
num+=autoopen(a+i,b+j); //递归,直至没有四周雷数是0的格子
}
}
}
return num;
}
//开始扫雷
int landmine::Sweep()
{
int count=0;
while (count<((rows-2)*(cols-2)-Count)) //胜利条件的判断。当矩阵剩下Count个格子没翻开则获胜
{
cout<<"请输入坐标:"<<endl;
cin>>x>>y;
if (mine[x][y] == '*') //情况一:输入了雷的坐标
{
cout<<"你踩到雷了!"<<endl;
display_mine();
return 0;
}
if (get_num( x, y)==0) //情况二:输入了四周雷数是0的坐标
{
count+=autoopen(x,y);
display_show();
}
else //情况三:输入了周围有雷的坐标
{
if(show[x][y]=='x') //确保输入的坐标没有已经被翻开 //不加这个语句会导致胜利条件出错
count++; //从而出现提前获胜的情况
show[x][y] =get_num( x, y)+'0';//不加上 +'0',打印出来的不是数字而是图案??
display_show();
}
}
cout<<"恭喜你赢了!"<<endl;
return 0;
}
int main()
{landmine a;
a.set_mine();
a.display_mine();// 把雷的位置的矩阵显示出来,便于测试程序
a.display_show();
a.Sweep();
return 0;
}
评论0
最新资源