#include<cmath>#include<time.h>#include<easyx.h>#include<conio.h>usingnamespace std;#define Size 500 //定义窗口大小#define SquareSize 50 //定义格子大小#define BackGroundColor LIGHTGRAY //定义背景颜色constint N = Size / SquareSize;//设置地图大小为N * Nconstint Num = N * N /5;//设置总地雷数int num = Num, all = N * N - Num;//剩余地雷数和未格子访问数int Map[N +10][N +10];//地图表示(i, j)旁边的地雷数目,等于-1表示该位置为地雷bool vis[N +10][N +10];//标记是否(i, j)被访问bool vis_lm[N +10][N +10];//标记(i, j)是否被标记为地雷int dx[]={0,0,1,-1,1,-1,1,-1};int dy[]={1,-1,0,0,1,-1,-1,1};voidInit(){initgraph(Size, Size);setbkcolor(BackGroundColor);settextcolor(YELLOW);settextstyle(25,0,_T("宋体"));cleardevice();}voidBuildGameMap(){//构建地图srand((unsignedint)time(NULL));//产生随机数for(int i =1; i <= Num;++i){int x =rand()% N +1, y =rand()% N +1;while(Map[x][y]==-1){
x =rand()% N +1, y =rand()% N +1;}
Map[x][y]=-1;}//计算每个格子旁边的地雷数目for(int i =1; i <= N;++i){for(int j =1; j <= N;++j){if(Map[i][j]==-1)continue;for(int k =0; k <8;++k){if(Map[i + dx[k]][j + dy[k]]==-1)++Map[i][j];}}}}voidInitGameGraph(){//地图初始化memset(Map,0,sizeof(Map));memset(vis,false,sizeof(vis));memset(vis_lm,false,sizeof(vis_lm));
num = Num, all = N * N - Num;BuildGameMap();cleardevice();//清屏setfillcolor(WHITE);for(int i =0; i <= Size; i += SquareSize){line(i,0, i, Size);}for(int i =0; i <= Size; i += SquareSize){line(0, i, Size, i);}}intTranslate_X(int x){//左边变换return x * SquareSize + SquareSize /2;}voidGameOver(bool tag){
RECT r ={0,0, Size -1, Size -1};if(tag){drawtext(_T("Win"),&r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);}else{//游戏失败画出所有地雷setfillcolor(RED);for(int i =1; i <= N;++i){for(int j =1; j <= N;++j){if(Map[i][j]==-1){if(vis_lm[i][j])continue;//该地雷已被玩家标记,跳过outtextxy(Translate_X(i -1),Translate_X(j -1),'X');//否则显示出来}elseif(vis_lm[i][j]){//玩家标记了错误的地雷,标红fillcircle(Translate_X(i -1),Translate_X(j -1), SquareSize /2-10);}}}drawtext(_T("Failed"),&r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);}}voidHelp(){//调试函数(其实是挂)for(int i =1; i <= N;++i){for(int j =1; j <= N;++j){if(Map[i][j]==-1){outtextxy(Translate_X(i -1),Translate_X(j -1),'X');}}}}voidStartGame(){Init();while(true){InitGameGraph();//Help();bool IF_WIN =true;while(all || num){//胜利条件是所有非地雷格子均被访问且所有地雷均被标记
MOUSEMSG msg =GetMouseMsg();//获取用户鼠标信息int x =ceil(msg.x *1.0/ SquareSize *1.0), y =ceil(msg.y *1.0/ SquareSize *1.0);if(vis[x][y])continue;//该格已被访问,跳过if(msg.mkLButton){//鼠标左键按下if(Map[x][y]==-1){//如果是地雷那么游戏结束
IF_WIN =false;break;}outtextxy(Translate_X(x -1),Translate_X(y -1), Map[x][y]+'0');--all;
vis[x][y]=true;}elseif(msg.mkRButton){//鼠标右键按下if(!vis_lm[x][y]){//如果该格子已被标记,消除标记
vis_lm[x][y]=true;if(Map[x][y]==-1)--num;solidcircle(Translate_X(x -1),Translate_X(y -1), SquareSize /2-10);}elseif(vis_lm[x][y]){//否则标记
vis_lm[x][y]=false;if(Map[x][y]==-1)++num;clearrectangle((x -1)* SquareSize +1,(y -1)* SquareSize +1, x * SquareSize -1, y * SquareSize -1);}}}GameOver(IF_WIN);int t =_getch();}}intmain(){StartGame();return0;}