C++设计一个迷宫出来。

这个程序的前提是将迷宫保存在一个二维数组中,其中行走的地方为0,非行走的地方为1。因为采用的是递归算法而不是递归,所以要建立一个栈来保存路径,路径用一个点来表示,也就是说栈中保存了一个点的列表。

堆栈节点类型的描述:

结构堆栈节点

{

点点;

struct StackNode *Next,* Prev//链接列表表单

};

堆栈结构由一个类(CPointStack)实现,声明如下:

类CPointStack

{

公共:

void clear stack();//清空堆栈

void init stack();//初始化堆栈

布尔流行(点& amppt);//弹出顶部元素,给出该点坐标,返回弹出是否成功。

布尔推(点pt);//将pt点的信息压入堆栈,并返回压入是否成功。

CPointStack();

virtual ~ CPointStack();

受保护:

StackNode * m _ psnTop//栈顶指针

StackNode m _ snBottom//在堆栈底部,点信息没有保存。

};

以下是成员函数的实现,都是数据结构操作,应该没什么好说的:

//在构造时初始化堆栈

CPointStack::CPointStack()

{

init stack();

}

//析构时清空堆栈

CPointStack::~CPointStack()

{

clear stack();

}

//将指针推送到堆栈上(成功时返回true,失败时返回false)

bool CPointStack::Push(点pt)

{

stack node * new node = new stack node;

//是否返回true主要看这里对内存的申请是否成功。

如果(!新节点)

返回false

新节点-& gt;Point = pt

新节点-& gt;Prev = m _ psnTop

新节点-& gt;Next = NULL

m _ psn top-& gt;Next = NewNode

m _ psnTop = NewNode

返回true

}

//将该点弹出堆栈(如果成功,则返回true,如果堆栈为空,则返回false)

Pop(POINT & amp;pt)

{

if(m _ psn top = = & amp;M_snBottom)//是否返回true主要看这里的栈是否为空。

返回false

stack node * p;

p = m _ psnTop

m _ psn top = m _ psn top-& gt;Prev

pt = p-& gt;点;

删除p;

m _ psn top-& gt;Next = NULL

返回true

}

//初始化堆栈

void CPointStack::InitStack()

{

m _ psnTop = & ampm _ snBottom

m_snBottom。Next = NULL

m_snBottom。Prev = NULL

}

//清空堆栈

void CPointStack::ClearStack()

{

stack node * p;

while(m_psnTop!= & ampm_snBottom)

{

p = m _ psnTop

m _ psn top = m _ psn top-& gt;Prev

删除p;

}

}

然后设计如何走出这个迷宫,这是迷宫算法的主要部分。同样,它是用一个类实现的。

在设计这个类时,我考虑了以下几点:

1,迷宫出入口坐标

2.保存迷宫的二维数组。

3.获取路径的功能

但在实际设计中,因为没有考虑太多问题,只设计了迷宫算法,解决了一个特定的迷宫,所以没有考虑动态迷宫,而是将迷宫大小设置为601×401。而且设计迷宫算法后,路径不是按顺序输出,而是直接在原始图像中识别(在存储迷宫数据的表中,通过点设置为2,死端点设置为3)。

这种CGoMaze的陈述是:

CGoMaze类

{

公共:

void Go();//函数查找路径

点m _ ptIn//入口坐标

点m _ ptOut//导出坐标

BYTE m _ btArrMaze[401][601];//保存迷宫的二维表。

CGO maze();

虚拟~ CGO maze();

};

最后,我们来看看CGoMaze::Go()函数:

我们在走迷宫时模仿人的思维,设定一个当前点和一个目标点(下一个要走的点)。在初始情况下,当前点是入口,终止条件是当前点是出口,这样我们函数的近似结构就出来了。

从入口到出口的过程中,程序依次判断当前点的上、下、左、右四点。当发现任何一个方向是未探索的区域时,就试图将当前点指向该点,同时将当前点放入堆栈并标记。当四个方向都被阻挡或已经通过时,就是一个死胡同,将当前点标记为死胡同并从栈中弹出最后一个点继续尝试。此时由于当前点已经被标记为死胡同,所以在弹出最后一点时不会重复这条路径,从而找到正确的路径。

Go函数的具体实现如下,其实挺简单的_:

void CGoMaze::Go()

{

CPointStack psPath//保存路径堆栈

POINT ptCur = m_ptIn,ptNext//将当前点设置为入口

while(ptCur.x!= m_ptOut.x || ptCur.y!= m_ptOut.y)//判断自己是否走出去了。

{

ptNext = ptCur//将目标点设置为当前点,便于后续偏移。

if(m _ btArrMaze[pt cur . y-1][pt cur . x]= = 0)

pt next . y-;//如果顶部为空,则目标点向上偏移。

else if(m _ btArrMaze[pt cur . y][pt cur . x-1]= = 0)

pt next . x-;//如果左侧为空,则目标点向左偏移。

else if(m _ btArrMaze[pt cur . y+1][pt cur . x]= = 0)

pt next . y++;//如果底部为空,则目标点向下偏移。

else if(m _ btArrMaze[pt cur . y][pt cur . x+1]= = 0)

pt next . x++;//如果右侧为空,则目标点向右偏移。

其他

{//这里没有路。

m _ btArrMaze[pt cur . y][pt cur . x]= 3;//标记为死胡同

psPath。pop(pt cur);//弹出最后一点。

继续;//继续循环

}

//如果有办法,就在这里执行。

m _ btArrMaze[pt cur . y][pt cur . x]= 2;//将当前点标记为路径上的一个点。

psPath。push(pt cur);//将当前点推入堆栈。

ptCur = ptNext//移动当前点

}

}

实际上,这部分可以将堆栈设置为CGoMaze类的成员,然后添加:

psPath。clear stack();

这样,计时器就可以用来演示走迷宫的过程。