c语言汉诺塔动画程序,C语言实现的动画汉诺塔

/*本程序实现C上的汉诺塔动画移动效果,如有建议可和我联系,QQ:928853003*/

/*编写者:杰 */

/*完成时间:2012年9月25日9:02*/

/*有部分函数可参见easyx帮助,运行之前必须安装easyx*/

0818b9ca8b590ca3270a3433284dd417.png

/*指针的运用尤为重要,尤其是指针的指针容易迷惑人心*/

/*全局变量的定义应该优先与编写函数之前*/

/*常量的定义可以节省大量的编写时间,并可以使程序简洁友善*/

#include

#include

#include

#include

#include

#define Width(N) 220-20*(N)/*计算对应编号N的盘子的宽度*/

#define H 20/* 每个盘子的高度*/

#define LINE 180/*盘子移动的上基准线*/

#define MAX 9/*盘子的最大数目,由于配置优先,数目过大不能完全运行*/

#define DOWN 580/*盘子底部基准线*/

/*-------全局变量-------------------------*/

int a[3]={0,0,0};/*存储A,B,C柱子的当前盘子数目*/

int findNum(char c)

{

switch(c)

{

case 'A':return 0;break;

case 'B':return 1;break;

case 'C':return 2;break;

}

}

struct Rec/*盘子的定义*/

{

int number;

int width;

int left;

int top;

int right;

int bottom;

};

struct Rec r[MAX];/*声明所最大数目的盘子,当然也可以动态分配内存,从而节省资源,但是当前没有必要,有兴趣的的可以自己改写*/

struct Area/*柱子的定义*/

{

char name;/*柱子的名称*/

int x;/*画图区域底边中点的横坐标*/

int y;/*画图区域底边中点的纵坐标*/

struct Rec* recs[MAX];/*定义最大数目的盘子数目*/

void Reduce()/*去除最上位置的盘子*/

{

a[findNum(name)]--;

recs[a[findNum(name)]]=NULL;

}

void Add(int n,int l,int t)/*n为盘子的编号,l为坐标left,t为坐标top---实现盘子的添加*/

{

r[n-1].number=n;

r[n-1].width=Width(n);

r[n-1].left=l;

r[n-1].top=t;

r[n-1].right=r[n-1].left+r[n-1].width;

r[n-1].bottom=r[n-1].top+H;

a[findNum(name)]++;

recs[a[findNum(name)]-1]=&r[n-1];

}

};

struct Area A,B,C;/*声明三个柱子*/

void animation(int left,int top,int right,int bottom,int distance,char direction)/*实现盘子移动的动画*/

/*left、top、right、bottom是坐标,distance是移动距离(可以为负),direction为方向(X为横向,Y为纵向)*/

{

if(distance<=0)/*反方向运动*/

{

for(int i=0;i

{

switch(direction)

{

case 'X':

{

setfillstyle(BLACK);

bar(left-i,top,right-i,bottom);

setfillstyle(WHITE);

bar(left-i-1,top,right-i-1,bottom);

break;

}

case 'Y':

{

setfillstyle(BLACK);

bar(left,top-i,right,bottom-i);

setfillstyle(WHITE);

bar(left,top-i-1,right,bottom-i-1);

break;

}

}

Sleep(5);/*暂停时间,可以修改*/

}

}

else/*正方向移动*/

{

for(int i=0;i

{

switch(direction)

{

case 'X':

{

setfillstyle(BLACK);

bar(left+i,top,right+i,bottom);

setfillstyle(WHITE);

bar(left+i+1,top,right+i+1,bottom);

break;

}

case 'Y':

{

setfillstyle(BLACK);

bar(left,top+i,right,bottom+i);

setfillstyle(WHITE);

bar(left,top+i+1,right,bottom+i+1);

break;

}

}

Sleep(5);/*暂停时间,可以修改*/

}

}

}

void move(struct Area *c,struct Area *d)/*实现盘子从c柱子到d柱子的移动*/

{

int number=a[findNum((*c).name)];

int left=(*(*c).recs[number-1]).left;

int top=(*(*c).recs[number-1]).top;

int right=(*(*c).recs[number-1]).right;

int bottom=(*(*c).recs[number-1]).bottom;

int distance=LINE-top;

animation(left,top,right,bottom,distance,'Y');/*向上运动到LINE线*/

top=LINE;

bottom=LINE+H;

distance=(*d).x-(*c).x;

animation(left,top,right,bottom,distance,'X');/*横向移动到d柱子的正上方*/

left+=distance;

right+=distance;

if(a[findNum((*d).name)]==0)

{

distance=(*d).y-LINE-H;

}

else

{

distance=(*(*d).recs[a[findNum((*d).name)]-1]).top-LINE-H;

}

animation(left,top,right,bottom,distance,'Y');/*放下盘子在d柱子上*/

(*d).Add((*(*c).recs[number-1]).number,left,top+distance);/*完成动画之后,进行d柱子盘子的添加,以及c柱子牌子的去除*/

(*c).Reduce();

}

void hanoi(int n,struct Area *x,struct Area *y,struct Area *z) /*汉诺塔原型算法*/

{

if(n==1)

{

Sleep(2);

move(x,z);

}

else

{

hanoi(n-1,x,z,y);

Sleep(2);

move(x,z);

hanoi(n-1,y,x,z);

}

}

void main()

{

int number;

printf("输入数字(不能大于%d):",MAX);

while(scanf("%d",&number))

{

if(number0)

{

break;

}

printf("请再次输入符合要求的数据:");

}

initgraph(800, 640);

A.name='A';

A.x=140;

A.y=DOWN;

B.name='B';

B.x=400;

B.y=DOWN;

C.name='C';

C.x=660;

C.y=DOWN;

a[findNum(A.name)]=0;

a[findNum(B.name)]=0;

a[findNum(C.name)]=0;

for(int i=1;i<=number;i++)

{

int x=Width(i);

A.Add(i,A.x-x/2,A.y-i*H);

}

a[findNum(A.name)]=number;

/*以上完成全局变量的赋值*/

for(int j=0;j

{

Rec r=(*A.recs)[j];

setfillstyle(WHITE);

bar(r.left,r.top,r.right,r.bottom);

}

/*以上进行初状态画面的绘制*/

hanoi(number,&A,&B,&C);

getch();

closegraph();

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值