汉诺塔的源程序

这是一个使用TURBO C 2.0编写的汉诺塔游戏程序,允许玩家选择3到7个盘子进行游戏。游戏具有三种结局,并在成功后提供继续游戏选项,每次继续会增加盘子数量。程序界面友好,算法简单,是DOS环境下首个汉诺塔游戏。
摘要由CSDN通过智能技术生成

    本程序是一个汉诺塔的游戏程序,用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;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值