《汉诺塔c源程序实现及讲解.ppt》由会员分享,可在线阅读,更多相关《汉诺塔c源程序实现及讲解.ppt(21页珍藏版)》请在金锄头文库上搜索。
1、汉诺塔C源程序实现及讲解 制作人:贾维华、刘璐 汉诺塔一、汉诺塔游戏简介及其玩法二、设计思路及其程序设计流程三、源程序及其讲解四、游戏程序中应注意的问题一、汉诺塔游戏简介及其玩法1 游戏方法:点击PLAY开始,会看到3个柱子和从大到小编着号码的盘子,而且盘子自上而下半径依次增大。成功把盘子顺序不变的堆到最右边的竹子旁为胜利。2 游戏规则:一次只能移动一个木块,盘子可以累起来,但是必须把半径小的放在半径大的上面。3操作指南:在挂有圆盘的柱子上方点击向上按钮 W 或者 UPDOWN按键选中圆盘,按左右移动键移动到相对应的柱子上方,按向下键放下圆盘,至此完成一次圆盘移动。二、设计思路及程序设计流程1
2、 设计思路:本设计中将盘子的数目设定为39个。设三个柱子A、B、C 移动的过程可分解为三个步骤: 第一步 把A上的n-1个圆盘移到B上; 第二步 把A上的一个圆盘移到C上; 第三步 把B上的n-1个圆盘移到C上; 其中第一步和第三步是类同的。 其实际思想是利用一个递归原理。例如最简单的三阶汉诺塔移动方法:AC,AB,CB,AC,BA,BC,AC 2 程序设计流程图:三、源程序及其讲解1 源程序:见win tc 2 主程序构架main() INITIAL(); /*界面初始化*/ Start_Logo(); /*游戏启动始界面*/ getch(); again: nStep=0;/*判断条件*/
3、 Logo();/*进入游戏*/ goto again;3. 主要程序分析#include stdio.h#include conio.h#include stdlib.h#include dos.h#include time.h#include graphics.h#define S setcolor#define F setfillstyle#define R rectangle#define C circle#define B bar#define B3D bar3d#define L line#define O outtextxy#define X 200 #define Y 20in
4、t nStep=0;int nRecord7=7,15,31,63,127,255,511,nRec;int nDisk,nDisknum;int nBaseNum;float nDelay;char chMark15;struct rod int nDisk105; int nDiskName10; tree3;/*/ntoa(int s) int b15; int i,j; for (i=0;i=10;i+) bi=s%10; s/=10; bi=s; for(j=i;j=0;j-) chMarki-j=bj+0;void INITIAL() /*GAME INITIAL*/ int gd
5、=DETECT,gm=0; initgraph(&gd,&gm,); setbkcolor(0);void Start_Logo()/*启动标志*/ F(3,8); B(200,150,439,259); S(7); R(201,151,442,262); S(WHITE); R(199,149,440,260); settextstyle(DEFAULT_FONT,HORIZ_DIR,2); O(233,180,HANOI TOWER); S(1); O(232,179,HANOI TOWER); S(WHITE); settextstyle(DEFAULT_FONT,HORIZ_DIR,2
6、); O(284,204,V 2.0); S(1); O(283,203,V 2.0); settextstyle(DEFAULT_FONT,HORIZ_DIR,1); S(WHITE); O(205,240,WERTE BY LiuLu AND JiaWeiHua!); O(204,239,WERTE BY LiuLu AND JiaWeiHua!);void FLASH_REC() int NUM,x1=8,x2=10; randomize(); for(NUM=0;NUM33;NUM+) F(1,rand()%16); B(x1,412,x2,414); x1=x1+20; x2=x2+
7、20; void DrawRod() F(1,3); B(120,152,124,402); /*ROD1*/ B(320,152,324,402); /*ROD2*/ B(520,152,523,402); /*ROD3*/ F(6,LIGHTBLUE); B(119,151,123,401); B(319,151,323,401); B(519,151,522,401);void DRAW() F(1,8); B(6,80,633,100); /*BROWN BAR*/ B(6,415,633,479); F(1,7); /*GAME BACKGROUND*/ B(7,102,632,41
8、0); S(15); R(6,0,633,479); S(15); settextstyle(DEFAULT_FONT,HORIZ_DIR,4); O(70,30,HANOI TOWER V2.0); S(9); O(71,31,HANOI TOWER V2.0); S(7); /*SHOW MESSAGE*/ settextstyle(DEFAULT_FONT,HORIZ_DIR,1); O(189,445,-MADE BY LiuLu AND JiaWeiHua-); L(165,419,165,425); S(12); O(170,419,MESSAGE:); /*MESSAGE BOX
9、*/ S(7); O(20,419,PRESS ESC TO QUIT);void ShowInfo(int nRn,int nWhetherGetDisk) F(1,8); B(230,418,620,428); settextstyle(DEFAULT_FONT,HORIZ_DIR,1); S(CYAN); if(nRn=0&nWhetherGetDisk=0) O(235,419,YOU NOW AT THE FIRST ROD); else if(nRn=1&nWhetherGetDisk=0) O(235,419,YOU NOW AT THE SECOND ROD); else if
10、(nRn=2&nWhetherGetDisk=0) O(235,419,YOU NOW AT THE THIRD ROD); else if(nWhetherGetDisk=1) S(YELLOW); switch(nRn) case 0 :O(235,419,YOU GET THE TOP DISK AT THE FIRST ROD);break; case 1 :O(235,419,YOU GET THE TOP DISK AT THE SECOND ROD);break; case 2 :O(235,419,YOU GET THE TOP DISK AT THE THIRD ROD);b
11、reak; default:break; else if(nRn=3&nWhetherGetDisk=nBaseNum) S(WHITE);O(235,419,YOU SHOULD DO YOUR BEST); else if(nRn=3&nWhetherGetDisk=nBaseNum*2) O(235,419,YOU SEEMS PLAY NOT VERY GOOD._); else if(nRn=4&nWhetherGetDisk=0) S(13);O(235,419,O.K YOU HAVE FINISHED YOURWORK);sleep(1); else O(235,419,YOU
12、 HAVE GET DOWN THE DISK);void ShowRecord() settextstyle(DEFAULT_FONT,HORIZ_DIR,1); F(1,8); B(78,82,90,94); ntoa(nDisk); S(YELLOW); O(40,86,DISK:); S(15); O(80,86,chMark); B(348,82,360,94); ntoa(nRec); S(YELLOW); O(290,86,RECORD:); S(15); O(350,86,chMark); B(560,82,610,94); ntoa(nStep); S(YELLOW); O(
13、520,86,STEP:); S(15); O(562,86,chMark);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(1,color1); B3D(x1+1,y1+1,x2+1,y2+1,5,5);/*=END OF FUN FADEOUT=*/void ClrScreen(void) int NUM; F(11,9); for (NUM=84;NUM476;NUM+) B(7,NUM,632,NUM+2); del
14、ay(20); int Ball(int nRn) F(1,7); B(20,105,609,130); F(1,RED); S(RED); C(118+(nRn*200),115,10); floodfill(118+(nRn*200),115, RED);void Quit() ClrScreen(); settextstyle(DEFAULT_FONT,HORIZ_DIR,2); S(WHITE); O(180,210,THANK YOU TO PLAY); O(180,230, 2010.6 ); S(RED); O(181,211,THANK YOU TO PLAY); O(181,
15、231, 2010.6 ); O(181,260, ANY KEY TO QUIT ); S(GREEN); O(180,180,G A M E O V E R); S(15); O(181,181,G A M E O V E R); getch(); closegraph(); exit(0) ; int IsWin() int i,nStep_Sub_Rec; int nDiskNum=0; for (i=0;inDisk;i+) if(tree2.nDiski0=1) nDiskNum+; nStep_Sub_Rec=nStep-nRec; if (nDiskNum=nDisk) Sho
16、wInfo(4,0); /*IT CAN BE SET AS YOUR WAY*/ nBaseNum=nRec/9; if (nStep_Sub_Rec=nBaseNum)/*WIN*/ ClrScreen(); S(GREEN); settextstyle(DEFAULT_FONT,HORIZ_DIR,3); O(230,200,YOU WIN); S(RED); O(231,201,YOU WIN); else if (nStep_Sub_Rec=nBaseNum*2) ClrScreen(); S(RED);settextstyle(DEFAULT_FONT,HORIZ_DIR,3);
17、O(220,200,JUST SOSO); S(LIGHTBLUE); O(221,201,JUST SOSO); else ClrScreen(); S(LIGHTBLUE); settextstyle(DEFAULT_FONT,HORIZ_DIR,3); O(175,200,YOU PLAY BAD); S(CYAN); O(176,201,YOU PLAY BAD); sound(1000); delay(1000); sound(1500); delay(300); sound(400); delay(2020); nosound(); S(BLUE); settextstyle(DE
18、FAULT_FONT,HORIZ_DIR,1); O(170,230,PRESS ANY KEY TO CONTINUE(ESC TO QUIT); S(WHITE); O(171,231,PRESS ANY KEY TO CONTINUE(ESC TO QUIT); if(getch()=27) Quit(); else ClrScreen();return(1); else ShowInfo(3,nStep_Sub_Rec); return(0);void HelpMessage() S(3); L(7,314,632,314); L(7,432,632,432); S(12); sett
19、extstyle(DEFAULT_FONT,HORIZ_DIR,1); O(23,320,HELP MESSAGE:); S(7); O(50,340,1).KEY: ,A,D :MOVE THE RED BALL TO SELECT A ROD); O(50,365,2).KEY: UP,W :TO SELECT THE TOP DISK); O(50,390,3).KEY: DOWN,S :TO GET DOWN THE DISK WHICH SELECT); O(50,415,4).KEY: ESC :QUIT THE GAME); S(12); O(50,442,5).IF STEP-
20、RECORD=A BASENUM THAN :YOU WIN); O(50,453,6).IF STEP-RECORD=A BASENUM*2 THAN :JUST SOSO); O(50,464,7).ELSE :YOU BAD BAD_);void Game() /*见turboc*/void Select() int nInput,i; DRAW(); settextstyle(DEFAULT_FONT,HORIZ_DIR,1); S(15);O(155,230,PLEASE INPUT THE NUMBER OF DISKS(3.9):); while(nInput=getch()9)
21、; nInput=nInput-48; nDisk=nInput; delay (1000);void Mode_1() /*PLAYER PLAY*/again: DRAW(); Game(); /*GAME*/ cleardevice(); if(nDisk9) nDisk+; nStep=0; goto again;void GameMode(int mode) if(mode=1) ClrScreen();Select();Mode_1(); void Logo() int nPlay_Mode=1; DRAW(); ClrScreen(); HelpMessage(); /*HELP
22、 MESSAGE*/ F(1,15); B(150,200,529,300); F(1,8); B(151,201,530,300); F(1,12); /*DRAW BUTTON*/ B(300,275,380,290); S(12); O(265,235,PRESS TO ENTER); O(264,234,PRESS TO ENTER); S(15); settextstyle(DEFAULT_FONT,HORIZ_DIR,1); O(324,279,PLAY); O(325,280,PLAY); while(1) if(kbhit()/*检查当前按下的键检查当前按下的键 */ switch(getch() case 13:GameMode(nPlay_Mode);return;break; case 27:Quit(); default:sound(100);delay(10);nosound();break; main() INITIAL(); Start_Logo(); getch();again: nStep=0; Logo(); goto again;/*END*/四、程序注意事项1:注意汉诺塔实现的原理2:程序设计中函数的嵌套调用3:程序中某些特殊函数的作用4:游戏界面设计中各个函数的参数5:各函数实现的功能6:整个游戏程序设计的主线