本程序是一个汉诺塔的游戏程序,用TURBO C 2.0编写并编译成功,游戏可以让玩家选择盘子的个数(3到7个).并有三种游戏结果(YOU WIN;GAME OVER;YOU PLAY BAD),而且一局成功以后,玩家可以选择退出或继续(如果选择继续,则盘子的个数就会自动加一). 本游戏程序算法简单,界面友好,可玩性强,是第一款在DOS界面下的汉诺塔游戏程序.
作者E_MAIL: [email protected]
/*---------------------------HANOI TOWER V 1.0--------------------------*/ /*-----------------------------SOURCE PROGRAM---------------------------*/ #include "stdio.h" #include "conio.h" #include "stdlib.h" #include "graphics.h" #include "math.h"
#define O outtextxy #define S setcolor #define F setfillstyle #define R rectangle #define C circle #define L line #define B bar #define B3D bar3d
#define X 200 #define Y 30
int step=0; int record[5]={7,15,31,63,127},rec; int disk,disknum; char mark[15];
struct rod { int disk[8][5]; int diskname[8]; }tree[3];
/********************************************/ ntoa(int s) { int b[15]; int i,j; for (i=0;i<15;i++) mark[i]='\0'; for (i=0;s>=10;i++) {b[i]=s%10; s/=10;} b[i]=s; for(j=i;j>=0;j--) mark[i-j]=b[j]+'0'; }
void drawrod() { F(1,LIGHTBLUE); B(118,150,122,400); /*ROD1*/ B(318,150,322,400); /*ROD2*/ B(518,150,522,400); /*ROD3*/ F(6,BLUE); B(119,151,123,401); B(319,151,323,401); B(519,151,522,401); }
void draw() { S(LIGHTBLUE); R(10,10,629,469); L(10,30,629,30); /*UP LINE1*/ L(10,26,629,26); L(10,450,629,450); /*BOTTOM LINE1*/ L(10,446,629,446); S(GREEN); settextstyle(DEFAULT_FONT,HORIZ_DIR,2); O(200,452,"HANOI TOWER V1.0"); S(LIGHTBLUE); O(201,453,"HANOI TOWER V1.0"); }
void showrecord() { settextstyle(DEFAULT_FONT,HORIZ_DIR,1); F(1,BLACK); bar(58,11,80,22); ntoa(disk); S(RED); O(20,15,"DISK:"); S(GREEN); O(60,15,mark);
bar(318,11,350,22); ntoa(rec); S(RED); O(260,15,"RECORD:"); S(GREEN); O(320,15,mark);
bar(530,11,600,22); ntoa(step); S(RED); O(490,15,"STEP:"); S(GREEN); O(532,15,mark); }
void filldisk(int x1,int y1,int x2,int y2,int color,int color1) { S(color); F(1,color); B3D(x1,y1,x2,y2,5,5); F(6,color1); B3D(x1+1,y1+1,x2+1,y2+1,5,5); }
void action() /**ANIMATION**/ { int i; S(BLACK); for (i=0;i<600;i=i+2) {R(i,0,i+40,479); delay(100);} }
int ifwin() { int i,step_sub_rec; disknum=0; for (i=0;i<disk;i++) { if(tree[2].disk[i][0]==1) disknum++;} step_sub_rec=step-rec; if (disknum==disk) { if (step_sub_rec<=10) /**WIN**/ { action(); cleardevice(); S(GREEN); settextstyle(DEFAULT_FONT,HORIZ_DIR,3); O(230,200,"YOU WIN"); S(RED); O(231,201,"YOU WIN"); } else if (step_sub_rec<=20) { action(); cleardevice(); S(RED); settextstyle(DEFAULT_FONT,HORIZ_DIR,3); O(220,200,"GAME OVER"); S(LIGHTBLUE); O(221,201,"GAME OVER"); } else { action(); cleardevice(); S(LIGHTBLUE); settextstyle(DEFAULT_FONT,HORIZ_DIR,3); O(175,200,"YOU PLAY BAD"); S(CYAN); O(176,201,"YOU PLAY BAD"); }
for (i=0;i<3000;i=i+50) {sound(i); delay(300); nosound();} S(RED); settextstyle(DEFAULT_FONT,HORIZ_DIR,2); O(180,240,"THANK YOU TO PLAY"); S(GREEN); O(181,241,"THANK YOU TO PLAY"); S(RED); R(168,298,473,309); settextstyle(DEFAULT_FONT,HORIZ_DIR,1); O(170,300,"PRESS ANY KEY TO CONTINUE(ESC TO QUIT)"); S(YELLOW); O(171,301,"PRESS ANY KEY TO CONTINUE(ESC TO QUIT)");
if(getch()==27) {closegraph();exit(0);} else return(1); } return(0); }
void helpmessage() { S(BLUE); R(20,258,619,405); L(20,260,619,260); L(20,376,619,376); S(RED); O(124,230,">>>"); settextstyle(SANS_SERIF_FONT,HORIZ_DIR,1); O(23,265,"HELP MESSAGE:"); settextstyle(DEFAULT_FONT,HORIZ_DIR,1); S(LIGHTBLUE); O(30,290,"1). KEY: <-,->,A,D :MOVE THE RED BALL TO SELECT A ROD"); O(30,315,"2). KEY: UP,W :TO SELECT THE TOP DISK"); O(30,340,"3). KEY: DOWN,S :TO GET DOWN THE DISK WHICH SELECT"); O(30,365,"4). KEY: ESC :QUIT THE GAME"); S(RED); O(30,382,"5). IF STEP-RECORD<10 THAN :YOU WIN"); O(30,393,"6). ELSE :GAME OVER"); }
/************************---GAME---**************************/ void game() { int movedisk[4],updiskname1,updiskname2,updisknum1,updisknum2,havemove=0,i,j,rn=0; int stage,stage1,stage2,rn1,rn2; int x1,y1,x2,y2; int a=0,b=0; int name=1; char c; rec=record[disk-3]; draw(); drawrod(); showrecord();
for (i=0;i<3;i++) /*****---EXIST BIT=0---********/ for (j=0;j<7;j++) {tree[i].disk[j][0]=0; tree[i].diskname[j]=0;}
for (i=0;i<disk;i++) /****DRAW THE DISKS OF THE FIRST ROD***/ { tree[rn].diskname[i]=name; tree[rn].disk[i][0]=1; /*DISK i-----exist bit*/ tree[rn].disk[i][1]=40+a; /*--X1--*/ tree[rn].disk[i][2]=380-b; /*--y1--*/ tree[rn].disk[i][3]=200-a; /*--X2--*/ tree[rn].disk[i][4]=400-b; /*--y2--*/
name=name+1; a=a+10; b=b+30; }
for (i=0;i<disk;i++) /*********DRAW THE DISKS***********/ filldisk(tree[rn].disk[i][1],tree[rn].disk[i][2],tree[rn].disk[i][3],tree[rn].disk[i][4],9,1); for (i=0;i<4;i++) movedisk[i]=0; drawrod(); /*-----------------------------------------------------------------*/
F(1,BLACK); B(20,100,609,130); F(1,RED); S(RED); C(118+(rn*200),115,10); floodfill(118+(rn*200),115, RED);
while(1) {if(kbhit()) switch(c=getch()) {case 75: /**left**/ case 'A': case 'a': rn=((rn==0)?2:rn-1); break;
case 77: /**right**/ case 'D': case 'd': rn=((rn==2)?0:rn+1); break;
case 72: /**up**/ case 'W': case 'w': for (i=0;tree[rn].disk[i][0]!=0;i++); if (i<1) break; else { updiskname1=tree[rn].diskname[i-1]; updisknum1=i-1; stage1=i-1; rn1=rn; for (i=0;i<4;i++) movedisk[i]=tree[rn].disk[updisknum1][i+1]; havemove=0; /* tree[rn].diskname[updisknum1]=0; tree[rn].disk[updisknum1][0]=0; */ } break;
case 80: /**down**/ case 'S': case 's': if (movedisk[0]==0) break; for (i=0;tree[rn].disk[i][0]!=0;i++); if (i<1) { if (havemove==1) break; stage2=0;rn2=rn; tree[rn].diskname[0]=updiskname1; tree[rn].disk[0][0]=1; /**exist bit-->1**/ tree[rn1].diskname[updisknum1]=0; tree[rn1].disk[updisknum1][0]=0; stage=stage1-stage2; x1=movedisk[0]+(rn2-rn1)*X; y1=movedisk[1]+stage*Y; x2=movedisk[2]+(rn2-rn1)*X; y2=movedisk[3]+stage*Y;
tree[rn].disk[0][1]=x1; tree[rn].disk[0][2]=y1; tree[rn].disk[0][3]=x2; tree[rn].disk[0][4]=y2; } else { updiskname2=tree[rn].diskname[i-1]; updisknum2=i; stage2=i; rn2=rn; if (updiskname1>updiskname2) { if (havemove==1) break; tree[rn].diskname[updisknum2]=updiskname1; tree[rn].disk[updisknum2][0]=1; /**exist bit-->1**/ tree[rn1].diskname[updisknum1]=0; tree[rn1].disk[updisknum1][0]=0; stage=stage1-stage2; x1=movedisk[0]+(rn2-rn1)*X; y1=movedisk[1]+stage*Y; x2=movedisk[2]+(rn2-rn1)*X; y2=movedisk[3]+stage*Y;
tree[rn].disk[updisknum2][1]=x1; tree[rn].disk[updisknum2][2]=y1; tree[rn].disk[updisknum2][3]=x2; tree[rn].disk[updisknum2][4]=y2; } else {sound(1000); delay(300); nosound(); break; } } filldisk(movedisk[0],movedisk[1],movedisk[2],movedisk[3],7,9); delay(2000); filldisk(movedisk[0],movedisk[1],movedisk[2],movedisk[3],0,0); filldisk(x1,y1,x2,y2,9,1); step=step+1; showrecord(); drawrod();
for(i=0;i<4;i++) movedisk[i]=0; havemove=1; if (ifwin()==1) return; /****check if moves are finished****/ break;
case 27:closegraph(); exit(0); default:break; } F(1,BLACK); B(20,100,609,130); F(1,RED); S(RED); C(118+(rn*200),115,10); floodfill(118+(rn*200),115, RED);
} }
/********************MAIN*******************/ void main() { int gd=DETECT,gm=0; int input,i; initgraph(&gd,&gm,""); setbkcolor(BLACK); S(YELLOW); settextstyle(DEFAULT_FONT,HORIZ_DIR,4); O(150,204,"HANOI TOWER"); S(LIGHTBLUE); O(149,203,"HANOI TOWER"); S(YELLOW); settextstyle(DEFAULT_FONT,HORIZ_DIR,3); O(267,254,"V 1.0"); S(LIGHTBLUE); O(266,253,"V 1.0"); S(LIGHTBLUE); settextstyle(DEFAULT_FONT,HORIZ_DIR,1); O(243,300,"--MADE BY CHENCHENG--"); S(CYAN); O(242,299,"--MADE BY CHENCHENG--"); sleep(2); cleardevice(); helpmessage(); S(GREEN); settextstyle(DEFAULT_FONT,HORIZ_DIR,1); for (i=1;i<75;i++) {delay(500); /*SPEED OF THE SENTENCE*/ setviewport(0,0,50+i*8,479,1); O(155,230,"PLEASE INPUT THE NUMBERS OF DISKS(3..7):"); } while((input=getch())<'3'||input>'7'); input=input-48; disk=input; delay (1000); action(); cleardevice(); ag: game(); /********GAME*******/ cleardevice(); if (disk<7) disk++; step=0; goto ag; }

|