经典推箱子子求解

在本节中,我们谈论的闭合曲线充满,为什么这件事情
当一个场景,当我们递归,我们推标箱,假设没有推箱子。然后跑到哪里都白跑。最好是反复出现歧视坐标都是一样的
这些坐标被反转包含(同样的排序结果)。工的位置(求解算法部分再具体说)
因为场景有多个箱子,每一个箱子能够有几个方向移动。重复的寻路效率不高。起初我想删除路径部分,仅仅检測是否能移动到目标
来提升运行效率,就是偷懒一下,然后想想既然是礼物,偷懒也不是分时候,也有脸献给别人于是废弃了A×算法
目的就非常明显了。标定全部能到达的位置。检測的时候就不用寻他妹的路了,直接检測是否被填充就可以
那么怎样填充一个闭合的曲线呢?最简单的逻辑是:
1.往周围4个或8个方向,记录全部不是边界。没被填充的点并填充
2.递归这些点,直到没有新的点被检測到
递归,又是递归。这是自交么?罪过啊!万恶的递归,可怜的堆栈……
上面的方法实现非常easy,只是有非常多点会被重复检測若干次,效率并不太高
第二种方法就是我们要说的:扫描线种子填充算法
主要逻辑思想是:
1.把坐标换成线段,记录最左和最右断点。填充线段,增加队列(取代递归)
2.填充最先增加队列的线段,检查上一行和下一行,把相邻的线段都加进来,从队列中删除
3.反复1-2直到队列没有不论什么线段
演示样例源码,详情见资源
// 扫描线填充(用循环代替递归, 玩家必须在边界封闭的曲线内)
int fnStageScan(PQUEUE pQueue, PSTAGE pStage)
UINT x0, xl, xr, y0,
UINT //, c
UINT X, Y;
// 首先清零非类型位
Y = pStage-&SizeX * pStage-&SizeY;
X = Y % 4;
pNum = pStage-&M
while(X--)
*pNum++ &= SMT_FILTER; // 清零非类型信息
while(Y--)
*pData++ &= SMT_MATRIX; // 清零非类型信息
// 清空堆栈, 种子入栈
s = pQueue-&S
p-&X = pStage-&PosX;
p-&Y = pStage-&PosY;
s-&Count = 1;
while(s-&Count)
s-&Count--;
pNum = &pStage-&Matrix[Y * pStage-&SizeX + X];
*pNum |= SMT_OPENED; // Me.PSet (x0, Y), newvalue
x0 = X + 1;
// 填充右边不是箱子也不是边界的单元
while((*pNum & SMT_MASKED) == 0) // Me.Point(x0, Y) && boundaryvalue
//if(x0 &= pStage-&SizeX) // 到最右边(地图控制)
*pNum |= SMT_OPENED;
xr = x0 - 1; // 最右坐标
x0 = X - 1;
pNum = &pStage-&Matrix[Y * pStage-&SizeX + x0];
// 填充左边不是箱子也不是边界的单元
while((*pNum & SMT_MASKED) == 0) // Me.Point(x0, Y) && boundaryvalue
//if(x0 & 0) // 到最左边(地图控制)
*pNum |= SMT_OPENED;
xl = x0 + 1; // 最左象素
// 检查上一条扫描线和下一条扫描线。若存在非边界且未填充的象素。则选代替表各连续区间的种子象素入栈。
for(i = 1; i &= -1; i -= 2)
while(x0 &= xl)
flag = 0; // 向左传递未填充的点直到边界, 记录最后一个点的X坐标
pNum = &pStage-&Matrix[Y * pStage-&SizeX + x0];
// c = Me.Point(x0, Y)
//while(((*pNum & SMT_MASKED) == 0) && ((*pNum & SMT_OPENED) == 0) && (x0 &= xl))
while(((*pNum & SMT_OPNMSK) == 0) && (x0 &= xl))
// (c && boundaryvalue) And (c && newvalue) And (x0 &= xl)
if(flag == 0)
pNum--; // c = Me.Point(x0, Y)
// 将最右側可填充象素压入栈中
if(flag == 1)
s-&Count++; // s.push(Point(xid,y));
// 检查当前填充行是否被中断。若被中断,寻找左方第一个可填充象素
pNum = &pStage-&Matrix[Y * pStage-&SizeX + x0];
// c = Me.Point(x0, Y)
while(*pNum & SMT_OPNMSK)
// (c = boundaryvalue) Or (c = newvalue) '推断当前点是否为边界或箱子 或 推断当前点是否为已填充点
if(x0 == 0) // 到最左边(...)
x0--; // 若当前点为边界点或已填充点。依据前面的推断,当前点必定未超出左边界。则当前点向左移动
} // loop while(x0 &= xl)
} // next for(i = 1; i &= -1; i -= 2)
} // loop while(!s.isempty())
为了存储空间,我仅仅填充特定标志位,队列固定大小,结构更加紧凑,測试运行效果:
<img src="http://img.blog.csdn.net/06243?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJzbmlwZXI=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
左边画线的端点。一个充满完全随机的内右键点击一个封闭的曲线上的点。请参阅资源工具包。
版权声明:本文博客原创文章,博客,未经同意,不得转载。
阅读(...) 评论()扫二维码下载作业帮
拍照搜题,秒出答案,一键查看所有搜题记录
下载作业帮安装包
扫二维码下载作业帮
拍照搜题,秒出答案,一键查看所有搜题记录
求下图推箱子解法如下图
ggWB81UL09
扫二维码下载作业帮
拍照搜题,秒出答案,一键查看所有搜题记录
左右下上上右上右下下下左下左左上左上上右右右左下下右右上上左左下左右右
为您推荐:
其他类似问题
扫描下载二维码当前【全部】
全部安卓手机安卓平板安卓电视iPhoneiPad其他
当前位置:>>>经典推箱子
经典推箱子类型:
热门排行榜
9000万+人在玩9000万+人在玩500万+人在玩100万+人在玩10万+人在玩500万+人在玩
经典推箱子app相关推荐
发现该应用有下载安装使用错误或恶意扣费携带病毒,请
版权所有 京ICP备号-5
京公网安备 50 备推箱子问题的设计与实现_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
推箱子问题的设计与实现
上传于|0|0|暂无简介
阅读已结束,如果下载本文需要使用1下载券
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,查找使用更方便
还剩2页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢}

我要回帖

更多关于 推箱子自动求解 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信