- [cutebe] 相当牛,这个苦思冥想也值了。^_^ 11/30 00:00
- [parse] 如果忽略消息循环,那么操作系统加载的程序很快就执行完了,就像DOS程序一闪而过,所以CPU会空闲下来 06/30 09:04
- [游客] 楼主好厉害,挺一下! 01/19 08:43
- [游客] 很不错。 01/04 18:36
- [chinatree] 潜力贴留名,沙发。 11/08 12:58
- [youthangel] 恩,这次对了 10/30 18:56
- [fpamc] mov bx,18 在这条指令的上边是不是要加一条sub dx,dx? 10/30 10:03
- [fpamc] 对的 10/27 11:19
- [fpamc] 对的 10/27 09:00
- [fpamc] 哦,对不起,看错了。实验13也有一个7ch中断 10/27 08:52
- [游客] 现在急需一个汇编大作业。。。。。。可以么。。。。。如果今天之内看见留言 就加 1765496715 12/28 16:52
- [youthangel] 这算是对我学习的鼓励吗?谢谢!咱们这样交流就可以了 10/11 15:48
- [fpamc] 多日观察,你的学习积极性挺高的。可以来我们群了。群号:75916434 10/11 10:58
[2012-10-12 18:16] 用C语言画图实现汉诺塔问题的演示
/**
汉诺塔实验:
1、三个塔 A B C
2、把从A 塔借助 B塔转移到C塔
3、盘子的宽比长为3:7
开发环境:EasyX插件+VC6.0 。新建一个.cpp文件把代码考进去就OK了
注意事项
目前程序只允许盘子的个数是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,"扣扣:958832538");
outtextxy(300,260,"汇编交流扣扣群:271328592");
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;
}
汉诺塔实验:
1、三个塔 A B C
2、把从A 塔借助 B塔转移到C塔
3、盘子的宽比长为3:7
开发环境:EasyX插件+VC6.0 。新建一个.cpp文件把代码考进去就OK了
注意事项
目前程序只允许盘子的个数是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,"扣扣:958832538");
outtextxy(300,260,"汇编交流扣扣群:271328592");
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;
}
评论次数(1) |
浏览次数(295) |
类型(冥思苦想) |
收藏此文 |