迷宮的實現--c語言

#include <stdio.h>
#include <stdlib.h>
#include <time.h>


#define M 20
#define N 20

#define visited 2
#define TRUE 1
#define FALSE 0
#define INITSIZE 100

typedef int Status;

typedef struct{       //座標點結構體
 int y;    //每個可通的行座標
 int x;  //每個可通的列座標
}PosType;

typedef struct{
 int ord;     //通道塊在路徑上的"序號"
 int di;    //從此通道塊走向下一通道塊的"方向"
 PosType seat;    //通道塊在迷宮中的"座標位置"
}MazeNode;     //迷宮節點

typedef struct {

 MazeNode base[INITSIZE];
 int top;   //棧頂指針

}Stack;

typedef struct{                 //用於存儲迷宮的路徑
 PosType coor[INITSIZE];
 int top;
}Postion;


void RandMatrix();     //隨機生成迷宮
int InitStack(Stack *);   //初始化棧
int InitStack1(Postion *);
int StackEmpty(Stack *);    //判斷棧是否爲空
int StackEmpty1(Postion *);
int StackIsFull(Stack *);  //判斷棧是否滿了
int StackIsFull1(Postion *);  //判斷棧是否滿了

int Push(Stack *s,MazeNode m);    //壓棧
int Push1(Postion *,PosType);
int Pop(Stack *s,MazeNode *m);  //出棧
int Pop1(Postion *,PosType *);
int DestroyStack(Stack *s);   //撤銷棧
int Pass(PosType pos); //判斷指定座標是否可通過

int FootPrint(PosType pos);      //標記能通過的
PosType NextCoord(PosType pos,int i);  //獲取下一位置

int MarkPrint(PosType pos);     //留下不能通過的標記,並退回一步
int MazePath(PosType start,PosType end,Postion *);   //從迷宮的入口到出口查找
void PrintMaze(Postion *);   //輸出迷宮

int mg[M][N];    //生成一個M*N 的迷宮

int main()
{
 int h=1;
 PosType start,end;
 Postion P;
 while(h)
 {
 printf("創建迷宮\n");
 InitStack1(&P);
 RandMatrix();

 printf("\n");
 printf("1、重新生成迷宮,0、就這個:");
 scanf("%d",&h);
 }
 do   //輸入迷宮入口座標
 {
  printf("\n輸入迷宮入口座標");
  scanf("%d%d",&start.x,&start.y);
  if(start.x>N || start.y>M)
  {
   printf("輸入的座標越界,請重新輸入!\n");
   continue;
  }
 }while(start.x>N || start.y>M);
 do   //輸入迷宮出口座標
 {
  printf("\n輸入迷宮出口座標:");
  scanf("%d%d",&end.x,&end.y);
  if(end.x>N || end.y>M)
  {
   printf("輸入的座標越界,請重新輸入!\n");
   continue;
  }
 }while(end.x>N || end.y>M);
 if(!MazePath(start,end,&P))    //調用函數查找路徑
 {
  printf("\n無法通過!\n");
 }
 else
 {
  PrintMaze(&P);    //打印找到的路徑
 } 
    system("pause");
 return 0;

}
int InitStack(Stack *s)
{
 s->top=-1;
 return 1;
}
int InitStack1(Postion *s)
{
 s->top=-1;
 return 1;
}
int StackEmpty(Stack *s)
{
 if(s->top==-1)
  return 1;
 return 0;
}
int StackEmpty1(Postion *s)
{
 if(s->top==-1)
  return 1;
 return 0;
}
int StackIsFull(Stack *s)
{
 if(s->top==INITSIZE-1)
  return 1;
 else
  return 0;
}
int StackIsFull1(Postion *s)
{
 if(s->top==INITSIZE-1)
  return 1;
 else
  return 0;
}

int Push(Stack *s,MazeNode m)
{
 if(!StackIsFull(s))
 {
  s->top++;
  s->base[s->top]=m;
 }
 return 1;
}
int Push1(Postion *s,PosType m)
{
 if(!StackIsFull1(s))
 {
  s->top++;
  s->coor[s->top]=m;
 }
 return 1;
}

int Pop(Stack *s,MazeNode *m)
{
 if(s->top!=-1)
 {
  *m=s->base[s->top];
  s->top--;
  return 1;
 }
 return 1;
}
int Pop1(Postion *s,PosType *m)
{
 if(s->top!=-1)
 {
  *m=s->coor[s->top];
  s->top--;
  return 1;
 }
 return 1;
}
int DestroyStack(Stack *s)
{
 s->top=-1;
 return 1;
}
int Pass(PosType pos) //判斷指定座標是否可通過
{
 if(mg[pos.y][pos.x]==0)  //可通
  return 1;
 else
  return 0;
}

int FootPrint(PosType pos)   //標記能通過的
{
 mg[pos.y][pos.x]=2;      //2表示可通
 return 1;
}

PosType NextCoord(PosType pos,int i)  //獲取下一位置
{
 switch(i)   //1,2,3,4,5,6,7,8代表方向順時針
 {
  case 1:
   pos.x+=1;  //向右側查找
   break;
  case 2:
   pos.x+=1;
   pos.y+=1;
   break;
  case 3:
   pos.y+=1;
   break;
  case 4: 
   pos.y+=1;
   pos.x-=1;
   break;
  case 5:
   pos.x-=1;
   break;
  case 6:
   pos.x-=1;
   pos.y-=1;
   break;
  case 7:
   pos.y-=1;
   break;
  case 8:
   pos.y-=1;
   pos.x+=1;
   break;
  default :
   exit(0);
 }
 return pos;
}


int MarkPrint(PosType pos)   //留下不能通過的標記,並退回一步
{
 mg[pos.y][pos.x]=3;   //3表示曾走過,但不通
 return 1;
}

void RandMatrix()
{
 int i=0,j=0;
 srand((unsigned)time(NULL));
 for(i=0;i<M;i++)
  for(j=0;j<N;j++)
   mg[i][j]=rand()%2;
 i=0;
 for(j=0;j<N;j++)
 {
  mg[i][j]=1;
  mg[j][i]=1;
 }
 i=N-1;
 for(j=0;j<M;j++)
 {
  mg[j][i]=1;
  mg[i][j]=1;
 }
 mg[1][1]=0;
 mg[M-2][N-2]=0;
 printf("\n");
 for(i=0;i<M;i++)
 {
  for(j=0;j<N;j++)
  {
   if(mg[i][j]==1)     //若是障礙
   {
    printf("█");
   }
   else if(mg[i][j]==2)   //若是可通路徑
   {
    printf("◎");
   }
   else if(mg[i][j]==3)
   {
    printf("☆");    //其他位置
   }
   else
    printf("  ");
  }
  printf("\n");
 }
}
 
int MazePath(PosType start,PosType end,Postion *P)   //從迷宮的入口到出口查找
{
 //若迷宮maze中存在從入口start到出口end的通道,則求得一條存放在棧中(從棧底到棧頂)
 //並返回TRUE,否則返回FALSE
 Stack S;   //定義棧
 PosType curpos;
 int curstep;  //當前序號1,2,3,4,5,6,7,8代表方向,1代表向右,後依次順時針
 MazeNode e;
 InitStack(&S);
 curpos=start;   //設定"當前位置"爲"入口位置",從入口位置開始查找
 curstep=1;    //探索第一步
 do  
 {
  if(Pass(curpos))
  {
   //從當前位置可以通過,即是未曾走到過的通道塊
   FootPrint(curpos);   //標記能通過的
   e.ord=curstep; //保存步數
   e.seat=curpos;
   e.di=1;  //向右側探測
   Push(&S,e);    //加入路徑
   Push1(P,curpos);
   if(curpos.y==end.x && curpos.x==end.y)   //若當前位置是出口座標
   {
    DestroyStack(&S);   //釋放棧佔用的空間
    return 1;  //返回查找成功
   }
   else    //與出口座標不同
   {
    curpos=NextCoord(curpos,1);  //向右側探測
    curstep++;   //探索下一步
   }
  }
  else   //當前位置不能通過(爲障礙或已走過)
  {
   if(!StackEmpty(&S))   //若棧不爲空,之前有走過的位置
   {
    Pop(&S,&e);  //出棧(返回上一步的位置)
    Pop1(P,&curpos);
    while(e.di==8 && !StackEmpty(&S))  //上一步,四個方向都探測定,且棧不爲空
    {
     MarkPrint(e.seat);   //留下不能通過的標記,並退回一步
     Pop(&S,&e);  //出棧,返回上一步
     Pop1(P,&curpos);
    }
    if(e.di<8)
    {
     e.di++; //換下一個方向探索,準備探測下一個方向
     Push(&S,e); //將當前節點入棧
     Push1(P,curpos);
     curpos=NextCoord(e.seat,e.di);  //設定當前位置是該新方向上的相鄰塊,查找下一個應該探測的方向
    }
   }
  }
 }while(!StackEmpty(&S));
 //程序運行到這裏,表示沒有能通達的路徑
 DestroyStack(&S);  //釋放佔用的空間
 return FALSE;  //返回失敗
}

void PrintMaze(Postion *P)   //輸出迷宮

 int i,j;
 PosType e;
 Postion W;
 InitStack1(&W);
 while(!StackEmpty1(P))
 {
  Pop1(P,&e);
  Push1(&W,e);
 }

 printf("\n可以通過,迷宮路徑:\n");     //在這裏可以設置迷宮的界面
 for(i=0;i<M;i++)
 {
  for(j=0;j<N;j++)
  {
     if(mg[i][j]==1)     //若是障礙
   {
    printf("█");
    
   }
   else if(mg[i][j]==2)   //若是可通路徑
   {
    printf("◎");
   
   }
      else if(mg[i][j]==3)
   {
    printf("☆");    //其他位置
   
   }
   else
   {
    printf("  ");
  
   }

  }
  printf("\n");
 }
 printf("\n\n");
 i=1;
 printf("迷宮的最短路徑爲:");
 while(!StackEmpty1(&W))
 {
  i++;
  Pop1(&W,&e);
  printf("(%d,%d),  ",e.y,e.x);
 }
 printf("\n\n");
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章