#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
#include <windows.h>
#include <sys/stat.h>
#include <string.h>
using namespace std;
const int N = 16;
const int M = 40;
int a[N][N];//a记录在 一个位置是否已经被打开,0代表未打开,1是打开
int b[N][N];//b记录所有位置周围的雷数 和是否是雷
int c[M][2];//
int d[M][2];//标记的雷的坐标
int e[N][N];
int cursor[2];
int numMark=0;
int gx=6,gy=10;//图形位置横坐标 ,图形位置竖坐标
int start,current;
struct hero
{
char name[30];
int score;
}hero;
void init();
void operate();
void saolei();
void menu();
void produce();//产生雷
void cal();
void autoOpen(int x,int y);
void open();
void check();
void heroSave(int time);
void heroRead();
void display(int b);
void gotoxy(int x, int y);
void zhenLei();
int main()
{
menu();
system("PAUSE");
return EXIT_SUCCESS;
}
void saolei()//程序
{
init();
gotoxy((int)(N/2),N+2);
cout<<"剩余雷数";
gotoxy((int)(N/2)+1,N+3);
cout<<M;
produce();
cal();
heroRead();
start=clock();
gotoxy(-gx,-gy);
while(1)
{
operate();
}
}
void menu()
{
cout<<" *************************************"<<endl;
cout<<" ************ 扫雷 ***********"<<endl;
cout<<" *************************************"<<endl;
cout<<endl<<endl<<endl<<endl<<endl<<endl;
cout<<" 1.扫雷 "<<endl;
cout<<" 2.退出游戏 "<<endl;
int choice;
choice=getch();
switch(choice)
{
case('1'):saolei();
case('2'):exit(1);
}
}
void init()//初始化
{
//输出初始化
system("CLS");
for(int i=0;i<N;i++)
{
for(int j=0;j<N;j++)
{
gotoxy(i,j);
cout<<"■";
}
cout<<endl;
}
gotoxy(-gx,-gy);
cout<<" *************************************"<<endl;
cout<<" ************ 扫雷 ***********"<<endl;
cout<<" *************************************"<<endl;
cout<<"操作:w,a,s,d控制方向;j打开;k标记雷;u震雷(相当于windows扫雷同时按鼠标左右键);"<<endl
<<"n重新开始;esc退出。";
//全部初始化为未知状态
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
{
a[i][j]=e[i][j]=0;
b[i][j]=10;
}//10 是未知状态
for(int k=0;k<M;k++)
d[k][0]=d[k][1]=0;
//光标初始化
cursor[0]=cursor[1]=0;
//标记的雷的个数初始化
numMark=0;
}
void operate()//键盘操作 w.a.s.d控制方向 j打开 k标记雷 esc退出
{
gotoxy(cursor[0],cursor[1]);
int choice ;
choice=getch();
switch(choice)
{
case ('w')://上移
{
cursor[0]=(cursor[0]==0?N-1:--cursor[0]);
gotoxy(cursor[0],cursor[1]);
break;
}
case ('s')://下移
{
cursor[0]=(cursor[0]==N-1?0:++cursor[0]);
gotoxy(cursor[0],cursor[1]);
break;
}
case ('a')://左移
{
cursor[1]=(cursor[1]==0?N-1:--cursor[1]);
gotoxy(cursor[0],cursor[1]);
break;
}
case ('d')://右移
{
cursor[1]=(cursor[1]==N-1?0:++cursor[1]);
gotoxy(cursor[0],cursor[1]);
break;
}
case ('j')://打开
{
open();
break;
}
case ('k')://标记
{
d[numMark][0]=cursor[0];
d[numMark][1]=cursor[1];
check();
break;
}
case ('u'):
{
if(e[ cursor[0] ][ cursor[1] ] == 1)
zhenLei();
break;
}
case ('n') :saolei();break;
case (27)://退出
{
gotoxy(N,0);
exit(1);
}
}
}
void produce()//产生雷
{
int num=0,i=0,flag=1;
srand((time(0)));//产生随机数
do
{
c[i][0]=rand()%N;
c[i][1]=rand()%N;
for(int j=i-1;j>=0;j--)
{
if( (c[i][0]!=c[j][0]) || (c[i][1]!=c[j][1]) )
flag=1;
else
{
flag=0;
break;
}
}
if(flag==1)
{
num++;
i++;
}
}
while(num<M);
for(int k=0;k<M;k++)
{
b[ c[k][0] ][ c[k][1] ]=9;
}
}
void cal()//计算周围有雷数
{
for(int i=0;i<N;i++)
{
for(int j=0;j<N;j++)
{
int num=0;
if(b[i][j]!=9)
{
for(int k= ( (i-1)>=0 ? (i-1) : i);k<= ( (i+1)<N ? (i+1) : i ) ; k++)//不超出边界计算雷
for(int l= ( (j-1)>=0 ? (j-1) : j);l<= ( (j+1)<N ? (j+1) : j ) ; l++)
if( b[k][l]==9 )
num++;
b[i][j]=num;
}
}
}
}
void open()
{
e[ cursor[0] ][ cursor[1] ]=1;
int flag=1;
for(int i=0;i<numMark;i++)
{
if( (d[i][0]==cursor[0]) && (d[i][1]==cursor[1]) )
{
flag=0;
break;
}
}
if(b[cursor[0]][cursor[1]]==9 && flag==1)
{
for(int i=0;i<M;i++)
{
gotoxy( c[i][0],c[i][1]);
cout<<"¤";
}
gotoxy(N,0);
cout<<"游戏结束";
gotoxy(N+1,0);
cout<<"重新开始请按n,退出请按esc";
}
else if( b[cursor[0]][cursor[1]]==0 && flag==1 )
autoOpen(cursor[0],cursor[1]);
else if(flag==1)
{
gotoxy(cursor[0],cursor[1]);
display( b[cursor[0]][cursor[1]] );
}
}
void check()
{
int flag1=1;
int temp;
for(int j=0;j<numMark;j++)
{
if(d[j][0]==cursor[0] && d[j][1]==cursor[1])
{
flag1=0;
temp=j;
break;
}
}
if(flag1==1)//和以前的记录不重复
{
cout<<"★";
numMark++;
}
else
{
for(int k=temp;k<numMark-1;k++)
{
d[k][0]=d[k+1][0];
d[k][1]=d[k+1][1];
}
cout<<"■";
numMark--;
}
gotoxy((int)(N/2)+1,N+3);
cout<<M-numMark<<" ";
if(numMark==M)
{
int flag=1;
for(int i=0;i<M;i++)
{
if(b[ d[i][0] ][ d[i][1] ]!=9 )
{
flag=0;
break;
}
}
if(flag==1)
{
current=clock();
gotoxy(N,0);
cout<<"恭喜你!已成功扫完所有雷"<<endl;
int time=(int)( (current-start)/CLK_TCK );
cout<<"所用时间为"<<time<<endl;
system("PAUSE");
if(time<hero.score)
heroSave(time);
gotoxy(N+1,0);
cout<<"重新开始请按n,退出请按esc";
}
}
}
void heroSave(int time)
{
system("CLS");
gotoxy(0,0);
cout<<"英雄榜"<<endl<<"请留下你的大名:";
cin>>hero.name;
hero.score=time;
FILE* fp = fopen("hero.dat", "wb");
fwrite(&hero, sizeof(struct hero), 1, fp);
fclose(fp);
}
void heroRead()
{
FILE* fp = fopen("hero.dat", "rb");
if(fp==NULL)
{
FILE* fpo = fopen("hero.dat", "wb+");
fclose(fpo);
}
struct stat fs;
fstat(fileno(fp),&fs);
if(fs.st_size==0)
{
FILE* fpi = fopen("hero.dat", "wb");
strcpy(hero.name,"nobody");
hero.score=999;
fwrite(&hero, sizeof(struct hero), 1, fpi);
fclose(fp);
}
fread(&hero, sizeof(struct hero), 1, fp);
fclose(fp);
gotoxy( (int)(N/2),-6);
cout<<"英雄榜";
gotoxy( (int)(N/2)+1,-8);
cout<<hero.name<<" "<<hero.score;
}
void display(int b)
{
switch(b)
{
case(0): cout<<"□"; break;//周围无雷
case(1): cout<<"①"; break;
case(2): cout<<"②"; break;
case(3): cout<<"③"; break;
case(4): cout<<"④"; break;
case(5): cout<<"⑤"; break;
case(6): cout<<"⑥"; break;
case(7): cout<<"⑦"; break;
case(8): cout<<"⑧"; break; //周围8个雷
}
}
void autoOpen(int x,int y)
{
if(b[x][y]==0&&a[x][y]==0)
{
for(int i=((x-1>=0)?x-1:x);i<=((x+1<N)?x+1:x);i++)
for(int j=((y-1>=0)?y-1:y);j<=((y+1<N)?y+1:y);j++)
{
gotoxy(i,j);
display(b[i][j]);
a[x][y]=1;
e[i][j]=1;
autoOpen(i,j);
}
}
}
void zhenLei()
{
int num=0;
int x=cursor[0],y=cursor[1];
for(int i=((x-1>=0)?x-1:x);i<=((x+1<N)?x+1:x);i++)
for(int j=((y-1>=0)?y-1:y);j<=((y+1<N)?y+1:y);j++)
for(int k=0;k<numMark;k++)
{
if( i==d[k][0] && j==d[k][1] )
num++;
}
if( nu