//written by soheil setayeshi
//www.codecorona.com
#include <iostream>
#include <time.h>
#include <vector>
using namespace std;
class mine{
friend class sweeper;
bool bomb;
bool open;
bool pass;
int num;
};
//****************************************************
class sweeper{
public:
sweeper(int);
void play();
private:
void cleaner(int,int);
void display();
void lose();
bool checkwin();
mine **map;
int length;
int width;
int mines;
};
//****************************************************
sweeper :: sweeper(int difficulty)
{
int i,j,k,l,x,n;
vector<int> v;
srand(time(0));
switch (difficulty)
{
case 1: width=9;
length=9;
mines=10;
break;
case 2: width=16;
length=16;
mines=40;
break;
case 3: width=16;
length=32;
mines=99;
break;
default:exit(0);
}
map=new mine* [width];
for (i=0;i<width;i++)
map[i]=new mine [length];
for (i=0;i<width;i++)
for (j=0;j<length;j++)
{
map[i][j].num=0;
map[i][j].bomb=false;
map[i][j].open=false;
map[i][j].pass=false;
}
n=width*length;
for (i=0;i<n;i++)
v.push_back(i);
for (i=0;i<mines;i++)
{
x=rand()%n--;
map[v[x]/length][v[x]%length].bomb=true;
v.erase(v.begin()+x);
}
for (i=0;i<width;i++)
for (j=0;j<length;j++)
for (k=i-1;k<=i+1;k++)
for (l=j-1;l<=j+1;l++)
if (k>-1 && k<width && l>-1 && l<length)
if (map[k][l].bomb)
(map[i][j].num)++;
}
//****************************************************
void sweeper :: display()
{
int i,j;
cout<<" ";
for (i=0;i<length;i++)
{
cout<<i+1;
if (i+1<10) cout<<' ';
}
cout<<"\n";
for (i=0;i<width;i++)
{
if (i+1<10) cout<<i+1<<' ';
else cout<<i+1;
for (j=0;j<length;j++)
if (map[i][j].open)
if (map[i][j].bomb)
cout<<"* ";
else if (!map[i][j].num)
cout<<" ";
else
cout<<map[i][j].num<<" ";
else
cout<<"# ";
cout<<"\n";
}
cout<<endl;
}
//****************************************************
void sweeper::play()
{
int x,y;
while(1)
{
system("cls");
display();
while(1)
{
cout<<"FROM:\n";
cout<<"X:";
cin>>x;
x--;
if (x<0 || x>=width)
{
cout<<'\a';
system("cls");
display();
continue;
}
cout<<"Y:";
cin>>y;
y--;
if (y<0 || y>=length)
{
cout<<'\a';
system("cls");
display();
continue;
}
if (map[x][y].open)
{
cout<<'\a';
system("cls");
display();
continue;
}
break;
}
if (map[x][y].bomb)
lose();
else
{
map[x][y].open=true;
cleaner(x,y);
checkwin();
}
}
}
//****************************************************
void sweeper::lose()
{
int i,j;
cout<<"\a\a";
for (i=0;i<width;i++)
{
if (length == 32) cout<<"\t";
else if (length == 16) cout<<"\t\t\t";
else cout<<"\t\t\t\t";
for (j=0;j<length;j++)
if (map[i][j].open)
cout<<map[i][j].num<<' ';
else if (map[i][j].bomb)
cout<<"* ";
else
cout<<"# ";
cout<<endl;
}
cout<<"\n GAME OVER ... YOU LOSE\n";
system("pause");
exit(0);
}
//****************************************************
bool sweeper::checkwin()
{
int i,j,n=width*length-mines;
for (i=0;i<width;i++)
for (j=0;j<length;j++)
if (map[i][j].open)
n--;
if (!n)
{
cout<<"\a\a\a";
for (i=0;i<width;i++)
{
if (length == 32) cout<<"\t";
else if (length == 16) cout<<"\t\t\t";
else cout<<"\t\t\t\t";
for (j=0;j<length;j++)
if (map[i][j].open)
cout<<map[i][j].num<<' ';
else
cout<<"* ";
cout<<endl;
}
cout<<"\n GAME OVER ... YOU WIN!!!!\n";
system("pause");
exit(0);
}
}
//****************************************************
void sweeper::cleaner(int x,int y)
{
if (x>=0 && y>=0 && x<width && y<length && map[x][y].num == 0 && map[x][y].pass == false)
{
int i,j;
map[x][y].pass=true;
for (i=x-1;i<=x+1;i++)
for (j=y-1;j<=y+1;j++)
if (i>=0 && j>=0 && i<width && j<length)
map[i][j].open=true;
cleaner(x-1,y-1);//up left
cleaner(x-1,y);//up
cleaner(x-1,y+1);//up right
cleaner(x,y-1);//left
cleaner(x,y+1);//right
cleaner(x+1,y-1);//down left
cleaner(x+1,y);//down
cleaner(x+1,y+1);//down right
}
}
//****************************************************
int main()
{
system("color 80");
int state;
cout << "Select difficulty mode:\n\n";
cout << "1 ) Easy : With 9*9 map & 10 mine\n\n";
cout << "2 ) Medium : With 16*16 map & 40 mine\n\n";
cout << "3 ) Difficult : With 16*32 map & 99 mine\n\n";
cout << "or type another key to quit\n";
cin>>state;
sweeper game(state);
game.play();
system("pause");
return 0;
}