/********************************************************************
经典迷宫算法
迷宫值的含义:
1---表示可以占据
0---障碍物
2---已走过该位置
------------------------------------------->y
| 寻路顺序图
| |
| |3:x-1
| |
| 4:y-1 <--------------------->2:y+1
| |
| | 1:x+1
| |
|
x
寻找到一个位置后按照方向1,2,3,4的顺序进行探索。
********************************************************************/
#include
#include "string.h"
using namespace std;
#define MAZESIZE 50
/*表示位置的结构体*/
typedef struct {
int x, y, dir;//dir - 表示此位置下一步将要探索的方向
}pos;
/*栈信息存储,此栈为增地址*/
typedef struct {
pos** base;//栈中存放的是pos位置的指针,栈底
pos** top;//栈顶指向栈顶元素的下一个位置
int size;//栈的容量
}stack;
/*栈初始化函数*/
void Init(stack* s, int size)
{
if (size <= 0)return;
else
{
s->base = (pos**)malloc(size*sizeof(pos*));
if (s->base == NULL)
{
cout << "Init stack failed!" << endl;
exit(-1);
}
s->size = size;
s->top = s->base;
cout << "分配了" << size << "*" << sizeof(pos*) << "字节空间" << endl;
}
}
/*判断栈是否为空*/
bool IsEmpty(stack* s)
{
if (s == NULL || s->base == s->top)return true;
else
{
return false;
}
}
/*元素入栈*/
void push(stack* s, pos* position)
{
//如果栈满再扩充10个元素的空间
if (s->top-s->base==s->size)
{
//分配十个指向pos的指针数组
s->base = (pos**)realloc(s->base, (s->size + 10) + sizeof(pos*));
if (s->base == NULL)
{
cout << "push failed " << endl;
exit(-1);
}
s->top = s->base + s->size;
s->size += 10;
cout << "重新分配了" << s->size + 10 << "*" << sizeof(pos*) << "字节空间" << endl;
}
*s->top = position;
s->top++;
cout << "位置[" << position ->x<<","<y<< "]入栈" << endl;
}
/*元素出栈*/
void pop(stack* s)
{
if (IsEmpty(s) == true)
{
cout << "empty stack! " << endl;
}
else
{
cout << "位置[" << (*(s->top-1))->x << "," << (*(s->top-1))->y << "]出栈" << endl;
s->top--;
delete *(s->top);//某元素出栈,则要释放内存空间
}
}
int getStep(stack*s)
{
return (s->top - s->base);
}
pos* getStackTopPos(stack*s)
{
cout << "获取栈顶位置[" << (*(s->top - 1))->x << "," << (*(s->top - 1))->y << "]" << endl;
return *(s->top - 1);
}
/*判断当前位置是否可以占据*/
bool IsPassPos(pos* position, int maze[][8])
{
if (maze[position->x][position->y] != 0 && maze[position->x][position->y] != 2)
{
return true;
}
else
{
return false;
}
}
/*根据当前位置寻找下一个位置*/
int findNextPos(pos* curpos,int maze[][8])
{
if (curpos == NULL)
{
cout << "pos error" << endl;
exit(-1);
}
else
{
//根据当前位置欲探索的方向,代表方向的数字值是一直增加的,
//一旦找出一个可行的方向立即返回
for (int i = curpos->dir; i < 5; i++)
{
switch (i)
{
case 1:
if (curpos->x + 1 < 8 && maze[curpos->x + 1][curpos->y] != 0 && maze[curpos->x + 1][curpos->y] != 2)
{
return 1;
}
case 2:
if (curpos->y + 1 < 8 && maze[curpos->x][curpos->y + 1] != 0 && maze[curpos->x][curpos->y + 1] != 2)
{
return 2;
}
case 3:
if (curpos->x - 1 >= 0 && maze[curpos->x - 1][curpos->y] != 0 && maze[curpos->x - 1][curpos->y] != 2)
{
return 3;
}
case 4:
if (curpos->y - 1 >= 0 && maze[curpos->x][curpos->y - 1] != 0 && maze[curpos->x][curpos->y - 1] != 2)
{
return 4;
}
default:
continue;
}
}
}
return 0;//表示没有下一个位置
}
/*核心寻路算法*/
bool searchPath(pos* curpos, pos* end, stack*s, int maze[][8])
{
if (curpos->dir<5 && curpos->dir>0)//判断当前方向是否合法
{
cout << "寻路方向-->" << curpos->dir << endl;
push(s, curpos);//当前位置入栈
maze[curpos->x][curpos->y] = 2;//当前位置留下足迹
if (curpos->x == end->x && curpos->y == end->y)//此位置是终点
{
cout << "find path step:"<< endl;
//打印路径
for (pos **p = s->base; p != s->top-1; ++p)
{
cout << "[" << (*p)->x << "," << (*p)->y << "]" << "->";
}
cout << "[" << (*(s->top - 1))->x << "," << (*(s->top - 1))->y << "]" << endl;
return true;
}
//获取下一个位置
else
{
int dir=findNextPos(curpos, maze);//获取下一个可以探索的方向
pos *next=new pos;//为下一个位置分配存储空间。
switch (dir)
{
case 0: //说明没有下一个位置
maze[curpos->x][curpos->y] = 1;//清除足迹
pop(s);//当前位置退栈
memcpy(next, getStackTopPos(s),sizeof(pos));
next->dir += 1;//方向加一
//cout << "[" << next->x << "," << next->y << "," << next->dir << "]" << endl;
pop(s);//栈顶元素再退栈
break;
case 1: next->x = curpos->x + 1;
next->y = curpos->y;
next->dir = 1;
break;
case 2: next->x = curpos->x;
next->y = curpos->y + 1;
next->dir = 1;
break;
case 3: next->x = curpos->x - 1;
next->y = curpos->y;
next->dir = 1;
break;
case 4: next->x = curpos->x;
next->y = curpos->y - 1;
next->dir = 1;
break;
default:
break;
}
searchPath(next, end, s, maze);
}
}
else //没有下一个位置,curpos->dir > 5,表示当前位置不合法
{
pos *next=new pos;
memcpy(next, getStackTopPos(s), sizeof(pos));
next->dir += 1;//方向加一
pop(s);//当前位置退栈
searchPath(next, end, s, maze);
}
}
int main(int argc,char* argv[])
{
/*迷宫数据*/
int maze[8][8] =
{
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 1, 0, 0, 1, 0, 0 },
{ 0, 0, 1, 1, 1, 0, 1, 0 },
{ 0, 0, 1, 0, 1, 0, 0, 0 },
{ 0, 0, 0, 1, 1, 0, 1, 0 },
{ 0, 0, 0, 1, 0, 0, 1, 0 },
{ 0, 0, 0, 1, 1, 1, 1, 0 },
{ 0, 0, 0, 0, 1, 0, 0, 0 }
};
stack *s=new stack();//存储栈信息,只有一个实例
pos* start = new pos();//起点
start->x = 1;
start->y = 2;
start->dir = 1;
pos* end = new pos();//终点
end->x = 4;
end->y = 6;
end->dir = 0;
cout << "起点位置:[" << start->x << "," << start->y << "]" << endl;
cout << "终点位置:[" << end->x << "," << end->y << "]" << endl;
Init(s, MAZESIZE);//初始化栈
searchPath(start, end, s, maze);//寻路
delete s;
delete start;
delete end;
}