/*------------------------------------------------------------------------程式說明:迷宮求解用棧實現迷宮尋找一條可行的路徑---------------------------------------------------------------------*//*----------------------------------------------------------------------檔案:useMaze.c功能:提供測試代碼------------------------------------------------------------------*/#include<stdio.h>#include"maze.h"int main(void){MazeType Maze[MAX][MAX] ;PosType start ,end ;InitMaze(Maze) ; //初始化迷宮InitStartEnd(&start,&end) ; //初始化入口出口printf("\n\n\n\n") ;if(MazePath(Maze,start,end)){puts("能找到一條路徑到出口") ;}else{puts("不能找到一條路徑到出口") ;}return 0 ;}/*----------------------------------------------------------檔案:maze.h功能:提供函式宣告以及一些常量標識符、類型定義--------------------------------------------------------*/#ifndef MAZE_H_#define MAZE_H_/*--------------------------------------------------------*//*路徑的一些標識*/#define PASS 0#define USE 1#define BLOCK 2#define DIE 3#define MAX 5#define ISPASS(Pos) (Pos.x >= 0 && Pos.x < MAX && Pos.y>= 0 && Pos.y < MAX && Maze[Pos.x][Pos.y] == PASS )/*-----------------------------------------------------*//*--------------------------------------------------------*//*函數的一些傳回值定義符*/#define OK 1#define FALSE 0#define TRUE 1#define OVERFLOW -1#define ERROR 0typedef int Status ;/*-----------------------------------------------------*//*-----------------------------------------------------*//*一些類型的定義*/typedef int MazeType ; //迷宮類型,二維整型數組實現typedef struct { int x; int y;}PosType ; // 路徑的座標typedef struct //關於每一塊路徑的資訊{int ord ;PosType seat ;int di ;} SElemType ;typedef struct //棧{SElemType *base ;SElemType *top ;int stacksize ;}MazeStack ;#define STACK_ININ_SIZE 100#define STACKINCREMENT 10/*-----------------------------------------------------*//*-----------------------------------------------------*///fuction definedvoid InitStartEnd(PosType *start,PosType *end) ;//InitStartEnd Status DestoryStack(MazeStack *S) ; //DestoryStackStatus Push(MazeStack *S,SElemType e) ; //PushStatus Pop(MazeStack *S, SElemType *e) ;//PopStatus StackEmpty(MazeStack S) ;//StackEmptyvoid MarkPrint(PosType P , MazeType (*Maze)[MAX]); //MarkPrintPosType NextPos(PosType *P, int d) ;//NextPos void FootPrint(const PosType Pos,MazeType (*Maze)[MAX]) ;//FootPrintStatus Pass(const PosType Pos,MazeType (*Maze)[MAX]); //PassStatus InitStack(MazeStack *S) ;//InitStackvoid PrintMaze(MazeType (*Maze)[MAX]); //PrintMazevoid InitMaze(MazeType (*Maze)[MAX]); //InitMazeStatus MazePath(MazeType (*Maze)[MAX],PosType start,PosType end) ;//MazePath/*-----------------------------------------------------*/#endif/*------------------------------------------------檔案:Maze.c功能:提供介面的實現----------------------------------------------*/#include<stdio.h>#include<stdlib.h> //提供realloc#include"maze.h"void InitStartEnd(PosType *start,PosType *end){printf("請輸入入口的橫座標: ") ;scanf("%d",&(start->x )) ;printf("請輸入入口的縱座標:") ;scanf("%d",&(start->y )) ;printf("請輸入出口的橫座標: ") ;scanf("%d",&(end->x )) ;printf("請輸入出口的縱座標:") ;scanf("%d",&(end->y )) ;}//InitStartEnd Status DestoryStack(MazeStack *S){free(S->base) ;S->base = S->top = NULL ;return OK ;}//DestoryStackStatus Push(MazeStack *S,SElemType e){if(S->top -S->base >= S->stacksize ){S->base = (SElemType *)realloc(S->base ,(S->stacksize +STACKINCREMENT) * sizeof(SElemType)) ;if(NULL == S->base ){puts("ERROR") ;exit(OVERFLOW) ;}S->top = S->base + S->stacksize ;S->stacksize += STACKINCREMENT ;}*(S->top )++ = e ;return OK ;}//PushStatus Pop(MazeStack *S, SElemType *e){if(S->top == S->base )return ERROR ;*e = * --S->top ;return OK ;}//PopStatus StackEmpty(MazeStack S){return (S.base == S.top ) ;}// StackEmptyvoid MarkPrint(PosType P , MazeType (*Maze)[MAX]) //注意二維數組的地址是如何傳遞給函數的{Maze[P.x][P.y] = DIE ;}//MarkPrintPosType NextPos(PosType *P, int d){switch(d){case 1 : P->y++ ; break ;case 2 : P->x++ ; break ;case 3 : P->y-- ; break ;case 4 : P->x-- ; break ;}return *P ;} //NextPosvoid FootPrint(const PosType Pos,MazeType (*Maze)[MAX]){//調試使用printf(" x = %d,y = %d\n",Pos.x,Pos.y ) ; Maze[Pos.x][Pos.y] = USE ;}//FootPrintStatus Pass(const PosType Pos,MazeType (*Maze)[MAX]){return ISPASS(Pos) ;}//PassStatus InitStack(MazeStack *S){S->base = (SElemType *) malloc(STACK_ININ_SIZE * sizeof(SElemType) ) ;if(NULL == S->base){puts("ERROR") ;exit(OVERFLOW) ;}S->top = S->base ;S->stacksize = STACK_ININ_SIZE ;return OK ;}//InitStackvoid PrintMaze(MazeType (*Maze)[MAX]){int i = 0 ;int j = 0 ;printf("\n迷宮現狀:\n") ;printf("\n0代表通路、1代表走過、2代表牆壁、3代表死胡同\n") ;for(i = 0 ; i < MAX ; i++){for(j = 0 ; j < MAX ; j++){printf("%2d",Maze[i][j]) ;}printf("\n") ;}}//PrintMazevoid InitMaze(MazeType (*Maze)[MAX]){int i = 0 ;int j = 0 ;printf("\n0代表通路、2代表牆壁\n") ;for(i = 0 ; i < MAX ; i++){for(j = 0 ; j < MAX ; j++)Maze[i][j] = 2 ;}PrintMaze(Maze) ;printf("\n0代表通路、2代表牆壁\n") ;printf("請初始化迷宮:\n") ;for(i = 0 ; i < MAX ; i++){printf("請初始化第%d行: \n",i+1) ;for(j = 0 ; j < MAX ; j++)scanf("%d",&Maze[i][j]) ;}PrintMaze(Maze) ;}//InitMazeStatus MazePath(MazeType (*Maze)[MAX],PosType start,PosType end){SElemTypee ;MazeStack S ;PosType curpos ;int curstep ;InitStack(&S) ; //初始化棧curpos = start ; // start.x= start.y = 0curstep = 1 ;do{if(Pass(curpos,Maze)){FootPrint(curpos,Maze) ;e.di = 1 ;e.seat = curpos ;e.ord = curstep ;Push(&S,e) ;if(curpos.x == end.x && curpos.y == end.y ){PrintMaze(Maze) ;return TRUE ;} //ifcurpos = NextPos(&curpos,1) ;curstep++ ;} //ifelse{if(!StackEmpty(S)){Pop(&S,&e) ;while(e.di == 4 && !StackEmpty(S)){MarkPrint(e.seat,Maze) ;Pop(&S,&e) ;} //whileif(e.di <4){e.di++ ;Push(&S,e) ;curpos = NextPos(&(e.seat) ,e.di) ;} //if} //if} //else}while(!StackEmpty(S)) ; //whilePrintMaze(Maze) ;return FALSE ;} // MazePath