C++设计一个迷宫出来。
堆栈节点类型的描述:
结构堆栈节点
{
点点;
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();
这样,计时器就可以用来演示走迷宫的过程。