dos下实现汉若塔动画的移动程序和思想
来源:互联网 发布:知乎数据挖掘考研 编辑:程序博客网 时间:2024/06/05 04:59
程序的主要思想是标识盘子的位置,和该入的柱子号,很容易让人联想到栈实现,设立三个栈,动态记录盘子数和要出栈的序号
定义t11.h包含常用头文件
#include"stdio.h"
#include"string.h"
#include"ctype.h"
#include"malloc.h"
#include"stdlib.h" //atoi(),exit();
#include"io.h" //eof()
#include"math.h"
#include"windows.h"
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
typedef int Status;
typedef int Boolean;
int p=1; // 全局变量,记录移动步数
定义数据类型包含于头文件hrt.h中
#define INIT_STACK_SIZE 40
#define STACK_ADD 10
typedef struct
{
int xu; // 对应的盘子序数
int zbj; // 对应的纵坐标
}cun;
typedef struct // 把位子放入栈中 线性表操作
{
cun *top;
cun *bottom;
int stacksize;
} Sqstack;
定义实现函数包含于hrt.cpp中
extern p; // 引用全局变量
void initstack(Sqstack &L) // 初始化栈操作
{
L.bottom=(cun*)malloc(INIT_STACK_SIZE*sizeof(cun));
if(!L.bottom)
{
printf("内存分配失败!!");
exit(-1);
}
L.top=L.bottom;
L.stacksize=INIT_STACK_SIZE;
}
Status push(Sqstack &L,int xu,int zbj) // 压入位置 q表示行,p表示列
{
if(L.top-L.bottom >= L.stacksize)
{ L.bottom=(cun*)realloc(L.bottom,(L.stacksize+STACK_ADD)*sizeof(cun));
if(!L.bottom)
{
printf("内存分配失败!!");
exit(-1);
}
L.top=L.bottom+L.stacksize;
L.stacksize+=STACK_ADD;
}
L.top->xu=xu;
(L.top++)->zbj=zbj;
return OK;
}
Status pop(Sqstack &L,int &xu,int&zbj) // 弹出 将栈顶的元素带回
{
if(L.top == L.bottom)
return ERROR;
xu=(--L.top)->xu; // 这点自己犯的问题 不能--L.top->i 这样就表示值减1 没意义,出错
zbj=L.top->zbj;
return OK;
}
Status emptystack(Sqstack L) // 判断栈为空
{
if(L.top == L.bottom)
return OK;
else
return ERROR;
}
int gettop(Sqstack L,int &xu,int &zbj)
{
if(L.top == L.bottom)
return ERROR;
else
{
xu=(L.top-1)->xu;
zbj=(L.top-1)->zbj;
return OK;
}
}
void GotoConsoleXY(HANDLE hConsole,int x,int y) // 定位光标位置
{
COORD coordScreen={x,y};
SetConsoleCursorPosition(hConsole,coordScreen);
return;
}
void gotoxy(int x,int y) // 定位光标位置
{
HANDLE hStdOut=GetStdHandle(STD_OUTPUT_HANDLE);
GotoConsoleXY(hStdOut,x,y);
return;
}
void huatu(Sqstack &A,Sqstack &B,char (*b)[16],char (*a)[16],int e,int zbj,int l,int xu) // 画图
{
int xs,hs;
if(e<l) // 从左到右
{
for(int i=0;i<zbj-5;i++) // 从塔中出来到达顶端
{
gotoxy(e-xu+1,zbj-i); // 定位对应盘的起始盘子代号
printf("%s",*(b+xu-1)); // 输出对应的空格字符代号
gotoxy(e,zbj-i); // 定位盘子的位置
printf("|"); // 输出竖杠
gotoxy(e-xu+1,zbj-i-1); // 定位产生动画的下一个光标位置
printf("%s",*(a+xu-1)); // 打印出对应的盘子数
Sleep(50); // 暂停0.5毫秒
}
for(i=0;i<l-e;i++) // 平行移动
{
gotoxy(e-xu+1+i,5); // 定位平行的位置
printf("%s",*(b+xu-1)); // 将其对应的清除
gotoxy(e-xu+2+i,5); // 定位下一个单位
printf("%s",*(a+xu-1)); // 打印出对应的盘子
Sleep(20); // 暂停0.2毫秒
}
if(!emptystack(B)) //判断要移动到的盘子是否为空
gettop(B,xs,hs); // 得到该盘子的横行及序号
else
hs=14; // 将横行置为最底层
gotoxy(e-xu+1+i,5); // 将要入盘的第一个位置定位
printf("%s",*(b+xu-1)); // 输入对应空格覆盖
gotoxy(e-xu+1+i,6); // 定位入盘的光标位置
printf("%s",*(a+xu-1)); // 空格覆盖
Sleep(50); // 暂停0.5毫秒
for(int k=6;k<hs-1;k++) // 进入要移动的指定塔上
{
gotoxy(e-xu+1+i,k);
printf("%s",*(b+xu-1));
gotoxy(l,k);
printf("|");
gotoxy(e-xu+1+i,k+1);
printf("%s",*(a+xu-1));
Sleep(50);
}
push(B,xu,k); // 将序数和位置入栈
}
else // 从右到左
{
for(int i=0;i<zbj-5;i++)
{
gotoxy(e-xu+1,zbj-i);
printf("%s",*(b+xu-1));
gotoxy(e,zbj-i);
printf("|");
gotoxy(e-xu+1,zbj-i-1);
printf("%s",*(a+xu-1));
Sleep(50);
}
for(int k=e;k>=l;k--)
{
gotoxy(k-xu+1,5);
printf("%s",*(b+xu-1));
gotoxy(k-xu,5);
printf("%s",*(a+xu-1));
Sleep(20);
}
if(!emptystack(B))
gettop(B,xs,hs);
else
hs=14;
gotoxy(l-xu,5);
printf("%s",*(b+xu-1));
gotoxy(l-xu+1,6);
printf("%s",*(a+xu-1));
Sleep(50);
for( k=6;k<hs-1;k++)
{
gotoxy(l-xu+1,k);
printf("%s",*(b+xu-1));
gotoxy(l,k);
printf("|");
gotoxy(l-xu+1,k+1);
printf("%s",*(a+xu-1));
Sleep(50);
}
push(B,xu,k); // 将盘子序数和要入的光标位置
}
Sleep(500); // 暂停0.5秒
}
void move(Sqstack &A,Sqstack &B,Sqstack &C,char (*b)[16],char (*a)[16],char X,char Y)
{
int xu,zbj;
switch(X) // 匹配移动盘子代号
{
case 'A':
switch(Y)
{
case 'B':{
pop(A,xu,zbj); // 弹出对应盘子的序数和横行位置
huatu(A,B,b,a,16,zbj,40,xu);
p++; // 全局变量加1,表示移动了一步
};break;
case 'C':{
pop(A,xu,zbj);
huatu(A,C,b,a,16,zbj,64,xu);
p++;
};break;
};break;
case 'B':
switch(Y)
{
case 'A':{
pop(B,xu,zbj);
huatu(B,A,b,a,40,zbj,16,xu);
p++;
};break;
case 'C':{
pop(B,xu,zbj);
huatu(B,C,b,a,40,zbj,64,xu);
p++;
};break;
};break;
case 'C':
switch(Y)
{
case 'A':{
pop(C,xu,zbj);
huatu(C,A,b,a,64,zbj,16,xu);
p++;
};break;
case 'B':{
pop(C,xu,zbj);
huatu(C,B,b,a,64,zbj,40,xu);
p++;
};break;
}
}
}
void hrt(Sqstack &e,Sqstack &f,Sqstack &g,char (*b)[16],char (*a)[16],int n,char A,char B,char C)
{
if(n == 1)
{
gotoxy(28,3);
printf("(第%d步,第%d个盘): %c->%c ",p,1,A,C); // 动态显示移动盘子和步数
move(e,f,g,b,a,A,C);
}
else
{
hrt(e,f,g,b,a,n-1,A,C,B); // 递归调用
gotoxy(28,3);
printf(" ");
gotoxy(28,3);
printf("(第%d步,第%d个盘): %c->%c ",p,n,A,C);
move(e,f,g,b,a,A,C);
hrt(e,f,g,b,a,n-1,B,A,C);
}
}
最后就是在主函数里面进行调用了,定义文件main_hrt.cpp
#include"t11.h"
#include"hrt.h"
#include"hrt.cpp"
extern p; // 引用全局变量
void main()
{
int n;
Sqstack A,B,C;
initstack(A);
initstack(B);
initstack(C);
char a[][16]={"-","---","-----","-------","---------","-----------","-------------","---------------"}; // 定义盘子
char b[][16]={" "," "," "," "," "," "," "," "}; // 定义要覆盖对应的空格
printf("输入盘子数(<=8):");
scanf("%d",&n);
printf("\n\n\n\n\n");
if(n>8)
{
printf("输入不正确!");
exit(1);
}
for(int i=1;i<=8;i++)
printf("\t\t|\t\t\t|\t\t\t|\n");
printf("\t\t A\t\t\t B\t\t\t C\n");
for( i=0;i<n;i++) // 将盘子的代号入栈
{
gotoxy(17-n+i,13-i);
printf("%s",a[n-1-i]);
push(A,n-i,13-i);
}
printf("\n\n\n\n\n\n\n\n\n\n\n\n");
getchar(); getchar();
hrt(A,B,C,b,a,n,'A','B','C');
printf("\n\n\n\n\n\n\n\n\n\t\t\t移动结束!~~~~~@@@@~~~~~\n\t\t\t历经步数:%d 步\n",p-1);
getchar();
}
总结:程序的思路清晰就很好编写代码,只要基础功好,肯思考,就会一点一点进步,这是自己随手编写的一个小程序,全部完成花了将近4个多小时,但还是觉得自己的逻辑能力还行,编程的过程中也是一个渐渐熟悉的过程,我只用一个简单的栈操作完成了,想必以后我一定会用更好的方法编写完的。~~~~~~~~~~~~留住最真的于2012.04.04.21:49写。。。。。。
程序图片为: 希望大家批评指正,有更好的方法,欢迎交流分享。
代码的下载地址贴上:http://download.csdn.net/detail/wu10045125/4679585 希望能够结识更多编程的好友。。。。。。~~~~~~~~~~~~~~~~~~··
- dos下实现汉若塔动画的移动程序和思想
- Dos下的屏保程序实现
- Console程序和Dos程序的差别
- DOS下的倒记时程序
- DOS 下的简单登陆程序
- dos下读写内存的小程序
- DOS下内存分页程序的编写
- Linux下的Dos攻击程序
- DOS下编辑的LINUX程序
- DOS下的多窗口程序!
- TESHELL DOS下的测试程序管理软件
- Linux下的Dos攻击程序
- 单片机实现灯左右移动和闪烁的程序
- Unity12--鼠标按键的移动实现程序和Random随机数
- Android移动开发-属性动画的实现
- Android RecyclerView 详解(三) RecyclerView的动画实现(移除、添加、改变、移动)和自定义动画的实现
- 在VS2008的Debug32模式和Dos下运行程序时对于“./”的理解
- 在WINDOWS下和DOS(硬盘安装)下实现全自动安装XP系统的方法
- 第七周C++实验报告(1)
- 第七周C++实验报告(2)
- ZOJ Problem Set - 1049
- 第七周C++实验报告(3)
- hduoj2544:最短路
- dos下实现汉若塔动画的移动程序和思想
- 用js取得DIV的top,left,width,height值
- LAMP安装配置超详细讲解!
- 浅谈C中的wprintf和宽字符显示 .
- C++ char *c 与char []的区别
- GDI函数 坐标系综述
- oracle 日志文件、参数文件、控制文件备份恢复
- poj 1364 King 差分约束
- task_struct和mm_struct和vm_area_struct和vm_operation_struct