本程序通过tc2.0和tc3.0编译运行,请在主目录(tc.exe所在的目录)下添加文件out.xia,文件中加入如下内容。 999 999 999,xiajia xiajia xiajia 再进行编译运行。否则会有错误。
#include <graphics.h> #include <math.h> #include <stdio.h> #include <dos.h> union REGS regs; int size=15;/*用于表示每个方块的大小(正方形的边长)*/ int pix,piy=50;/*pix,piy是矩阵的偏移量*/ char b[2]="1";/*用于显示方格周围的雷的个数*/ int pan[30][16]={0};/*用于记录盘面的情况:0:没有、9:有雷、1~8:周围雷的个数*/ int pan1[30][16]={0};/*pan1[][]纪录当前的挖雷情况,0:没有操作、1:打开了、2:标记了*/ int tt;/*纪录时间参数*/ int Msinit(); void Draw(int x,int y,int sizex,int sizey); void Facedraw(int x,int y,int sizel,int k); void Dead(int sizel,int x,int y); void Setmouse(int xmax,int ymax,int x,int y); int Msread(int *xp,int *yp,int *bup,struct time t1,int k); void Draw1(int x,int y); int Open(int x,int y); float Random(); void Have(int sum,int x,int y,int xx,int yy); void Help(); void Coread();
/*下面是主函数*/ main() { int mode=VGAHI,devices=VGA;/*图形模式初始化的变量*/ char ams; /*鼠标操作中的标志变量*/ int xms,yms,bms; /*鼠标的状态变量*/ int i,j,k,k1=0; /*i,j,k是循环变量*/ int x=9,y=9; /*x,y矩阵的大小*/ int sum=10; /*sum 盘面的雷的总数目,是个x,y的函数*/ int x1=0,y1=0; /*用于记录光标当前的位置*/ int sizel=10; /*脸的大小*/ char string3[4]="Big",string1[6]="Small",string2[7]="Normal"; struct time t1={0,0,0,0}; int co[3]; char name[3][20]; FILE * p; Msinit(); /*鼠标初始化*/ registerbgidriver(EGAVGA_driver); initgraph(&devices,&mode,"\\tc\\BGI"); /*图形模式初始化*/ if((p = fopen("out.xia", "r")) == NULL) {printf("The file cannot open!\n"); exit(1);} fscanf(p,"%d %d %d,",&co[0],&co[1],&co[2]); for(i=0;i<3;i++) fscanf(p,"%s\n",name[i]); fclose(p); pix=250-x*size/2; bss: b[0]='1'; /*游戏开始和重来的切入点*/ k=0,tt=0; for(i=0;i<30;i++) /*盘面初始化*/ for(j=0;j<16;j++) {pan[i][j]=0; pan1[i][j]=0;} Setmouse(pix,piy,x,y);/*设置鼠标的活动范围*/ /*下面是程序的试验阶段的部分,技术成熟时要改变*/ for(;;) /*用于生成雷的盘面情况*/ {i=(int)(x*Random()); j=(int)(y*Random()); if(pan[i][j]==0) {pan[i][j]=9; k=k+1; } if(k==sum) break; } for(i=0;i<x;i++)/*用于统计各点的周边情况*/ for(j=0;j<y;j++) if(pan[i][j]==0)/*只有没有雷的才需要处理*/ {if(i-1>=0 && j-1>=0 && pan[i-1][j-1]==9) pan[i][j]++; if(j-1>=0 && pan[i][j-1]==9) pan[i][j]++; if(i+1<x && j-1>=0 && pan[i+1][j-1]==9) pan[i][j]++; if(i-1>=0 && pan[i-1][j]==9) pan[i][j]++; if(i+1<x && pan[i+1][j]==9) pan[i][j]++; if(i-1>=0 && j+1<y && pan[i-1][j+1]==9) pan[i][j]++; if(j+1<y && pan[i][j+1]==9) pan[i][j]++; if(i+1<x && j+1<y && pan[i+1][j+1]==9) pan[i][j]++; } /*下面是一个试验阶段用于检验上面计算的正确性的小节 for(i=0;i<x;i++) {for(j=0;j<y;j++) printf("%d,",pan[i][j]); printf("\n");} getch(); exit(1); 通过实验了!*/ cleardevice();/*清屏*/ Draw(40,1,470,320);/*画底座*/ setcolor(1);/*显示提示信息*/ outtextxy(100,300," : Help."); setcolor(4); outtextxy(100,300,"H"); setcolor(1); outtextxy(200,300," / : exit."); setcolor(4); outtextxy(200,300,"Q"); outtextxy(220,300,"ESC"); setcolor(1); outtextxy(330,300," : cores."); setcolor(4); outtextxy(330,300,"R"); Facedraw(250,20,sizel,2);/*显示控制按钮*/ Draw(300,10,60,20); setcolor(0); outtextxy(309,15,string1); Draw(360,10,60,20); setcolor(0); outtextxy(369,15,string2); Draw(420,10,60,20); setcolor(0); outtextxy(434,15,string3); for(i=0;i<x;i++)/*这一段用于描绘盘面*/ for(j=0;j<y;j++) {Draw(i*size+pix,j*size+piy,size,size);} Have(sum,70,20,x,y);/*各项的初始显示*/ k=0; setfillstyle(1, 0); bar(105,15,135,30); setcolor(4); outtextxy(110,20,"000"); /*下面这一段用于接收用户的控制,并做出反应*/ for(;;) { css:ams=Msread(&xms,&yms,&bms,t1,k);/*读取鼠标状态*/ /*鼠标状态发生变化时描绘原有情况*/ /*如果鼠标不在盘面上,就如下操作*/ if(y1<0) {if(x1<x/4) Facedraw(250,20,sizel,2); if(x1>=x/4 && x1<x/2) {Draw(300,10,60,20); setcolor(0); outtextxy(309,15,string1);} if(x1>=x/2 && x1<x*3/4) {Draw(360,10,60,20); setcolor(0); outtextxy(369,15,string2);} if(x1>=x*3/4) {Draw(420,10,60,20); setcolor(0); outtextxy(434,15,string3);} } /*如果鼠标在盘面上*/ else{ if(ams==-1 && pan1[x1][y1]==0) Draw(x1*size+pix,y1*size+piy,size,size); if(ams==-1 && pan1[x1][y1]==1) Draw1(x1,y1); if(ams==-1 && pan1[x1][y1]==2) {Draw(x1*size+pix,y1*size+piy,size,size); setcolor(10); circle(x1*size+pix+7,y1*size+piy+7,4);} } x1=(int)((xms-pix)/size);/*计算鼠标目前的位置*/ y1=(int)((yms-piy)/size); if(y1<0){setcolor(4); if(x1<x/4) {rectangle(250-sizel-3,20-sizel-3,254+sizel,24+sizel); if(bms!=0) goto bss;} if(x1>=x/4 && x1<x/2) {rectangle(300,10,359,30); if(bms!=0) {x=9;y=9;sum=10;pix=250-x*size/2;goto bss;}} if(x1>=x/2 && x1<x*3/4) {rectangle(360,10,419,30); if(bms!=0) {x=16;y=16;sum=40;pix=250-x*size/2;goto bss;}} if(x1>=x*3/4) {rectangle(420,10,479,30); if(bms!=0) {x=30;y=16;sum=99;pix=250-x*size/2+25;goto bss;}} goto css;} if(ams==-1 && bms==1 && pan1[x1][y1]==0)/*单击鼠标左键*/ {if(k==0) {gettime(&t1); k=1;} if(pan[x1][y1]!=9) {Draw1(x1,y1);Open(x,y);} else {Dead(sizel,x,y); goto bss;} } if(ams==-1 && bms==2 && pan1[x1][y1]==0) {setcolor(10); circle(x1*size+pix+7,y1*size+piy+7,4); pan1[x1][y1]=2; Have(sum,70,20,x,y);} else if(ams==-1 && bms==2 && pan1[x1][y1]==2) {Draw(x1*size+pix,y1*size+piy,size,size); pan1[x1][y1]=0; Have(sum,70,20,x,y);}/*相当于鼠标右击*/ if(ams==-1 && bms==3 && pan1[x1][y1]==1) {/*相当于鼠标双击,有效性判断*/ i=0; if(x1-1>=0 && y1-1>=0 && pan1[x1-1][y1-1]==2) i++; if(y1-1>=0 && pan1[x1][y1-1]==2) i++; if(x1+1<x && y1-1>=0 && pan1[x1+1][y1-1]==2) i++; if(x1-1>=0 && pan1[x1-1][y1]==2) i++; if(x1+1<x && pan1[x1+1][y1]==2) i++; if(x1-1>=0 && y1+1<y && pan1[x1-1][y1+1]==2) i++; if(y1+1<y && pan1[x1][y1+1]==2) i++; if(x1+1<x && y1+1<y && pan1[x1+1][y1+1]==2) i++; if(i==pan[x1][y1]) /*有效*/ { if(x1-1>=0 && y1-1>=0 && pan1[x1-1][y1-1]!=2) {if(pan[x1-1][y1-1]!=9) Draw1(x1-1,y1-1);else {Dead(sizel,x,y); goto bss;}} if(y1-1>=0 && pan1[x1][y1-1]!=2) {if(pan[x1][y1-1]!=9) Draw1(x1,y1-1);else {Dead(sizel,x,y);goto bss;}} if(x1+1<x && y1-1>=0 && pan1[x1+1][y1-1]!=2) {if(pan[x1+1][y1-1]!=9) Draw1(x1+1,y1-1);else {Dead(sizel,x,y);goto bss;}} if(x1-1>=0 && pan1[x1-1][y1]!=2) {if(pan[x1-1][y1]!=9) Draw1(x1-1,y1);else {Dead(sizel,x,y);goto bss;}} if(x1+1<x && pan1[x1+1][y1]!=2) {if(pan[x1+1][y1]!=9) Draw1(x1+1,y1);else {Dead(sizel,x,y);goto bss;}} if(x1-1>=0 && y1+1<y && pan1[x1-1][y1+1]!=2) {if(pan[x1-1][y1+1]!=9) Draw1(x1-1,y1+1);else {Dead(sizel,x,y);goto bss;}} if(y1+1<y && pan1[x1][y1+1]!=2) {if(pan[x1][y1+1]!=9) Draw1(x1,y1+1);else {Dead(sizel,x,y);goto bss;}} if(x1+1<x && y1+1<y &&pan1[x1+1][y1+1]!=2) {if(pan[x1+1][y1+1]!=9) Draw1(x1+1,y1+1);else {Dead(sizel,x,y);goto bss;}} Open(x,y); } } if(ams=='q'||ams=='Q'|| ams==27 ) {fclose(p);exit(1);} /*退出*/ if(ams=='c'||ams=='C') goto bss; /*重来*/ if(ams=='h'||ams=='H') {Help();goto bss;}/*帮助文档*/ if(ams=='r'||ams=='R') {Coread();goto bss;}/*察看成绩*/ /*胜利条件*/ k1=0; for(i=0;i<x;i++) for(j=0;j<y;j++) if(pan1[i][j]!=1) k1++; if(k1==sum) { for(i=0;i<x;i++) for(j=0;j<y;j++) if(pan1[i][j]==0) {setcolor(10);circle(i*size+pix+7,j*size+piy+7,4);} Facedraw(250,20,sizel,3); if(x==9 && tt<co[0]) {j=0;co[0]=tt;i=0;} if(x==16 && tt<co[1]) {j=1;co[1]=tt;i=0;} if(x==30 && tt<co[2]) {j=2;co[2]=tt;i=0;} if(i==0) {Draw(10,10,300,55); setcolor(4); outtextxy(20,20,"Please input your name(0 - 19):"); for(i=0;i<19;i++) {name[j][i]=getch(); if(name[j][i]==8) i=i-2; if(name[j][i]==13) {name[j][i]='\0';break;} name[j][i+1]='\0'; setfillstyle(1, 7); bar(20,35,200,50); setcolor(4); outtextxy(20,40,name[j]); } if((p = fopen("out.xia", "w")) == NULL) {printf("The file cannot open!\n"); exit(1);} fprintf(p,"%d %d %d,",co[0],co[1],co[2]); for(i=0;i<3;i++) fprintf(p,"%s\n",name[i]); fclose(p); Coread();} getch(); goto bss;} setcolor(4); rectangle(x1*size+pix,y1*size+piy,x1*size+size+pix-1,y1*size+size+piy-1); } } /*++++++++主函数结束++++++++*/
/*这个函数用于实现鼠标的初始化*/ int Msinit() {int recored; regs.x.ax=0; int86 (0x33, ®s, ®s); recored=regs.x.ax; if(recored==0) {printf("Mouse not found or Mouse driver not installed.\n"); return 0;} else return recored; } /*下面这个子程序是完成描绘一个按钮*/ void Draw(int x,int y,int sizex,int sizey)/* x, y为左上角坐标sizex,sizey为长和宽*/ {int sizx=sizex-1; int sizy=sizey-1; setcolor(15);/*这里最好用白色*/ line(x,y,x+sizx-1,y); line(x,y+1,x+sizx-2,y+1); line(x,y,x,y+sizy-1); line(x+1,y,x+1,y+sizy-2); setcolor(8);/*这里最好用深灰色*/ line(x+1,y+sizy,x+sizx,y+sizy); line(x+2,y+sizy-1,x+sizx,y+sizy-1); line(x+sizx-1,y+1,x+sizx-1,y+sizy); line(x+sizx,y+2,x+sizx,y+sizy); setcolor(7);/*这里最好用灰色*/ putpixel(x,y+sizy,3); putpixel(x+1,y+sizy-1,3); putpixel(x+sizx,y,3); putpixel(x+sizx-1,y+1,3); setfillstyle(1, 7);/*这里最好用灰色,设置填充模式*/ bar(x+2,y+2,x+sizx-2,y+sizy-2); } /*下面是一些画图程序*/ void Facedraw(int x,int y,int sizel,int k) /*形参x,y笑脸的中心坐标,sizel脸的大小(半径), k为要描述的脸型,1:哭、2:平常、3:笑*/ {Draw(x-sizel-3,y-sizel-3,2*(sizel+4),2*(sizel+4));/*画一个按钮*/ setcolor(14); setfillstyle(1, 14); pieslice(x, y, 0, 360, sizel);/*画一个黄色的圆面*/ setfillstyle(1, 0); setcolor(0); if(k==1)/*失败*/ {line(x-sizel*7/20,y-sizel*7/20,x-sizel*3/20,y-sizel*3/20);/*画两个差表示眼睛*/ line(x-sizel*7/20,y-sizel*3/20,x-sizel*3/20,y-sizel*7/20); line(x+sizel*3/20,y-sizel*7/20,x+sizel*7/20,y-sizel*3/20); line(x+sizel*3/20,y-sizel*3/20,x+sizel*7/20,y-sizel*7/20); arc(x,y+sizel,20,160, sizel/2);} if(k==2)/*平常*/ {bar(x-sizel*7/20,y-sizel*7/20,x-sizel*3/20,y-sizel*3/20); bar(x+sizel*3/20,y-sizel*7/20,x+sizel*7/20,y-sizel*3/20); arc(x,y,200,340, sizel*3/4); } if(k==3)/*成功*/ {bar(x-sizel/2,y-sizel/2,x-sizel*3/20,y-sizel*3/20); bar(x+sizel*3/20,y-sizel/2,x+sizel/2,y-sizel*3/20); line(x-sizel*3/20,y-sizel/2,x+sizel*3/20,y-sizel/2); line(x-sizel/2,y-sizel*5/20,x-sizel,y); line(x+sizel/2,y-sizel*5/20,x+sizel,y); arc(x,y,200,340, sizel*3/4); /*嘴巴*/ } } /*死亡后的处理程序*/ void Dead(int sizel,int x,int y) /*x,y要判断的点的坐标,sizel为脸的大小*/ {int i,j;/*循环变量*/ setcolor(4); for(i=0;i<x;i++) for(j=0;j<y;j++) if(pan[i][j]==9) {circle(i*size+pix+7,j*size+piy+7,4);}/*用红色的圆圈标记有雷的方块*/ Facedraw(250,20,sizel,1); getch(); } /*下面的函数用于实现设置鼠标的移动范围*/ void Setmouse(int xmax,int ymax,int x,int y) /*xmax,ymax为左上角的坐标x,y矩阵的大小*/ {int left,right,top,buttom;/*这四个变量用于确定移动的左上角和右下角*/ left=xmax; right=xmax+size*(x-1); top=ymax-size; buttom=ymax+size*(y-1); regs.x.ax=7; regs.x.cx=left; regs.x.dx=right; int86(0x33,®s,®s); regs.x.ax=8; regs.x.cx=top; regs.x.dx=buttom; int86(0x33,®s,®s); } /*下面这个函数用于实现鼠标的读取*/ int Msread(int *xp,int *yp,int *bup,struct time t1,int k) /*xp,yp,bup分别为鼠标的位置和按键情况,t1,k是时间现实参数,t1为开始时间,k为开始标记*/ {int x0=*xp,y0=*yp,bu0=*bup; int xnew,ynew,ch; int tt1=0;/*用于记录时间差*/ struct time t2; char ttt[4]="000"; do{if(kbhit()) return getch(); regs.x.ax=3; int86(0x33,®s,®s); xnew=regs.x.cx; ynew=regs.x.dx; *bup=regs.x.bx; if(k==1)/*如果已经开始就计算时间差*/ {gettime(&t2); tt1=(t2.ti_hour- t1.ti_hour)*3600 + (t2.ti_min- t1.ti_min)*60 + t2.ti_sec - t1.ti_sec;/*有待改进*/ if(tt1<=999 && tt!=tt1)/*当时间差有改变时,才显示*/ {tt=tt1; ttt[0]=(tt-tt%100)/100+48; ttt[1]=(tt%100-tt%10)/10 +48; ttt[2]=tt%10+48; setfillstyle(1, 0); bar(105,15,135,30); setcolor(4); outtextxy(110,20,ttt); } } } while(xnew==x0&&ynew==y0&&*bup==bu0); *xp=xnew; *yp=ynew; return -1;/*键盘无输入时返回-1,其次返回键盘值*/ } void Draw1(int x,int y)/*这个函数用于在x,y的位置描绘开后的情况*/ {setfillstyle(1, 7); bar(x*size+pix,y*size+piy,x*size+size+pix-1,y*size+size+piy-1); if(pan[x][y]!=0)/*没有雷的话不做显示*/ {b[0]=pan[x][y]+48; if(pan[x][y]!=7)/*防止字的颜色和背景颜色相同*/ setcolor(pan[x][y]); else setcolor(9); outtextxy (x*size+pix+3,y*size+piy+3,b); } pan1[x][y]=1;/*在pan1[][]中标记这一点的挖雷情况*/ } /*自开函数*/ int Open(int x,int y)/*函数中引入pan2[][]的目的是为了增加自开的效率,但是还是有不足之处*/ {int i,j,k; int pan2[30][16]={0};/*pan2[][],临时纪录盘面的自开情况,0没有自开过,1:已经自开过(30 这里有危险的技术性问题!!!)*/ for(;;) {k=0;/*是一个标记变量*/ for(i=0;i<x;i++) for(j=0;j<y;j++) {if (pan[i][j]==0 && pan1[i][j]==1 && pan2[i][j]==0)/*如果满足下面条件,没有雷,已经打开,没有自开过就继续*/ {pan2[i][j]=1;/*标记自开过*/ k=k+1; /*开周围的点*/ if(i-1>=0 && j-1>=0 && pan1[i-1][j-1]==0) Draw1(i-1,j-1); /*左上方*/ if(j-1>=0 && pan1[i][j-1]==0) Draw1(i,j-1); /*上方*/ if(i+1<x && j-1>=0 && pan1[i+1][j-1]==0) Draw1(i+1,j-1); /*右上方*/ if(i-1>=0 && pan1[i-1][j]==0) Draw1(i-1,j); /*左方*/ if(i+1<x && pan1[i+1][j]==0) Draw1(i+1,j); /*右方*/ if(i-1>=0 && j+1<y && pan1[i-1][j+1]==0) Draw1(i-1,j+1); /*左下方*/ if(j+1<y && pan1[i][j+1]==0) Draw1(i,j+1); /*下方*/ if(i+1<x && j+1<y && pan1[i+1][j+1]==0) Draw1(i+1,j+1); /*右下方*/ } } if(k==0) return 0;/*没有新的自开点时退出*/ } } float Random()/*随即数生成函数,加入了时间变量目的在于加强它的随机性*/ {float aa; int i,j; struct time t; gettime(&t); i=t.ti_min+t.ti_hour+t.ti_sec+t.ti_hund; for(j=0;j<i;j++) rand(); aa=rand()/32767.0; return aa;/*返回产生的随机数(0-1)*/ } /*下面是一个显示剩余雷数目的函数*/ void Have(int sum,int x,int y,int xx,int yy)/*游戏中雷的总数目不能多余99颗,sum 为雷的总数目,x,y为显示的地点*/ {int i,j,k=0; char a[3]="1"; for(i=0;i<xx;i++) for(j=0;j<yy;j++) {if (pan1[i][j]==2) k++;}/*统计一共标记了多少*/ k=sum-k;/*剩下了多少*/ if(k<0) k=0; a[0]=(k-(k%10))/10+48;/*字符转换*/ a[1]=k%10+48; setfillstyle(1, 0); bar(x-5,y-5,x+20,y+10);/*在原点涂黑*/ setcolor(4); outtextxy(x,y,a);/*显示数目*/ } /*下面是帮助函数*/ void Help() {Draw(40,1,560,160); setcolor(1); outtextxy(300,10,"Help"); setcolor(4); outtextxy(50,30,"Welcome to play this game. The mouse is supplied."); outtextxy(50,40,"Please press left button of the mouse where there is no boom."); outtextxy(50,50,"If you think there is a boom please press right button."); outtextxy(50,60,"You can choose the size of the game with press the right buttons."); outtextxy(50,70,"'Big' means 99 booms,'Normal' means 40 booms,'Small' means 10 booms."); outtextxy(50,80,"You can press the laugh-face-button or press C to play again."); outtextxy(50,90,"When you fail or success you can press any key to play again. "); outtextxy(50,100,"Whenever you want to quit this game please press Q. "); outtextxy(50,110,"If you find out all booms then you are winning. "); outtextxy(50,120,"This game is express by XiaJia. "); outtextxy(50,130,"Anybody do not have copyright,except get the right from XiaJia."); setcolor(9); outtextxy(50,140,"Press any key to play again."); getch(); } void Coread()/*这个函数用于读取纪录并显示*/ { int co[3],i; char name[3][20]; char cco[3][4]; FILE * p; for(i=0;i<3;i++) cco[i][3]='\0';
if((p = fopen("out.xia", "rb")) == NULL) {printf("The file cannot open!\n"); exit(1);} fscanf(p,"%d %d %d,",&co[0],&co[1],&co[2]); for(i=0;i<3;i++) fscanf(p,"%s\n",name[i]); fclose(p); Draw(10,20,400,90); setcolor(11); outtextxy(100,30,"HighCore"); setcolor(2); outtextxy(20,50,"Small"); outtextxy(20,60,"Normal"); outtextxy(20,70,"Big"); setcolor(3); for(i=0;i<3;i++) {cco[i][0]=(co[i]-co[i]%100)/100+48; cco[i][1]=(co[i]%100-co[i]%10)/10 +48; cco[i][2]=co[i]%10+48;} outtextxy(70,50,cco[0]); outtextxy(70,60,cco[1]); outtextxy(70,70,cco[2]); setcolor(5); outtextxy(100,50,name[0]); outtextxy(100,60,name[1]); outtextxy(100,70,name[2]); setcolor(1); outtextxy(30,85,"Press any key to play again!"); getch(); }
(编辑:andy)
|