本程序是一个汉诺塔的游戏程序,用TURBO C 2.0编写并编译成功,游戏可以让玩家选择盘子的个数(3到7个).并有三种游戏结果(YOU WIN;GAME OVER;YOU PLAY BAD),而且一局成功以后,玩家可以选择退出或继续(如果选择继续,则盘子的个数就会自动加一).
本游戏程序算法简单,界面友好,可玩性强,是第一款在DOS界面下的汉诺塔游戏程序.
作者E_MAIL: bolm@etang.com
/*---------------------------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;
}