287场比赛

扫雷游戏(C语言版)

运行确认已编译:

# include & ltgraphics.h & gt

# include & ltstdlib.h & gt

# include & ltdos.h & gt

#定义LEFTPRESS 0xff01

#定义左键单击0xff10

#定义左拖动0xff19

#定义鼠标移动0xff08

结构体

{

int num/*网格的当前状态是什么?1有雷,0已经显示数字或者空白格子*/

int roundnum/*数一数网格周围有多少雷*/

int标志;/*右键单击显示红旗的标志,0没有红旗标志,1有红旗标志*/

}矿[10][10];

int game again = 0;/*是否重新开始的变量*/

int gamePLAY = 0;/*是不是第一次玩游戏的标志*/

int mineNUM/*计算已处理网格的数量*/

char randmineNUM[3];/*显示一串数字*/

int Keystate

int MouseExist

int MouseButton

int MouseX

int MouseY

void Init(void);/*图形驱动程序*/

void MouseOn(void);/*鼠标光标显示*/

void MouseOff(void);/*鼠标光标隐藏*/

void MouseSetXY(int,int);/*设置当前位置*/

int left press(void);/*左按*/

int right press(void);/*按下鼠标右键*/

void mouse getxy(void);/*获取当前位置*/

无效控制(void);/*游戏开始、重启和关闭*/

void GameBegain(void);/*游戏开始屏幕*/

void DrawSmile(无效);/*画一张笑脸*/

void DrawRedflag(int,int);/*显示红旗*/

void DrawEmpty(int,int,int,int);/*显示两个空格*/

void game over(void);/*游戏结束*/

void GameWin(无效);/*展示胜利*/

int MineStatistics(int,int);/*计算每个网格周围的雷数*/

int ShowWhite(int,int);/*显示无雷区的空白部分*/

void玩法(void);/*游戏过程*/

void Close(无效);/*图形关闭*/

无效总管(无效)

{

init();

control();

close();

}

Void Init(void)/*图形开始*/

{

int gd=DETECT,GM;

init graph(& amp;gd,& ampgm," c:\ \ TC ");

}

Void Close(void)/*图形关闭*/

{

closegraph();

}

Void MouseOn(void)/*鼠标光标显示*/

{

_ AX = 0x 01;

gen interrupt(0x 33);

}

Void MouseOff(void)/*鼠标光标隐藏*/

{

_ AX = 0x02

gen interrupt(0x 33);

}

Void MouseSetXY(int x,int y)/*设置当前位置*/

{

_ CX = x;

_ DX = y;

_ AX = 0x04

gen interrupt(0x 33);

}

Int LeftPress(void)/*按下鼠标左键*/

{

_ AX = 0x03

gen interrupt(0x 33);

回归(_ BX & amp;1);

}

Int RightPress(void)/*按下鼠标右键*/

{

_ AX = 0x03

gen interrupt(0x 33);

回归(_ BX & amp;2);

}

Voidmousetxy (void)/*获取当前位置*/

{

_ AX = 0x03

gen interrupt(0x 33);

MouseX = _ CX;

MouseY = _ DX

}

Void Control(void)/*游戏开始、重启和关闭*/

{

int game flag = 1;/*游戏失败后判断是否重启的标志*/

while(1)

{

If(gameFLAG)/*如果游戏失败后没有决定重启或退出游戏,继续判断*/

{

GameBegain();/*游戏初始屏幕*/

游戏性();/*特定游戏*/

If(gameAGAIN==1)/*在游戏中重启*/

{

game again = 0;

继续;

}

}

MouseOn();

game flag = 0;

If(LeftPress())/*判断是否重新开始*/

{

mouse getxy();

if(MouseX & gt;280 & amp& ampMouseX & lt300 & amp& ampMouseY & gt65 & amp& amp老鼠& lt85)

{

game flag = 1;

继续;

}

}

If(kbhit())/*判断是否按键退出*/

打破;

}

MouseOff();

}

Void DrawSmile(void)/*画一个笑脸*/

{

setfillstyle(SOLID_FILL,黄色);

filllellipse(290,75,10,10);

setcolor(黄色);

setfillstyle(SOLID_FILL,黑色);/*眼睛*/

filllellipse(285,75,2,2);

filllellipse(295,75,2,2);

setcolor(黑色);/*嘴*/

bar(287,80,293,81);

}

Void draw dflag (int i,int j)/*显示红色标志*/

{

set color(7);

setfillstyle(SOLID_FILL,红色);

bar(198+j*20,95+i*20,198+j*20+5,95+I * 20+5);

setcolor(黑色);

line(198+j*20,95+i*20,198+j*20,95+I * 20+10);

}

Void draw empty (int i,int j,int mode,int color)/*显示两种空白*/

{

setcolor(颜色);

setfillstyle(SOLID_FILL,color);

If(mode==0)/*未被点击的大网格*/

bar(200+j*20-8,100+i*20-8,200+j*20+8,100+I * 20+8);

其他

If(mode==1)/*单击空白小网格*/

bar(200+j*20-7,100+i*20-7,200+j*20+7,100+I * 20+7);

}

无效游戏增益(void)/*游戏开始屏幕*/

{

int i,j;

clear device();

如果(玩法!=1)

{

MouseSetXY(290,70);/*鼠标的初始位置作为其初始坐标*/

MouseX = 290

MouseY = 70

}

游戏性= 1;/*下次按重新启动时,鼠标将不会被重新初始化*/

mineNUM = 0;

setfillstyle(SOLID_FILL,7);

吧(190,60,390,290);

for(I = 0;我& lt10;I++)/*画一个网格*/

for(j = 0;j & lt10;j++)

DrawEmpty(i,j,0,8);

set color(7);

draw smile();/*画一张脸*/

randomize();__page_break__

for(I = 0;我& lt10;I++)/*100方格随机分配是否有地雷*/

for(j = 0;j & lt10;j++)

{

我的[我][j]。num = random(8);/*如果随机数的结果是1,说明这个格子里有地雷*/

if(我的[i][j]。num==1)

minenum++;/*现有矿井数加1*/

其他

我的[我][j]。num = 2;

我的[我][j]。flag = 0;/*表示没有红旗标志*/

}

sprintf(randmineNUM,“%d”,mineNUM);/*显示本次地雷总数*/

set color(1);

settextstyle(0,0,2);

outtextxy(210,70,randmineNUM);

mineNUM = 100-mineNUM;/*变量的空白单元格数*/

MouseOn();

}

Void GameOver(void)/*游戏结束画面*/

{

int i,j;

set color(0);

for(I = 0;我& lt10;i++)

for(j = 0;j & lt10;j++)

If(我的[i][j]。num==1)/*显示所有地雷*/

{

DrawEmpty(i,j,0,RED);

setfillstyle(SOLID_FILL,黑色);

filllellipse(200+j * 20,100+i*20,7,7);

}

}

Void GameWin(void)/*显示胜利*/

{

set color(11);

settextstyle(0,0,2);

outtextxy(230,30,“你赢了!”);

}

Int MineStatistics(int i,int j)/*统计每个网格周围的雷数*/

{

int nNUM = 0;

if(I = = 0 & amp;& ampJ==0)/*左上网格的统计*/

{

if(我的[0][1])。num==1)

nnum++;

if(我的[1][0])。num==1)

nnum++;

if(我的[1][1]。num==1)

nnum++;

}

其他

if(I = = 0 & amp;& ampJ==9)/*右上网格的统计*/

{

if(我的[0][8])。num==1)

nnum++;

if(我的[1][9])。num==1)

nnum++;

if(我的[1][8])。num==1)

nnum++;

}

其他

if(I = = 9 & amp;& ampJ==0)/*左下角网格的统计*/

{

if(我的[8][0])。num==1)

nnum++;

if(我的[9][1])。num==1)

nnum++;

if(我的[8][1])。num==1)

nnum++;

}

其他

if(I = = 9 & amp;& ampJ==9)/*右下角网格的统计*/

{

如果(我的[9][8])。num==1)

nnum++;

如果(我的[8][9])。num==1)

nnum++;

如果(我的[8][8])。num==1)

nnum++;

}

Else if(j==0)/*左边第一列网格的统计*/

{

if(我的[i][j+1])。num==1)

nnum++;

if(我的[i+1][j]。num==1)

nnum++;

if(我的[i-1][j]。num==1)

nnum++;

if(我的[i-1][j+1])。num==1)

nnum++;

if(我的[i+1][j+1])。num==1)

nnum++;

}

Else if(j==9)/*右边第一列网格的统计*/

{

if(我的[i][j-1])。num==1)

nnum++;

if(我的[i+1][j]。num==1)

nnum++;

if(我的[i-1][j]。num==1)

nnum++;

if(我的[i-1][j-1])。num==1)

nnum++;

if(我的[i+1][j-1])。num==1)

nnum++;

}

Else if(i==0)/*第一个网格的统计*/

{

if(我的[i+1][j]。num==1)

nnum++;

if(我的[i][j-1])。num==1)

nnum++;

if(我的[i][j+1])。num==1)

nnum++;

if(我的[i+1][j-1])。num==1)

nnum++;

if(我的[i+1][j+1])。num==1)

nnum++;

}

Else if(i==9)/*最后一个网格的统计*/

{

if(我的[i-1][j]。num==1)

nnum++;

if(我的[i][j-1])。num==1)

nnum++;

if(我的[i][j+1])。num==1)

nnum++;

if(我的[i-1][j-1])。num==1)

nnum++;

if(我的[i-1][j+1])。num==1)

nnum++;

}

Else/*普通格的统计*/

{

if(我的[i-1][j]。num==1)

nnum++;

if(我的[i-1][j+1])。num==1)

nnum++;

if(我的[i][j+1])。num==1)

nnum++;

if(我的[i+1][j+1])。num==1)

nnum++;

if(我的[i+1][j]。num==1)

nnum++;

if(我的[i+1][j-1])。num==1)

nnum++;

if(我的[i][j-1])。num==1)

nnum++;

if(我的[i-1][j-1])。num==1)

nnum++;

}__page_break__

返回(nNUM);/*返回网格周围雷数的统计结果*/

}

Int ShowWhite(int i,int j)/*显示没有雷区的空白部分*/

{

If(我的[I] [j]。flag = = 1 ||矿[I] [j]。num = = 0)/*如果有红旗或者网格已经处理过,则不判*/

返回;

mineNUM-;/*显示数字或空格的格子表示又处理了一个格子,当所有格子都处理完后,表示胜利*/

if(我的[i][j]。roundnum==0。& amp我的[我][j]。num!=1)/*显示空间*/

{

DrawEmpty(i,j,1,7);

我的[我][j]。num = 0;

}

其他

if(我的[i][j]。roundnum!=0)/*输出闪电数*/

{

DrawEmpty(i,j,0,8);

sprintf(randmineNUM," %d ",Mine[i][j]。round num);

setcolor(红色);

outtextxy(195+j*20,95+i*20,randmineNUM);

我的[我][j]。num = 0;/*已经输出闪电数的网格表示该网格已经与0一起使用*/

返回;

}

/*递归显示8个方向的所有空白网格*/

如果(我!= 0 & amp& amp我的[i-1][j]。num!=1)

ShowWhite(i-1,j);

如果(我!= 0 & amp& ampj!= 9 & amp& amp我的[i-1][j+1]。num!=1)

ShowWhite(i-1,j+1);

如果(j!= 9 & amp& amp我的[i][j+1]。num!=1)

ShowWhite(i,j+1);

如果(j!= 9 & amp& amp我!= 9 & amp& amp我的[i+1][j+1]。num!=1)

ShowWhite(i+1,j+1);

如果(我!= 9 & amp& amp我的[i+1][j]。num!=1)

ShowWhite(i+1,j);

如果(我!= 9 & amp& ampj!= 0 & amp& amp我的[i+1][j-1]。num!=1)

ShowWhite(i+1,j-1);

如果(j!= 0 & amp& amp我的[i][j-1]。num!=1)

ShowWhite(i,j-1);

如果(我!= 0 & amp& ampj!= 0 & amp& amp我的[i-1][j-1]。num!=1)

ShowWhite(i-1,j-1);

}

Void游戏玩法(void)/*游戏过程*/

{

int i,j,Num/*Num用于接收统计函数并返回一个网格周围有多少个地雷*/

for(I = 0;我& lt10;i++)

for(j = 0;j & lt10;j++)

我的[我][j]。roundnum=MineStatistics(i,j);/*计算每个网格周围有多少地雷*/

而(!kbhit())

{

If(LeftPress())/*按鼠标左键*/

{

mouse getxy();

if(MouseX & gt;280 & amp& ampMouseX & lt300 & amp& ampMouseY & gt65 & amp& amp老鼠& lt85)/*重新开始*/

{

MouseOff();

game again = 1;

打破;

}

if(MouseX & gt;190。& ampMouseX & lt390 & amp& ampMouseY & gt90 & amp& amp老鼠& lt290)/*当前鼠标位置在网格内*/

{

j =(MouseX-190)/20;/*x坐标*/

I =(MouseY-90)/20;/*y坐标*/

If(我的[i][j]。flag==1)/*如果网格有红色标志,则左键无效*/

继续;

if(我的[i][j]。num!=0)/*如果网格没有被处理*/

{

If(我的[i][j]。num==1)/*鼠标点击的格子是地雷*/

{

MouseOff();

game over();/*游戏失败*/

打破;

}

Else/*鼠标按下的格子不是地雷*/

{

MouseOff();

Num=MineStatistics(i,j);

If(Num==0)/*如果周围没有地雷,使用递归算法显示空白网格*/

ShowWhite(i,j);

Else/*按网格。周围有地雷*/

{

sprintf(randmineNUM," %d ",Num);/*输出当前网格周围的雷数*/

setcolor(红色);

outtextxy(195+j*20,95+i*20,randmineNUM);

mineNUM-;

}

MouseOn();

我的[我][j]。num = 0;/*选中网格周围的雷数变为0,表示该网格已被使用*/

if(mineNUM & lt;1)/*胜利*/

{

GameWin();

打破;

}

}

}

}

}

If(RightPress())/*鼠标右键键盘按*/

{

mouse getxy();

if(MouseX & gt;190。& ampMouseX & lt390 & amp& ampMouseY & gt90 & amp& amp老鼠& lt290)/*当前鼠标位置在网格内*/

{

j =(MouseX-190)/20;/*x坐标*/

I =(MouseY-90)/20;/*y坐标*/

MouseOff();

if(我的[i][j]。flag = = 0 & amp& amp我的[我][j]。num!=0)/*本来没有红旗,现在显示出来了*/

{

DrawRedflag(i,j);

我的[我][j]。flag = 1;

}

其他

If(我的[i][j]。flag==1)/*如果有红旗标志,按右按钮,红旗消失*/

{

DrawEmpty(i,j,0,8);

我的[我][j]。flag = 0;

}

}

MouseOn();

睡眠(1);

}

}

}