[置顶] 迷宫的寻找路径和最短路径的动画演示

这是自己编写的第一个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

 

你可能感兴趣的:(数据结构,算法,struct,dos,存储,output)