写这个程序的原因是在某论坛上看到一个据称走出了这个迷宫就能让“i服了u”的帖子,迷宫如图:

这个图片是gif格式的文件,所以像素比较清晰,便于用程序读点,所以开始考虑用程序写出这个迷宫算法。
在书写本程序时参考了vc知识库的相关文章(http://www.vckbase.com/document/viewdoc/?id=1219),在此表示感谢。
本程序的前提是将迷宫保存在一个二维数组里,可走的地方为0,不可走的地方为1。由于采用回朔算法,不使用递归,所以首先应该建立一个栈来保存路径,路径是用一个一个点来表示的,也就是说栈中保存的是一系列点的列表。
栈节点类型说明:
struct stacknode
{
point point;
struct stacknode *next, *prev;//双向链表形式
};
栈结构用一个类(cpointstack)实现,声明如下:
class cpointstack
{
public:
void clearstack();//清空栈
void initstack();//初始化栈
bool pop(point &pt);//弹出顶端元素,并给出该点的坐标,返回是否弹出成功
bool push(point pt);//将pt点的信息压入栈,返回是否压入成功
cpointstack();
virtual ~cpointstack();
protected:
stacknode *m_psntop;//栈顶指针
stacknode m_snbottom;//栈底,不保存点信息
};
以下为成员函数实现,都是一些数据结构的操作,应该没什么好说的:
//构造时初始化栈
cpointstack::cpointstack()
{
initstack();
}
//析构时清空栈
cpointstack::~cpointstack()
{
clearstack();
}
//将点压入栈(成功返回true,失败返回false)
bool cpointstack::push(point pt)
{
stacknode* newnode = new stacknode;
//是否返回true主要看这里申请内存是否成功
if(!newnode)
return false;
newnode->point = pt;
newnode->prev = m_psntop;
newnode->next = null;
m_psntop->next = newnode;
m_psntop = newnode;
return true;
}
//将点弹出栈(成功返回true,栈为空则返回false)
bool cpointstack::pop(point &pt)
{
if(m_psntop == &m_snbottom)//是否返回true主要看这里栈是否为空
return false;
stacknode *p;
p = m_psntop;
m_psntop = m_psntop->prev;
pt = p->point;
delete p;
m_psntop->next = null;
return true;
}
//初始化栈
void cpointstack::initstack()
{
m_psntop = &m_snbottom;
m_snbottom.next = null;
m_snbottom.prev = null;
}
//清空栈
void cpointstack::clearstack()
{
stacknode *p;
while(m_psntop != &m_snbottom)
{
p = m_psntop;
m_psntop = m_psntop->prev;
delete p;
}
}
接下来设计怎样走出这个迷宫,也就是迷宫算法的主体部分。再次用一个类实现。
在设计这个类时,我考虑到以下几点:
1、迷宫入口和出口的坐标
2、保存迷宫的2维数组
3、获得路径的函数
但是实际设计时由于没有考虑太多问题,只是以设计迷宫算法和解决一个具体迷宫为目的,所以没有考虑动态大小的迷宫,而是将迷宫大小定为601×401。而且在设计迷宫算法后没有将路径顺序输出而是直接在原图中标识(在保存迷宫数据的表中设置经过的点为2而将死路点设置为3)。
这样迷宫类(cgomaze)的声明为:
class cgomaze
{
public:
void go();//寻找路径的函数
point m_ptin;//入口坐标
point m_ptout;//出口坐标
byte m_btarrmaze[401][601];//保存迷宫的二维表
cgomaze();
virtual ~cgomaze();
};
最后让我们来看一下cgomaze::go()这个函数:
我们模仿人走迷宫时的思路,设置一个当前点,一个目标点(下一个要走的点)。初始情况下当前点为入口,终止条件为当前点为出口,这样,我们的函数大概结构就出来了。