扫雷游戏实现

这是一个使用C语言实现扫雷游戏的代码示例,包括游戏界面绘制、布雷、展开数字、计时器等功能。代码中包含了初始化系统、设置雷、判断游戏胜利条件等关键函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <graphics.h>
#include <conio.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>

#pragma comment(lib,“Winmm.lib”)

void draw_circul(int x,int y,int row,int col);
int init_system();
void draw_mode(int x,int y,int wm_wh,int type);
void draw_framework();
void set_mine(int num);
void draw_min_max_framework(int x1,int y1,int x2,int y2);
void draw_happyface(int type);
void draw_clock_score();
void draw_mine(int row,int col);
void mouse_clear_mine();
void round_mine_num();
int deal_space(int x, int y);
void deal_situation(int y,int x);
void output_num();
void show_space(int y,int x);
void show_num(int y,int x);
int win_judge();
void darw_menu();
void sort_rank();

#define FLAG 20
#define win m_col*m_row
#define mine_num 20 //雷的数目

FILE *fp;
double begain,finsh;
char s[10];
int m_maxx,m_maxy;
int m_row,m_col,m_wh;
int x0,y0,num=0;
int **p;
int t;

/*typedef struct News //保存信息
{
char name[10]; //姓名
int count; //时间
}news;
*/

int win_judge() //游戏胜利条件判断
{
int flag=0; //flag=win(总格子数)-mine_num(雷数)代表成功
for (int j=0;j<m_col;j++)
for (int i=0;i<m_row;i++)
{
if (p[i][j]>10) //全部为-1时胜利
flag++;
}
if(flag==win-mine_num)
return 1;
return 0;
}

void music() //添加音乐
{
initgraph(640,480);
mciSendString(“open 让全世界知道我爱你.mp3 alias mymusic”,NULL,0,NULL);
outtextxy(0,0,“按任意键播放”);
getch();
mciSendString(“play mymusic”,NULL,0,NULL);
/* outtextxy(0,0,“按任意键结束”);
getch();
mciSendString(“stop mymusic”,NULL,0,NULL);
mciSendString(“close mymusic”,NULL,0,NULL);
outtextxy(0,0,“按任意键退出程序”);
getch();
closegraph();*/
}

int main(void)
{
// music();
init_system();//初始化系统
if(!init_system())
exit(0);
x0=(m_maxx-m_col*(m_wh+1))/2;
y0=(m_maxy-m_row*(m_wh+1))/2;

draw_circul(x0,y0,m_row,m_col);     //初始化界面
draw_framework();                   //框架
set_mine(mine_num);                     //布雷
round_mine_num();                   //计算周围雷数
darw_menu();
mouse_clear_mine();                 //鼠标清雷

getch();
closegraph();
return 0;

}
//用时排序
void sort_rank()
{
int a[10],t,i=0; //只排前十名
if((fp=fopen(“1.txt”,“r”))==NULL)
{
printf(“open error!\n”);
exit(0);
}
int k=0;
while(!feof(fp))
{
if(k<10)
{
fscanf(fp,"%d ",&a[k]);
k++;
}
else
break;
}
fclose(fp);
for(i=0;i<k-1;i++) //冒泡排序
for(int j=0;j<k-i-1;j++)
{
if(a[j]>a[j+1])
{
t=a[j+1];
a[j+1]=a[j];
a[j]=t;
}
}
if((fp=fopen(“1.txt”,“w”))NULL)
{
printf(“open error!”);
exit(0);
}
for(i=0;i<k;i++)
{
fprintf(fp,"%d ",a[i]);
}
fclose(fp);
//打印部分
for(i=0;i<k;i++)
{
if(k
0)
printf(“暂无记录,少侠继续努力啊!\n”);
else
printf(“第%d名:%d秒\n”,i+1,a[i]);
}
}

//鼠标清雷
void mouse_clear_mine()
{
MOUSEMSG m;
m=GetMouseMsg();

int x,y;
begain=clock();
while(1)
{
    m=GetMouseMsg();
    x=(m.x-x0)/(m_wh+1);
    y=(m.y-y0)/(m_wh+1);
    switch(m.uMsg)
    {
        case WM_LBUTTONDOWN:
        {
            if (x0<m.x && m.x<((m_wh+1)*m_col+x0) && m.y>y0 && m.y<(y0+(m_wh+1)*m_row) && p[y][x]<8 && p[y][x]>-3)
            {
                if (p[y][x]==-1)  //踩雷
                {
                    draw_happyface(2);   //画哭脸
                    for (int j=0;j<m_col;j++)
                        for (int i=0;i<m_row;i++)
                        {                   
                            if (p[i][j]==-1)    //画出所有雷
                                draw_mine(j,i);   //画雷函数
                            p[i][j]+=FLAG;
                        }
                    setlinecolor(RED);
                    line(x0+x*(m_wh+1)+2,y0+y*(m_wh+1)+2,x0+(x+1)*(m_wh+1)-2,y0+(y+1)*(m_wh+1)-2);
                    line(x0+(x+1)*(m_wh+1)-2,y0+y*(m_wh+1)+2,x0+x*(m_wh+1)+2,y0+(y+1)*(m_wh+1)-2);

                }
                if (p[y][x]==0)   //展开
                {
                    show_space(y,x);
                }
                if(p[y][x]>0 && p[y][x]<9) 
                {
                    show_num(y,x);
                } 
            }
            else if (m.x>m_maxx/2-m_wh-5 && m.x<m_maxx/2+m_wh+5 && m.y>y0-m_wh*5/2-5 && m.y<y0-m_wh/2+5) 
            {
                draw_mode(m_maxx/2-m_wh-5,y0-m_wh*5/2-5,2*m_wh+10,1);
                Sleep(20);
                main();
            }
			else if(40<m.x&&m.x<100&&140<m.y&&m.y<170)
			{
				closegraph();
				system("cls");
				printf("====排行榜====\n");
				sort_rank();
				system("pause");
				main();
				
			}
			else if(40<m.x&&m.x<100&&190<m.y&&m.y<220)
			{
				closegraph();
				system("cls");
				printf("本游戏由1073修改网络扫雷所得作品\n");
				system("pause");
				main();
			}
            else if (num==win)
            {
                exit(1);
            }else
			{
				;
			}
        }break;
        case WM_RBUTTONDOWN:
            {
                if (x0<m.x && m.x<((m_wh+1)*m_col+x0) && m.y>y0 && m.y<(y0+(m_wh+1)*m_row))
                {
                    if (p[y][x]>15 || p[y][x]==-2)
                    {
                        ;
                    }
                    else if (p[y][x]<-10)
                    {
                        draw_mode(x0+(m_wh+1)*x,y0+(m_wh+1)*y,m_wh,1);
                        p[y][x]+=FLAG;
                    }
                    else
                    {
                        setlinecolor(RED);
                        line(x0+(m_wh+1)*x+3,y0+(m_wh+1)*y+3,x0+(m_wh+1)*x+3,y0+(m_wh+1)*(y+1)-6);
                        rectangle(x0+(m_wh+1)*x+3,y0+(m_wh+1)*y+3,x0+(m_wh+1)*(x+1)-8,y0+(m_wh+1)*y+8);
                        setfillstyle(SOLID_FILL);
                        setfillcolor(RED);
                        floodfill(x0+(m_wh+1)*x+4,y0+(m_wh+1)*y+4,RED);
                        p[y][x]-=FLAG;
                    }
                }
                else
                {
                    ;
                }
            }break; 
    }
	if(win_judge()) //判断是否获得胜利
    {
		Sleep(1000);
		closegraph();
		initgraph(640,480);
		outtextxy(200,200,"游戏结束,您用时");
		outtextxy(320,200,s);
        outtextxy(332,200,"秒!");
		draw_mode(200,250,64,1);
		draw_mode(280,250,64,1);
		outtextxy(208,274,"新游戏");
		outtextxy(296,274,"退出");
		if((fp=fopen("1.txt","a+"))==NULL)
		{
			printf("open error!");
			exit(0);
		}
		fprintf(fp,"%d ",t);
		fclose(fp);
		MOUSEMSG n;
		while(1)
		{
			n=GetMouseMsg();
			switch(n.uMsg)
			{
			case WM_LBUTTONDOWN:
				{
					if(200<n.x  && n.x<264 && 250<n.y  && n.y <314)
					{
				        main();
					}
				    else if(296<n.x&&n.x<360&&250<n.y&&n.y<314)
					{
						closegraph();
						system("cls");
						printf("感谢使用扫雷游戏,本游戏功能尚在完善中.....\n");
						system("pause");
					    exit(0);
					}
				}
			    break;
			}
		}
		system("pause");
		closegraph();
        exit(0);
	}
 	finsh=clock();
	t=(int)(finsh-begain)/CLOCKS_PER_SEC;
    sprintf(s,"%d",t);
	settextcolor(WHITE);
	setbkmode(OPAQUE);     //OPAQUE用当前背景的画刷的颜色输出显示文字的背景
    outtextxy(x0+20,y0-2*m_wh+2,s);   //在左边框输出游戏时间
}

}

void darw_menu() //打印菜单
{
rectangle(40,140,100,170);
outtextxy(46,147,“排行榜”);
rectangle(40,190,100,220);
outtextxy(54,197,“帮助”);
}

void show_space(int y,int x) //展开
{
if(y>=0 && y<m_row && x>=0 && x<m_col && p[y][x]==0) //若周围没有雷就递归调用展开
{
draw_mode(x0+x*(m_wh+1),y0+y*(m_wh+1),m_wh,2);
p[y][x]+=FLAG;
num++;
show_space(y-1,x);
show_space(y,x-1);
show_space(y+1,x);
show_space(y,x+1);
}
if(y>=0 && y<m_row && x>=0 && x<m_col && p[y][x]>0 && p[y][x]<=8) //有雷就输出对应数字及颜色
{
show_num(y,x);
num++;
}
}

void show_num(int y,int x) //给每一个数字对应一个颜色
{
draw_mode(x0+x*(m_wh+1),y0+y*(m_wh+1),m_wh,2);
if (p[y][x]==1)
settextcolor(RED);
if (p[y][x]==2)
settextcolor(GREEN);
if (p[y][x]==3)
settextcolor(BLUE);
if (p[y][x]==4)
settextcolor(YELLOW);
if (p[y][x]==5)
settextcolor(BROWN);
if (p[y][x]==6)
settextcolor(RED);
if (p[y][x]==7)
settextcolor(GREEN);
if (p[y][x]==8)
settextcolor(BLUE);
setbkmode(TRANSPARENT); //该函数保持背景颜色不变,使用透明的输出,另一种(OPAQUE)
outtextxy(x0+x*(m_wh+1)+m_wh/3,y0+y*(m_wh+1)+m_wh/8,p[y][x]+48);
p[y][x]+=FLAG;
}
//布雷
void set_mine(int num)
{
int k,i,j;
int m=0;

srand((unsigned)time(NULL));
while(m<num)
{
    k=rand()%(m_row*m_col);
    j=k%m_col;
    i=k/m_col;
    if(p[i][j]!=-1)
    {   
        p[i][j]=-1;
        m++;
    }
}

}
//显示雷数
void round_mine_num()
{
int i,j;
for (i=0;i<m_row;i++)
for (j=0;j<m_col;j++)
{
if (j<m_col-1 && i<m_row-1 && p[i][j]-1 && p[i+1][j+1]!=-1)
p[i+1][j+1]++;
if (i<m_row-1 && p[i][j]
-1 && p[i+1][j]!=-1)
p[i+1][j]++;
if (i<m_row-1 && j>0 && p[i][j]-1 && p[i+1][j-1]!=-1)
p[i+1][j-1]++;
if (j>0 && p[i][j]
-1 && p[i][j-1]!=-1)
p[i][j-1]++;
if (i>0 && j>0 && p[i][j]-1 && p[i-1][j-1]!=-1)
p[i-1][j-1]++;
if (i>0 && p[i][j]
-1 && p[i-1][j]!=-1)
p[i-1][j]++;
if (i>0 && j<m_col-1 && p[i][j]-1 && p[i-1][j+1]!=-1)
p[i-1][j+1]++;
if (j<m_col-1 && p[i][j]
-1 && p[i][j+1]!=-1)
p[i][j+1]++;
}
}
//画一个雷
void draw_mine(int col,int row)
{
draw_mode(x0+col*(m_wh+1),y0+row*(m_wh+1),m_wh,2);
setcolor(BLACK);
circle(x0+m_wh/2+col*(m_wh+1),y0+m_wh/2+row*(m_wh+1),5);
setfillstyle(SOLID_FILL);
setfillcolor(BLACK);
floodfill(x0+m_wh/2+col*(m_wh+1),y0+m_wh/2+row*(m_wh+1),BLACK);
}
//画界面模式
void draw_mode(int x,int y,int wm_wh,int type)
{
if (type==1)
{
setcolor(WHITE);
rectangle(x,y,x+wm_wh,y+wm_wh);
setfillstyle(BS_SOLID); //固实填充 值为0 两者等价
setfillcolor(LIGHTGRAY); //填充颜色为浅灰色
floodfill((x+x+wm_wh)/2,(y+y+wm_wh)/2,WHITE); //最后一个参数必须与setcolor中参数一致
setlinecolor(WHITE);
line(x,y,x+wm_wh,y);
line(x,y,x,y+wm_wh);
setlinecolor(DARKGRAY);
line(x+wm_wh,y,x+wm_wh,y+wm_wh);
line(x,y+wm_wh,x+wm_wh,y+wm_wh);
setlinecolor(WHITE);
line(x+1,y+1,x+wm_wh-1,y+1);
line(x+1,y+1,x+1,y+wm_wh-1);
setlinecolor(DARKGRAY);
line(x+wm_wh-1,y+1,x+wm_wh-1,y+wm_wh-1);
line(x+1,y+wm_wh-1,x+wm_wh-1,y+wm_wh-1);
}
else
{
setcolor(WHITE);
rectangle(x,y,x+m_wh,y+m_wh);
setfillstyle(BS_SOLID);
setfillcolor(LIGHTGRAY);
floodfill((x+x+m_wh)/2,(y+y+m_wh)/2,WHITE);
setlinecolor(DARKGRAY);
line(x,y,x+m_wh,y);
line(x,y,x,y+m_wh);
setlinecolor(WHITE);
line(x+m_wh,y,x+m_wh,y+m_wh);
line(x,y+m_wh,x+m_wh,y+m_wh);
}
}
//画整个雷区界面
void draw_circul(int x,int y,int row,int col)
{
int i,j;
for (i=0;i<row;i++)
{
x=(m_maxx-m_col*(m_wh+1))/2;
for (j=0;j<col;j++)
{
draw_mode(x,y,m_wh,1);
x+=m_wh+1;
}
y+=m_wh+1;
}
}
//画外围框架界面
void draw_framework()
{
int x1,y1,x2,y2;
x1=x0-m_wh;
y1=y0-3m_wh;
x2=x0+(m_col
(m_wh+1))+m_wh;
y2=y0+(m_row*(m_wh+1))+m_wh;

draw_min_max_framework(x1,y1,x2,y2);
draw_happyface(1);
draw_clock_score();

}
//大框小框
void draw_min_max_framework(int x1,int y1,int x2,int y2)
{
setlinecolor(WHITE);
rectangle(x0,y0,x0+m_col*(m_wh+1),y0+m_row*(m_wh+1));
setlinecolor(WHITE);
rectangle(x1,y1,x2,y2);
setfillstyle(BS_SOLID);
setfillcolor(LIGHTGRAY);
floodfill(x1+2,y1+2,WHITE);
}
//笑脸
void draw_happyface(int type)
{
draw_mode(m_maxx/2-m_wh-5,y0-m_wh5/2-5,2m_wh+10,1);
setlinecolor(RED);
circle(m_maxx/2,y0-m_wh3/2,m_wh);
setfillstyle(BS_SOLID);
setfillcolor(YELLOW);
floodfill(m_maxx/2,y0-m_wh
3/2,RED);

setlinecolor(BLACK);
circle(m_maxx/2-m_wh/2,y0-2*m_wh+2,2);
setfillstyle(BS_SOLID);
setfillcolor(BLACK);
floodfill(m_maxx/2-m_wh/2,y0-2*m_wh+2,BLACK);
circle(m_maxx/2+m_wh/2,y0-2*m_wh+2,2);
floodfill(m_maxx/2+m_wh/2,y0-2*m_wh+2,BLACK);
setlinecolor(RED);  

if (type==1)
    arc(m_maxx/2-m_wh/2,y0-m_wh*2,m_maxx/2+m_wh/2,y0-m_wh,3.4,6);
else
{
    arc(m_maxx/2-m_wh/2,y0-m_wh*3/2+2,m_maxx/2+m_wh/2,y0-m_wh/2+2,0.3,2.85);
}

}
//时钟和计时器
void draw_clock_score()
{//画左边框
setlinecolor(WHITE);
rectangle(x0,y0-2m_wh,x0+3m_wh,y0-m_wh);
setlinecolor(DARKGRAY);
line(x0,y0-2m_wh,x0+3m_wh,y0-2m_wh);
line(x0,y0-2
m_wh,x0,y0-m_wh);
//画右边框
setlinecolor(WHITE);
rectangle(x0+(m_col-3)(m_wh+1),y0-2m_wh,x0+m_col*(m_wh+1),y0-m_wh);
setlinecolor(DARKGRAY);
line(x0+(m_col-3)(m_wh+1),y0-2m_wh,x0+(m_col-3)(m_wh+1),y0-m_wh);
line(x0+(m_col-3)
(m_wh+1),y0-2m_wh,x0+m_col(m_wh+1),y0-2*m_wh);
}
//初始化系统
int init_system()
{
int gdriver=DETECT,gmode;
initgraph(&gdriver,&gmode," ");

m_maxx=getmaxx();
m_maxy=getmaxy();
m_row=10;
m_col=15;
m_wh=20;

int  i,j;
p=(int **)malloc(sizeof(int *)*m_row);
if (!p)
  return 0;
for(i=0;i<m_row;i++)
{
    p[i]=(int *)malloc(sizeof(int)*m_col);
    if(!p[i])
      return 0;
}

for (i=0;i<m_row;i++)
    for (j=0;j<m_col;j++)
        p[i][j]=0;
return 1;

}

图1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值