问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

C++设计一个迷宫并走出来11

发布网友 发布时间:2023-10-20 05:36

我来回答

3个回答

热心网友 时间:2024-12-02 21:59

本程序的前提是将迷宫保存在一个二维数组里,可走的地方为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()这个函数:
我们模仿人走迷宫时的思路,设置一个当前点,一个目标点(下一个要走的点)。初始情况下当前点为入口,终止条件为当前点为出口,这样,我们的函数大概结构就出来了。
在从入口到出口的过程中程序对当前点的上、下、左、右四个点依次进行判断,当发现任一个方向是未走过的区域时,就将当前点指向那个点进行尝试,同时将当前点入栈并做标记。而当4个方向都不通或已走过时,则为死路,标记当前点为死路并从栈中弹出上一个点继续进行尝试,这时因为当前点已被标记为死路,则弹出上一个点时就不会重复这条路,达到寻找正确路径的效果。
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[ptCur.y - 1][ptCur.x] == 0)
ptNext.y --;//如果上方是空的,则目标点向上偏移
else if(m_btArrMaze[ptCur.y][ptCur.x - 1] == 0)
ptNext.x --;//如果左边是空的,则目标点向左偏移
else if(m_btArrMaze[ptCur.y + 1][ptCur.x] == 0)
ptNext.y ++;//如果下方是空的,则目标点向下偏移
else if(m_btArrMaze[ptCur.y][ptCur.x + 1] == 0)
ptNext.x ++;//如果右边是空的,则目标点向右偏移
else
{//这里是没有路的状态
m_btArrMaze[ptCur.y][ptCur.x] = 3;//标记为死路
psPath.Pop(ptCur);//弹出上一次的点
continue;//继续循环
}
//如果有路的话会执行到这里
m_btArrMaze[ptCur.y][ptCur.x] = 2;//标记当前点为路径上的点
psPath.Push(ptCur);//当前点压入栈中
ptCur = ptNext;//移动当前点
}
}

其实这个部分可以将栈设置为CGoMaze类的成员,然后在Go函数里加上:
psPath.ClearStack();
这样就可以用Timer来演示走迷宫的过程了

热心网友 时间:2024-12-02 22:00

这么生成的迷宫有71.428571……种可能根本走不通。。。。。。。。。。汗……

热心网友 时间:2024-12-02 22:00

我记得严蔚敏版的《数据结构》这本书里面就有关于解迷宫的算法,你可以看看。
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
山外面包一个病旁是什么字 我的笔记本电脑显示电源的灯一直在绿色和橘红色之间闪烁,这是怎么回事... 笔记本电脑3个灯笔记本电脑这几个指示灯分别是啥意思 ...我的y470.第3个指示灯是橘红色的,开不了机,不知道怎么了?就开不了... QQ空间皮肤的代码是怎么放进去的啊. 为什么我在地址栏中输入皮肤代码按回车键,但一按空间就没有了 请教个问题哈~关于qq空间背景代码的,我在IE栏里输了代码,为啥每次弹出 ... win10删除多余的输入法 win10怎么删除多余的输入法 win10输入法怎么删除 win10输入法删除方法 如何做出爽口不腻、口味纯正的孟和尚粉肠? 对,有威胁 用英文怎么说2 电动汽车和汽油车开起来有什么不一样呢?3 中国十大品牌电动车是哪几个?1551 为什么电动汽车比一般汽车贵?368 求大神告知,华天动力协同OA系统的功能好不好?1 听上去有点危言耸听 用英语怎么说 组合美如玉的多肉拼盘,到底是怎么养的? 发出威胁言论 用英语怎么说谢谢 !!! 什么叫乳化作用113 关于电动车和汽车相撞,对方保险事故处理的流程89 发出威胁言论 用英语怎么说谢谢 红色电影观后感200字1804 蜻蜓少年电影观后感300字8 守信少年观后感400字101 用QQ登陆优酷,为什么网名变回了QQ账号的网名4 中老年人如何上网1 一千零一夜第26集,七七做的那个星空示爱柏海要答案的?现实中... 手机怎么下载老年网1 电信adsl 6M,到底网速是多少K? ...猫路由一体机。我现在从路由器里再拉了一条三十米的网线连接... 求豫菜、河南菜的经典菜谱49 一个人可以实名认证几个125 我一个卖给别人了但是解除实名认证了,那他以后用这个号做...87 自己的可以绑定别人的银行卡吗?167 别人名字实名的被封了,零钱能提出来吗?4 武汉艺海全鑫文化传媒有限公司怎么样? 我是业主,有一幢房屋想租给二手房东,怎么签租赁合同,最好能有... 微信群该二维码7天内(3月15日前)有效,重新进入将更新,是...34 恋爱期间淘宝代付的钱可以要回来吗?2 《见与不见》讲的是什么意思?180 恭维是什么意思?905 优酷用QQ登录上去的号不是原来的号,而是一个新开的号!!什么...3 优酷用QQ点了一下直接登录怎么就不是原先那个QQ号了,怎么改... 如何强制二次修改 帮帮忙,刚才漏发了2个句子。。翻译 今年最受欢迎的女装淘宝店是哪家 红红火火精品女装 恋爱鱼恋爱... 老年云课堂为什么打不开3 我的多肉拼盘里铺了一层火山石,然后今天晒了太阳☀... 以色列会和伊朗打仗吗?4 在长春哪里买电子狗好?1