汉诺塔在VC控制台的图形演示

/** 汉诺塔实验:

1、三个塔 A B C

2、把从A 塔借助 B塔转移到C塔

3、盘子的宽比长为3:7

4、开发环境VC+EasyX插件http://www.easyx.cn 注意事项 目前程序只允许盘子的个数是3或者4,如需输入更多的盘子,请先调整宏定义TW的值(变大)在增加盘子的个数

*/

#include<iostream>
#include<graphics.h>
#include <stdio.h>
#include <conio.h>//kbhit()函数的头文件

using namespace std;
//宏定义
#define WIDTH 1000 //图形界面的宽度
#define HEIGHT 600  //图形界面的长度
#define TOP 150 //塔顶
#define BOTTOM 500 //塔基位置
#define ALOCATION 200 //A塔的位置
#define BLOCATION 500 //B塔的位置
#define CLOCATION 800 //C塔的位置
#define TW 100 //塔基的宽的一半,同时也是最大盘子的一半Tower Width
#define MAXD (TW*2) //最大盘子的直径
#define DEC 20 //盘子直接半径的渐变
#define LINE 5//线的宽度
//--------------------------定义数据------------------------------
typedef struct  //定义塔的数据结构
{
 int icou; //当前塔的盘子数
 char ch;
 int tower[10]; //当前所有盘子的大小,从第二个元素开始存,第一个存塔基的位置
}T;
//-------------------------函数声明--------------------------------
void init(int in);//初始化图形界面
void showDishes(T *t);//画出盘子
void drawTower();//画出塔
void drawDish(int ix,int iy,int height,int width );//画出一个盘子
void mov(T *f,T *t,T *m);//移动一个盘子并显示移动过程
void move(T *f,T *t,T *m,int in);//移动盘子,核心算法
/*-------------------移动一个塔(关键算法)并显示移动过程--------------------------------
 移动一个塔从f到t
 参数T型的f t m
 返回:无
*/
 void mov(T *f,T *t,T *m)
{
 char *ch=(char*)malloc(sizeof(char)*60);
 
 t->tower[t->icou+1]=f->tower[f->icou];
 t->icou++;
 f->icou--;
 cleardevice();
 setfont(30, 0,"宋体");
 sprintf(ch,"从%c移动到%c,第大小为%d",f->ch,t->ch,f->tower[f->icou]);
 outtextxy(400,100,ch);
 drawTower();
 showDishes(f);
 showDishes(t);
 showDishes(m);
 Sleep(1000);
}
/*--------------------------------画出塔----------------------------------------
 参数无
 返回无
*/
void drawTower()
{
 setlinestyle(0,NULL,LINE-2); //设置线的格式,三个参数代表实线,自定义模式无效,线宽3像素
 setcolor(RED); //设置前景色
 line(ALOCATION,TOP,ALOCATION,BOTTOM); //A塔
 line(ALOCATION-TW,BOTTOM,ALOCATION+TW,BOTTOM); //A塔塔基
 line(BLOCATION,TOP,BLOCATION,BOTTOM); //B塔
 line(BLOCATION-TW,BOTTOM,BLOCATION+TW,BOTTOM); //B塔塔基
 line(CLOCATION,TOP,CLOCATION,BOTTOM); //C塔
 line(CLOCATION-TW,BOTTOM,CLOCATION+TW,BOTTOM); //C塔塔基
}
/*-------------------------移动函数(核心算法)-------------------------------------
 从f移动in个盘子到t借助m
 参数:T型的f,t,m和盘子数in
 返回:无
*/
 void move(T *f,T *t,T *m,int in)
{
 if (in>0)
 {
  move(f,m,t,in-1);
  mov(f,t,m);
  move(m,t,f,in-1);
 } 
}
/*---------------------------计算并画出所有的盘子---------------------------
 显示塔中的盘子void showDish(T *t);
 参数:当前塔 t
 返回;无
*/
void showDishes(T *t)
{
 int record[3];//记录上一个盘子的左上角坐标
 for (int icou=1;icou<=t->icou;icou++)//icou为要画的第icou个盘子
 {
  //求出当前盘子的左上角坐标和长、宽
  int ix,iy,height,width;
  if (1==icou)
  {
   height=t->tower[icou];//算出直径长度
   width=height*3/7;//算出宽度
   ix=t->tower[0]-height/2;
   iy=BOTTOM-width-(LINE-2)*2;
   //存储坐标
   record[0]=ix;
   record[1]=iy;
   record[2]=height/2;
  }
  else
  {
   height=t->tower[icou];//算出长度
   width=height*3/7;//算出宽度
   //计算坐标
   ix=record[0]+record[2]-height/2;
   iy=record[1]-width-(LINE-2)*2;
   //存储坐标
   record[0]=ix;
   record[1]=iy;
   record[2]=height/2;
  }
  
  drawDish(ix,iy,height,width);
 }
}

/*------------------------------画出一个盘子------------------------------
 画一个盘子void drawDish(int ix,int iy,int height,int width);
 参数:盘子左上角的左边(ix,iy)和盘子的长宽
 返回:无
*/
void drawDish(int ix,int iy,int height,int width)
{
 setcolor(GREEN);//设置前景色为绿色
 line(ix,iy,ix+height,iy);//
 line(ix+height,iy,ix+height,iy+width);//
 line(ix,iy+width,ix+height,iy+width);//
 line(ix,iy,ix,iy+width);//
}
/*----------------------------初始化函数----------------------------------------
 初始化函数 void init(int in)
 功能:
  1、初始化图形界面
  2、初始化A B C 三个塔,并把A塔上画出in个盘子
 参数: 三个塔的指针 f,t,m,盘子数in
 返回:无
*/
void init(T *f,T *t,T *m,int in)
{
 char ch;
 initgraph(WIDTH,HEIGHT,NULL); //初始化为800*600的图形界面
 setfont(50, 0,"宋体"); //设置字体
 setcolor(GREEN);
 outtextxy(300,200,"作者:李丙志");
 outtextxy(300,260,"QQ:958832538");
 outtextxy(300,320,"2012-09-20");
 while(kbhit()==NULL);
 //画出A B C 三个塔
 drawTower();
 //给三个塔初始化
 f->icou=in;
 t->icou=0;
 m->icou=0;
 f->tower[0]=ALOCATION;
 t->tower[0]=CLOCATION;
 m->tower[0]=BLOCATION;
 f->ch='A';
 m->ch='B';
 t->ch='C';
 for (int icou=1;icou<=f->icou;icou++) //初始化A塔中的盘子大小
 {
  f->tower[icou]=MAXD-DEC*2*(icou-1); //直径
 }
 
 //显示三个塔中的盘子
 showDishes(f);
 showDishes(m);
 showDishes(t);

}

//-------------------------------主函数----------------------------------------------------
int main()
{
 //定义三个塔并分配空间
 T *a,*b,*c;
 a=(T*)calloc(1,sizeof(T));
 b=(T*)calloc(1,sizeof(T));
 c=(T*)calloc(1,sizeof(T));
 //初始化化
 init(a,b,c,5);
 move(a,b,c,5); 
 closegraph();
 return 0;
}

结果截图:

注意使用VS时,要修改为多字节编码,否则编译会报错~

posted @ 2012-09-22 22:55  小丙子  阅读(554)  评论(0)    收藏  举报