两年前写的扫雷、也算完成了吧!同学说要用这个做毕业设计……刚想起来发上来!代码很丑陋。本来要加入可以选择难度的菜单,但是#define这个东西真是气人、也怪我C没学好。搞得我加入开始画面的心情也没有了!计时器也没有。另外还有一点小Bug、待修复。代码也加了点注释、主要是我发现以前写的东西现在我自己都看不懂了。
完整的工作间下载地址:http://download.csdn.net/detail/weizi4332/6814219
代码如下:
============================================================================
//
// 本程序使用了EasyX图形库2010惊蛰版 //
//
//扫雷的玩法是在一个9*9(初级),16*16(中级), //
//16*30(高级),或自定义大小的方块矩阵中随机布置一 //
//定量的地雷(初级为10个,中级为40个,高级为99个)。 //
//由玩家逐个翻开方块,以找出所有地雷为最终游戏目标。//
//如果玩家翻开的方块有地雷,则游戏结束。 //
//
#include "stdio.h"
#include "graphics.h"
#include "conio.h"
#include "time.h"
#define PIXEL 20 //设置每格的边长
#define GRADE_ROW 16 //行数
#define GRADE_COL 16 //列数
#define MINE_NUM 40 //地雷数量
//每个格子的数据
typedef struct
{
int mine_num; //周围地雷数量
bool has_mine; //true表示有雷
bool checked; //true表示已挖掘
bool flag; //true表示已标记
}CHECK;
//随机产生地图
void CreatMap(CHECK map[GRADE_ROW][GRADE_COL])
{
srand(time(0));
//初始化地图、并将0视为无雷
for(int i=0;i<GRADE_ROW;i++)
for(int j=0;j<GRADE_COL;j++)
{
map[i][j].mine_num=0;
map[i][j].has_mine=false;
map[i][j].checked=false;
map[i][j].flag=false;
}
//随机产生0~80间的不重复的数MINE_NUM个地雷位置
int num=0,temp;
int mine[MINE_NUM];
while(num<MINE_NUM)
{
if(num==0)
mine[num]=rand()%(GRADE_ROW*GRADE_COL);
else
{
newnum: temp=rand()%(GRADE_ROW*GRADE_COL);
for(int i=0;i<num;i++)
{
if(temp==mine[i])
goto newnum;
}
mine[num]=temp;
}
num++;
}
//将产生的MINE_NUM个地雷置入雷区
for(i=0;i<MINE_NUM;i++)
{
map[mine[i]/(GRADE_COL-1)][mine[i]%(GRADE_COL-1)].has_mine=true;
}
//产生地雷的逻辑分布图
int around_mine_num;
for(i=0;i<GRADE_ROW;i++)
for(int j=0;j<GRADE_COL;j++)
{
//本块无雷时判断其周围雷数
if(!map[i][j].has_mine)
{
around_mine_num=0;
for(int I=-1;I<=1;I++)
for(int J=-1;J<=1;J++)
{
if((i+I)>=0 && (j+J)>=0 && (i+I)<GRADE_ROW && (j+J)<GRADE_COL)
{
if(map[i+I][j+J].has_mine)
around_mine_num++;
}
}
map[i][j].mine_num=around_mine_num;
}
}
}
//递归筛选出无雷区
void find_around(CHECK map[GRADE_ROW][GRADE_COL],int x,int y)
{
//加载图像
IMAGE img,mine,none,flag,menu;
//loadimage(&img,"img.bmp");
//loadimage(&mine,"mine.bmp");
//loadimage(&none,"none.bmp");
//loadimage(&flag,"flag.bmp");
//loadimage(&menu,"menu.bmp");
loadimage(&img,"IMAGE","img");
loadimage(&mine,"IMAGE","mine");
loadimage(&none,"IMAGE","none");
loadimage(&flag,"IMAGE","flag");
loadimage(&menu,"IMAGE","menu");
for(int I=-1;I<=1;I++)
for(int J=-1;J<=1;J++)
{
if((x+I)>=0 && (y+J)>=0 && (x+I)<GRADE_ROW && (y+J)<GRADE_COL)
{
if(map[x+I][y+J].mine_num==0 && map[x+I][y+J].flag==false && map[x+I][y+J].checked==false)
{
putimage(x*PIXEL,y*PIXEL,&none);
map[x+I][y+J].checked=true;
find_around(map,x+I,y+J);
}
else if(map[x+I][y+J].mine_num>=1 && map[x+I][y+J].mine_num<=8 && map[x+I][y+J].checked==false && map[x+I][y+J].flag==false)
{
putimage((x+I)*PIXEL,(y+J)*PIXEL,&none);
map[x+I][y+J].checked=true;
char c=char(map[x+I][y+J].mine_num + 48); //int转换为char
setcolor(0x0000ee);
setbkmode(TRANSPARENT); //背景设为透明
RECT r = {(x+I)*PIXEL, (y+J)*PIXEL, (x+I+1)*PIXEL,(y+J+1)*PIXEL};
drawtext(c, &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
//outtextxy(((m.x/PIXEL)*PIXEL),((m.y/PIXEL)*PIXEL),c);
map[x+I][y+J].checked=true;
}
}
}
}
void GameOver(CHECK map[GRADE_ROW][GRADE_COL])
{
//加载图像
IMAGE img,mine,none,flag,menu;
//loadimage(&img,"img.bmp");
//loadimage(&mine,"mine.bmp");
//loadimage(&none,"none.bmp");
//loadimage(&flag,"flag.bmp");
//loadimage(&menu,"menu.bmp");
loadimage(&img,"IMAGE","img");
loadimage(&mine,"IMAGE","mine");
loadimage(&none,"IMAGE","none");
loadimage(&flag,"IMAGE","flag");
loadimage(&menu,"IMAGE","menu");
for(int i=0;i<GRADE_COL;i++)
for(int j=0;j<GRADE_ROW;j++)
{
if(map[i][j].has_mine==true)
putimage(i*PIXEL,j*PIXEL,&mine);
}
Sleep(1000);
RECT r = {0, 0, PIXEL*GRADE_COL, PIXEL*GRADE_ROW};
setfont(PIXEL*GRADE_COL/5,0,"Times New Roman");
setbkcolor(BLACK);
drawtext("GAME OVER", &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
getchar();
}
int main()
{
initgraph(PIXEL*GRADE_COL,PIXEL*GRADE_ROW);
MOUSEMSG m;
//加载图像
IMAGE img,mine,none,flag,menu;
//loadimage(&img,"img.bmp");
//loadimage(&mine,"mine.bmp");
//loadimage(&none,"none.bmp");
//loadimage(&flag,"flag.bmp");
//loadimage(&menu,"menu.bmp");
loadimage(&img,"IMAGE","img");
loadimage(&mine,"IMAGE","mine");
loadimage(&none,"IMAGE","none");
loadimage(&flag,"IMAGE","flag");
loadimage(&menu,"IMAGE","menu");
//初始化地图
CHECK map[GRADE_ROW][GRADE_COL];
CreatMap(map);
for(int i=0;i<GRADE_COL;i++)
for(int j=0;j<GRADE_ROW;j++)
putimage(i*PIXEL,j*PIXEL,&img);
putimage(GRADE_COL*PIXEL,0,&menu);
while(1)
{
m=GetMouseMsg();
if(m.x<PIXEL*GRADE_COL)
{
switch(m.uMsg)
{
case WM_LBUTTONDOWN:
//当挖到地雷时
if(map[m.x/PIXEL][m.y/PIXEL].has_mine==true && map[m.x/PIXEL][m.y/PIXEL].flag==false)
{
putimage((m.x/PIXEL)*PIXEL,(m.y/PIXEL)*PIXEL,&mine);
GameOver(map);
}
//没有挖到地雷
else if(map[m.x/PIXEL][m.y/PIXEL].has_mine==false && map[m.x/PIXEL][m.y/PIXEL].flag==false)
{
//周围有地雷
if(map[m.x/PIXEL][m.y/PIXEL].mine_num!=0)
{
putimage((m.x/PIXEL)*PIXEL,(m.y/PIXEL)*PIXEL,&none);
map[m.x/PIXEL][m.y/PIXEL].checked=true;
char c=char(map[m.x/PIXEL][m.y/PIXEL].mine_num + 48); //int转换为char
setcolor(0x0000ee);
setbkmode(TRANSPARENT); //背景设为透明
RECT r = {(m.x/PIXEL)*PIXEL, (m.y/PIXEL)*PIXEL, (m.x/PIXEL+1)*PIXEL,(m.y/PIXEL+1)*PIXEL};
drawtext(c, &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
//outtextxy(((m.x/PIXEL)*PIXEL),((m.y/PIXEL)*PIXEL),c);
}
//周围无雷
else
{
putimage((m.x/PIXEL)*PIXEL,(m.y/PIXEL)*PIXEL,&none);
find_around(map,m.x/PIXEL,m.y/PIXEL);
}
}
break;
case WM_RBUTTONDOWN:
if(map[m.x/PIXEL][m.y/PIXEL].checked==false && map[m.x/PIXEL][m.y/PIXEL].flag==false)
{
putimage((m.x/PIXEL)*PIXEL,(m.y/PIXEL)*PIXEL,&flag);
map[m.x/PIXEL][m.y/PIXEL].flag=true;
}
else if(map[m.x/PIXEL][m.y/PIXEL].checked==false && map[m.x/PIXEL][m.y/PIXEL].flag==true)
{
putimage((m.x/PIXEL)*PIXEL,(m.y/PIXEL)*PIXEL,&img);
map[m.x/PIXEL][m.y/PIXEL].flag=false;
}
break;
}
}
}
getch();
closegraph();
return 0;
}