修改后的迷宫算法(原版为http://blog.csdn.net/sunshinedabby/article/details/6284779)

// maze.cpp : 定义控制台应用程序的入口点。
//
#include<stdafx.h>
#include<iostream>

using namespace std;
struct PosType//迷宫坐标位置类型
{
int x;//行值
int y;//列值
};
#define MAXLENGTH 100 //设迷宫的最大行列为25
typedef int Mazetype[MAXLENGTH][MAXLENGTH];//迷宫数组
//全局变量
Mazetype m;//迷宫数组
int curstep = 1;//当前足迹,初值为1;
//int a[MAXLENGTH];
//int b[MAXLENGTH];
//int c[MAXLENGTH];
struct SElemType//栈的元素类型
{
int ord;//通道块在路径上的”序号“
PosType seat;//通道块在迷宫中的“坐标位置”
int di;//从此通道块走向下一通道块的方向(0~3表示东~北)
};
#define STACK_INIT_SIZE 10//储存空间初始分配量
#define STACKINCREMENT 2//存储空间分配增量
struct SqStack
{
SElemType *base;//在栈构造之前和销毁之后,base的值为null
SElemType *top;//栈顶指针
int stacksize;//当前已分配的存储空间,以元素为单位
};//顺序栈
bool Pass(PosType b)
{
//当迷宫m的b点的序号为1(可通路径),return true,否则return false
if (m[b.x][b.y] == 1)
{
return true;
}
else
return false;
}
void FootPrint(PosType a)
{
//使迷宫m的a点序号变为足迹(curstep)
m[a.x][a.y] = curstep;
}
PosType NextPos(PosType c, int di)
{
//根据当前位置及移动方向,返回下一位置
PosType direc[4] = { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } }; /* {行增量,列增量} */
//移动方向依次为东南西北
c.x += direc[di].x;
c.y += direc[di].y;
return c;
}
void MarkPrint(PosType b)
{
//使迷宫m的b点的序号变为-1(不能通过的路径)
m[b.x][b.y] = -1;
}
bool InitStack(SqStack *S)
{
//构造一个空栈S
(*S).base = (SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if (!(*S).base)
{
exit(1);//存储分配失败
}
(*S).top = (*S).base;
(*S).stacksize = STACK_INIT_SIZE;
return true;
}
bool Push(SqStack *S, SElemType e)
{
//插入元素e为新的栈顶元素
if ((*S).top - (*S).base >= (*S).stacksize)//栈满,追加存储空间
{
(*S).base = (SElemType *)realloc((*S).base, ((*S).stacksize + STACKINCREMENT)*sizeof(SElemType));
if (!(*S).base)
{
exit(1);
}
(*S).top = (*S).base + (*S).stacksize;
(*S).stacksize += STACKINCREMENT;
}
*((*S).top)++ = e; // 指针加1,指向新元素e
return true;
}
bool StackEmpty(SqStack S)
{
if (S.top == S.base)
return true;
else
return false;
}
bool Pop(SqStack *S, SElemType *e)
{
//若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK,否则返回Error
if ((*S).top == (*S).base)
return false;
*e = *--(*S).top;
return true;
}
bool MazePath(PosType start, PosType end) /* 算法3.3 */
{ /* 若迷宫maze中存在从入口start到出口end的通道,则求得一条 */
/* 存放在栈中(从栈底到栈顶),并返回TRUE;否则返回FALSE */
SqStack S;
PosType curpos;
SElemType e;
InitStack(&S);
curpos = start;
do
{
if (Pass(curpos))
{ /* 当前位置可以通过,即是未曾走到过的通道块 */
FootPrint(curpos); /* 留下足迹 */
e.ord = curstep;
/*a[curstep] = e.seat.x = curpos.x;
b[curstep] = e.seat.y = curpos.y;
c[curstep] = e.di = 0;*/
e.seat.x = curpos.x;
e.seat.y = curpos.y;
e.di = 0;
Push(&S, e); /* 入栈当前位置及状态 */
curstep++; /* 足迹加1 */
if (curpos.x == end.x&&curpos.y == end.y) /* 到达终点(出口) */
return true;
curpos = NextPos(curpos, e.di);
}
else
{ /* 当前位置不能通过 */
if (!StackEmpty(S))
{
//Pop(&S, &e); /* 退栈到前一位置 */
//curstep--;
if ((e.di == 3) && (!StackEmpty(S))) /* 前一位置处于最后一个方向(北) */
{
MarkPrint(e.seat); /* 留下不能通过的标记(-1) */
Pop(&S, &e); /* 退回一步 */
curpos.x = e.seat.x;
curpos.y = e.seat.y;
curstep--;
}
if (e.di < 3) /* 没到最后一个方向(北) */
{
e.di++; /* 换下一个方向探索 */
Push(&S, e);
/*    a[curstep] = e.seat.x = curpos.x;
b[curstep] = e.seat.y = curpos.y;
c[curstep] = e.di;*/
e.seat.x = curpos.x;
e.seat.y = curpos.y;
e.di;
curstep++;
curpos = NextPos(e.seat, e.di); /* 设定当前位置是该新方向上的相邻块 */
}
}
}
} while (!StackEmpty(S));
return false;
}

void Print(int x, int y)
{ /* 输出迷宫的解 */
int i, j;
for (i = 0; i < x; i++)
{
for (j = 0; j < y; j++)
cout << " " << m[i][j];
cout << endl;
}
}
void test()
{
PosType begin, end;
int i, j, x, y, x1, y1, xxx;
cout << "请输入迷宫的行数,列数(包括外墙):";
cin >> x >> y;
for (i = 0; i < x; i++) /* 定义周边值为0(同墙) */
{
m[0][i] = 0; /* 行周边 */
m[x - 1][i] = 0;
}
for (j = 1; j < y - 1; j++)
{
m[j][0] = 0; /* 列周边 */
m[j][y - 1] = 0;
}
for (i = 1; i < x - 1; i++)
for (j = 1; j < y - 1; j++)
m[i][j] = 1; /* 定义通道初值为1 */
cout << "迷宫结构如下:" << endl;
Print(x, y);
cout << "请输入迷宫内墙单元数:";
cin >> j;
cout << "请依次输入迷宫内墙每个单元的行数,列数:" << endl;
for (i = 1; i <= j; i++)
{
cin >> x1 >> y1;
m[x1][y1] = 0; /* 定义墙的值为0 */
}
cout << "迷宫结构如下:" << endl;
Print(x, y);
cout << "请输入起点的行数,列数:";
cin >> begin.x >> begin.y;
cout << "请输入终点的行数,列数:";
cin >> end.x >> end.y;
if (MazePath(begin, end)) /* 求得一条通路 */
{
cout << "此迷宫从入口到出口的一条路径如下:" << endl;
Print(x, y); /* 输出此通路 */

/*for (i = 1; i<curstep; i++)
cout << a[i] << " " << b[i] << " " << c[i] << endl;*/
}
else
{
cout << "此迷宫没有从入口到出口的路径" << endl;
}


cin >> xxx;
}
void main()
{
test();
}

 

posted on 2014-12-24 00:17  编程007  阅读(334)  评论(0编辑  收藏  举报