这是自己编写的第一个dos动画程序,所以自己感触很深,今天作为一个成就,写于自己的博客中,希望和大家分享~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
定义头文件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"
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
typedef int Status;
typedef int Boolean;
定义存储数据结构包含于m1.h头文件
#define INIT_STACK_SIZE 40
#define STACK_ADD 10
#define INIT_QUEUE 100
#define INIT_ADD 40
typedef struct
{
int road;
int foot;
int direct;
}migong,*mi;
typedef struct
{
mi elem; // 定义能够接受迷宫结构体指针的变量
int size; // 记录迷宫初始化大小
}ji,*hui;
typedef struct
{
int i; // 行
int j; // 列
}cun;
typedef struct // 把位子放入栈中 线性表操作
{
cun *top;
cun *bottom;
int stacksize;
} Sqstack;
typedef struct sq
{
int i,j; //存放前面的下标位置
int i1,j1; // 存放当前位置
}sq;
typedef struct //定义队列数据结构
{
sq*front;
sq*rear;
int size;
}dui;
定义实现函数包含于migong.cpp文件中
void initdui(dui &L) // 初始化队列
{
L.front=(sq*)malloc(INIT_QUEUE*sizeof(sq));
L.rear=L.front;
if(!L.front)
{
printf("内存分配失败!!");
exit(1);
}
L.size=INIT_QUEUE;
printf("初始化成功!! \n");
}
void enqueue(dui &L,int i,int j,int i1,int j1) // 此队列针对迷宫先全部进完后再出,而设的顺序队列
{
if(L.rear-L.front>L.size) // 队列已满,追加空间
{
L.front=(sq*)realloc(L.front,(L.size+INIT_ADD)*sizeof(sq));
if(!L.front)
{
printf("追加空间失败!!");
exit(1);
}
}
L.rear->i=i;
L.rear->j=j;
L.rear->i1=i1;
(L.rear++)->j1=j1;
}
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 q,int p) // 压入位置 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->i=q;
(L.top++)->j=p;
return OK;
}
Status pop(Sqstack &L,int &k,int &l) // 弹出 将栈顶的元素带回
{
if(L.top == L.bottom)
return ERROR;
k=(--L.top)->i; // 这点自己犯的问题 不能--L.top->i 这样就表示值减1 没意义,出错
l=L.top->j;
return OK;
}
Status emptystack(Sqstack L) // 判断栈为空
{
if(L.top == L.bottom)
return OK;
else
return ERROR;
}
void init(ji &L) // 初始化数据
{
printf("输入迷宫的行大小:");
scanf("%d",&L.size);
L.size+=2;
L.elem=(mi)malloc(L.size*L.size*sizeof(migong));
if(!L.elem)
{
printf("分配内存失败!!");
exit(1);
}
printf("初始化成功!\n");
}
void print(ji L)
{
int m;
// printf("打印输出!!\n\n");
m=L.size*L.size;
for(int i=0;i<m;i++)
{
//if((i+1)%L.size != 1 && (i+1)%L.size != 0 && i>L.size-1 && i<m-L.size+1 )
if( (L.elem+i)->road == 0)
{
printf("▇");
}
else
printf(" ");
if((i+1)%L.size == 0)
printf("\n");
}
printf("\n");
}
void shuru(ji &L,int &e)
{
int m=L.size*L.size;
for(int i=0;i<m;i++)
{
(L.elem+i)->direct=1;
(L.elem+i)->foot=0;
if((i+1)%L.size == 1 || (i+1)%L.size == 0 || i<=L.size-1 || i>=m-L.size+1)
(L.elem+i)->road=0;
else
(L.elem+i)->road=1; // 表示通路,初始化全部为
}
// print(L);
printf("设置墙:\n");
printf("输入迷宫的行和列:");
int k,j;
char ch='y';
while('Y' == ch || 'y' == ch)
{
scanf("%d%d",&k,&j);
(L.elem+k*L.size+j)->road=0;
e++;
printf("是否继续(Y/y):");
getchar();
ch=getchar();
}
// print(L);
getchar();
}
void shituan(ji &L,int z,int x,int &m,int &n) // 判断方向
{
switch((L.elem+L.size*z+x)->direct) // 线性表中位置的转换
{
case 1:m=z,n=x+1;break;
case 2:m=z+1,n=x;break;
case 3:m=z,n=x-1;break;
case 4:m=z-1,n=x;break;
}
}
void chuli(ji &L,dui &T,Sqstack &R)
{
int m=1,n=1,i=1,j=1;
int q=0,p,t;
sq*w=T.front-1,*r;
//printf("开始执行!!");
//getchar();
enqueue(T,1,1,1,1);
(L.elem+L.size+1)->foot=1;
t=1;
while(m != L.size-2 || n != L.size-2) // 循环条件是不是最后一个位置
{
// printf("进入循环!!");
// getchar();
r=w;
q=0;
for(p=1;p<=t;p++)
{
w++; // 查询入队元素的位置,不停的更新
i=w->i; // 取得已经入队元素的当前位置坐标
j=w->j;
while((L.elem+L.size*i+j)->direct <= 4) // 寻找4个方位 满足条件的位置
{
// printf("进入内部循环!!");
shituan(L,i,j,m,n);
if((L.elem+L.size*m+n)->road != 0 && (L.elem+L.size*m+n)->foot != 1) // 该位置不是墙也不是已经走过的路径
{
enqueue(T,m,n,i,j); // 压入位置
q++; // 入队元素个数记录
(L.elem+L.size*m+n)->foot=1; // 留下足迹
}
(L.elem+L.size*i+j)->direct++;
if(m == L.size-2 && n == L.size-2) // 找到最后一个跳出循环
break;
}
if(m == L.size-2 && n == L.size-2)
break;
}
t=q; // 将q循环的值放入t中,最为下次循环的终止条件
if(r == w)
{
printf("无通路!!\n");
exit(1);
}
if(m == L.size-2 && n == L.size-2)
break;
}
m=(--T.rear)->i; // 队列中的最后一个入队元素中是最后一个位置
n=T.rear->j;
push(R,m,n);
i=T.rear->i1;
j=T.rear->j1;
(L.elem+L.size*m+n)->road=2;
// printf("进入第二个循环!!");
// getchar();
while(T.rear != T.front) // 往上一直寻找
{
m=(--T.rear)->i;
n=T.rear->j;
if(i == m && j == n)
{
push(R,m,n);
(L.elem+L.size*m+n)->road=2; // 通路置为2
i=T.rear->i1;
j=T.rear->j1;
// push(R,i,j);
}
}
// print(L); // 打印路径
}
void chuli1(ji &L,Sqstack &T)
{
int m,n,i=1,j=1;
//printf("开始执行!!");
while(m!=L.size-2 || n!=L.size-2) // 循环条件是不是最后一个位置
{
shituan(L,i,j,m,n);
(L.elem+L.size*i+j)->direct++;
if((L.elem+L.size*m+n)->road != 0 && (L.elem+L.size*m+n)->foot != 1) // 该位置不是墙也不是已经走过的路径
{
push(T,i,j); // 压入位置
(L.elem+L.size*i+j)->foot=1; // 留下足迹
(L.elem+L.size*i+j)->road=2; // 将通路为置为2,表示路径
i=m;
j=n;
}
else if((L.elem+L.size*i+j)->direct >4) // 4个方向都没有路了
{
if(emptystack(T)) // 当前栈里面是否有元素
{
printf("无通路!!!~~~~~~~~~~~~~\n试探路径为:\n");
print(L);
exit(1); // 退出程序
}
(L.elem+L.size*i+j)->road=-1; // 将走过的路,不通的留下记号,标记为-1
(L.elem+L.size*i+j)->foot=1; // 留下足迹
pop(T,i,j); // 不通的路径出栈
}
}
if(m == L.size-2 && n == L.size-2) // 将最后一个位置为留下2
{
(L.elem+L.size*m+n)->road=2;
push(T,m,n);
}
// print(L);
}
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 move(int m,int n,int p,int q,int e)
{
gotoxy(2*n,m+e); // 将上一个位置的“中”用空格代替
printf(" ");
gotoxy(2*q,e+p); // 下一个用“中”代替
printf("中");
}
void huatu(Sqstack &L,int &e,int &i) // 画图,产生动画
{
int x1,y1,x2,y2;
pop(L,x1,y1); // 弹出栈的第一个元素
gotoxy(2*x1,e+y1);
i=1;
printf("中"); // 将位置画出起始位置
getchar();
while(!emptystack(L)) // 直到栈元素全部弹出
{
pop(L,x2,y2);
move(x1,y1,x2,y2,e);
x1=x2;
y1=y2;
i++;
Sleep(500); // 暂停0.5秒
}
}
定义主函数中调用包含于main_5中
#include"t11.h"
#include "windows.h" // 包含暂停函数
#include"m1.h"
#include"migong.cpp"
void main()
{
int x1,y1,e=0,k;
ji S;
dui T;
Sqstack X,R,F; // 设立栈,将路径入栈
initdui(T);
init(S);
initstack(X);
initstack(R);
initstack(F);
shuru(S,e);
e=2*e+4; // 算出光标的位置
chuli1(S,X);
while(!emptystack(X)) // 将栈重新调整
{
pop(X,x1,y1);
push(F,x1,y1);
}
print(S); // 打印出迷宫图案
huatu(F,e,k); // 画图函数,找出按规定算法的路径
printf("\n\n恭喜你一条路径出来啦!! 历经%d步\n",k);
int m=S.size*S.size; // 保存长度值
for(int i=0;i<m;i++) // 对比,将用户设置的墙不变,其他回归初始状态
{
if((S.elem+i)->road != 0)
(S.elem+i)->road=1;
(S.elem+i)->direct=1;
(S.elem+i)->foot=0;
}
chuli(S,T,R); // 做出处理
print(S); // 打印路径
e=e+S.size+1; // 算出此刻光标位置
huatu(R,e,k); // 找出最短路径
printf("\n\n恭喜你最短路径出来啦!! 历经%d步\n",k);
}
这是全部自己思想编写出来的,我很享受思考的过程,虽然会有困难,但这是一个很有意思的过程,不仅需要严谨的逻辑思维还需要充分的耐心。
贴上代码下载代码:http://download.csdn.net/detail/wu10045125/4679590