//c语言版数据结构(奇迹冬瓜)-栈实战(1)栈解迷宫<迷宫算法>
//题目:栈解迷宫
//---------头文件---------
#include<stdio.h>
#include<stdlib.h>
//---------宏定义---------
#define TRUE 1
#define ERROR 0
#define OVERFLOW -2
//------替换和结构体-------
typedef int Status;
typedef struct
{
int x;
int y;
int attribute;
}seat;
typedef struct
{
int height;
int width;
seat *wall;
}maze;
typedef struct
{
seat NowPosition;
int id;
}Block;
typedef struct
{
Block *base;
Block *top;
int stacksize;
}SqStack;
//------全局变量------
maze ma,*m=&ma;
//-------函数---------
int ComputerMazeStep(maze *m,seat start,seat end);
void CreatDigitalMap(maze *m);
void CreatInerfaceMap(maze *m);
void CreatInerfaceMapAgain(maze *m);
Status InitMap(maze *m);
Status InitStack(SqStack *s);
void InputAddStartAndEnd(seat *start,seat *end);
int JudgeThrough(maze *m,Block foot);
void MakeNoThroughSign(maze *m,Block foot);
void MakeThroughSign(maze *m,Block foot);
void NextStep(Block *foot,int id);
Status Pop(SqStack *s,Block *foot);
Status Push(SqStack *s,Block foot);
int VisitMap(maze *m,int x,int y);
//-----主函数-----
void main()
{
seat start,end;
CreatDigitalMap(m);
CreatInerfaceMap(m);
InputAddStartAndEnd(&start,&end);
if(ComputerMazeStep(m,start,end))
{
CreatInerfaceMapAgain(m);
}
else
{
printf("此迷宫没有通路的求解.\n");
}
getchar();
getchar();
}
//-------其它函数--------
int ComputerMazeStep(maze *m,seat start,seat end)
{
int flag=1;
SqStack sq,*s=&sq;
Block foot,blockfoot;
InitStack(s);
foot.id=1;
foot.NowPosition.x=start.x;
foot.NowPosition.y=start.y;
Push(s,foot);
MakeThroughSign(m,foot);
while(!(s->base==s->top))
{
blockfoot.NowPosition=foot.NowPosition;
NextStep(&foot,foot.id);
if(foot.id<5)
{
if(JudgeThrough(m,foot))
{
MakeThroughSign(m,foot);
Push(s,foot);
foot.id=1;
}
else
{
foot.NowPosition=blockfoot.NowPosition;
foot.id++;
}
}
else
{
MakeNoThroughSign(m,foot);
Pop(s,&foot);
}
if(foot.NowPosition.x==end.x&&foot.NowPosition.y==end.y)
{
flag=0;
break;
}
}
if(0==flag)
{
return TRUE;
}
else
{
return ERROR;
}
}
Status InitStack(SqStack *s)
{
if(!(s->base=(Block*)malloc(m->height*m->width*sizeof(Block))))
{
exit(OVERFLOW);
}
s->top=s->base;
s->stacksize=m->height*m->width;
return TRUE;
}
Status Push(SqStack *s,Block foot)
{
*(s->top++)=foot;
return TRUE;
}
Status Pop(SqStack *s,Block *foot)
{
if(s->base==s->top)
{
return ERROR;
}
*foot=*(--s->top);
}
Status InitMap(maze *m)
{
printf("输入地图的长:");
do
{
scanf("%d",&m->height);
if(m->height<=0)
{
printf("输入无效,重新输入有效数据.\n");
printf("输入地图的长:");
}
}while(m->height<=0);
printf("输入地图的宽:");
do
{
scanf("%d",&m->width);
if(m->width<=0)
{
printf("输入无效,重新输入有效数据.\n");
printf("输入地图的宽:");
}
}while(m->width<=0);
if(!(m->wall=(seat*)malloc(m->height*m->width*sizeof(seat))))
{
exit(OVERFLOW);
}
return TRUE;
}
int VisitMap(maze *m,int x,int y)
{
int i=0;
for(;i<m->height*m->width;i++)
{
if(x==m->wall[i].x&&y==m->wall[i].y)
{
return i;
}
}
return -1;
}
void CreatInerfaceMap(maze *m)
{
int i=0;
for(;i<m->height*m->width;i++)
{
if(0==m->wall[i].attribute)
{
printf("□");
}
else
{
printf("■");
}
if(0==(i+1)%m->height)
{
printf("\n");
}
}
}
void NextStep(Block *foot,int id)
{
switch(id)
{
case 1:foot->NowPosition.x++;break;
case 2:foot->NowPosition.y++;break;
case 3:foot->NowPosition.x--;break;
case 4:foot->NowPosition.y--;break;
}
}
int JudgeThrough(maze *m,Block foot)
{
int i;
if(-1!=(i=VisitMap(m,foot.NowPosition.x,foot.NowPosition.y)))
{
if(0==m->wall[i].attribute)
{
return TRUE;
}
else
{
return ERROR;
}
}
return ERROR;
}
void CreatDigitalMap(maze *m)
{
int i,j=0,k=0,x,y;
InitMap(m);
for(i=0;i<m->height*m->width;i++)
{
m->wall[i].y=j++;
m->wall[i].x=k;
m->wall[i].attribute=0;
if(0==j%m->height)
{
j=0;
k++;
}
}
printf("请输入墙壁的坐标,以(-1,-1)的格式结束\n");
do
{
do
{
printf("墙壁坐标输入(0<=x<=%d,0<=y<=%d):",m->height-1,m->width-1);
scanf("%d%d",&x,&y);
if((x<0||x>m->height-1)&&(y<0||y>m->width-1)&&(-1!=x&&-1!=y))
{
printf("输入有误,超过地图界限,请重新输入坐标.\n");
}
}while((x<0||x>m->height-1)&&(y<0||y>m->width-1)&&(-1!=x&&-1!=y));
if(-1!=(i=VisitMap(m,x,y)))
{
m->wall[i].attribute=1;
}
}while(-1!=x&&-1!=y);
}
void MakeThroughSign(maze *m,Block foot)
{
int i;
if(-1!=(i=VisitMap(m,foot.NowPosition.x,foot.NowPosition.y)))
{
m->wall[i].attribute=2;
}
}
void MakeNoThroughSign(maze *m,Block foot)
{
int i;
if(-1!=(i=VisitMap(m,foot.NowPosition.x,foot.NowPosition.y)))
{
m->wall[i].attribute=3;
}
}
void InputAddStartAndEnd(seat *start,seat *end)
{
int i;
printf("输入入口地址(0<=x<=%d,0<=y<=%d):",m->height-1,m->width-1);
do
{
scanf("%d%d",&start->x,&start->y);
if((start->x<0||start->x>m->height-1)&&(start->y<0||start->y>m->width-1))
{
printf("输入有误,超过地图界限,请重新输入坐标.\n");
printf("输入入口地址(0<=x<=%d,0<=y<=%d):",m->height-1,m->width-1);
}
if(-1!=(i=(VisitMap(m,start->x,start->y))))
{
if(1==m->wall[i].attribute)
{
printf("该入口地址已经为墙壁,请重新输入起始坐标.\n");
printf("输入入口地址(0<=x<=%d,0<=y<=%d):",m->height-1,m->width-1);
}
}
}while((start->x<0||start->x>m->height-1)&&(start->y<0||start->y>m->width-1)&&1==m->wall[i].attribute);
printf("输入出口地址(0<=x<=%d,0<=y<=%d):",m->height-1,m->width-1);
do
{
scanf("%d%d",&end->x,&end->y);
if((end->x<0||end->x>m->height-1)&&(end->y<0||end->y>m->width-1))
{
printf("输入有误,超过地图界限,请重新输入坐标.\n");
printf("输入出口地址(0<=x<=%d,0<=y<=%d):",m->height-1,m->width-1);
}
if(end->x==start->x&&end->y==start->y)
{
printf("入口地址和出口地址重合,请重新输入坐标.\n");
printf("输入出口地址(0<=x<=%d,0<=y<=%d):",m->height-1,m->width-1);
}
if(-1!=(i=(VisitMap(m,end->x,end->y))))
{
if(1==m->wall[i].attribute)
{
printf("该出口地址已经为墙壁,请重新输入起始坐标.\n");
printf("输入出口地址(0<=x<=%d,0<=y<=%d):",m->height-1,m->width-1);
}
}
}while((start->x<0||start->x>m->height-1)&&(start->y<0||start->y>m->width-1)&&1==m->wall[i].attribute&&(end->x==start->x&&end->y==start->y));
}
void CreatInerfaceMapAgain(maze *m)
{
int i=0;
for(;i<m->height*m->width;i++)
{
if(1==m->wall[i].attribute)
{
printf("■");
}
else if(2==m->wall[i].attribute)
{
printf("⊙");
}
else
{
printf("□");
}
if(0==(i+1)%m->height)
{
printf("\n");
}
}
}