推箱子游戏的算法或者说建模问题

KingSunshine 2012-10-04 03:48:25
考虑到国庆人多,所以没有出去,一直猫在家中。
这几天闲来无事,在玩手机上自带的小游戏--推箱子。

玩来玩去,总是有那么几关过不去,因此想是否能写个程序,自动计算出答案。
但考虑了很长时间,发觉问题不是那么简单。到现在为止,连如何建模都没有搞定。

其实,只要建模完成,剩下的事无非是递归、回溯就能解决了。

相信大多数同志都玩过这个游戏,其规则我就不写了。


游戏中涉及墙壁、推箱子的小人、个数不等的箱子、与箱子个数相等的球。
箱子移动过程中,要考虑人的位置。若人位于箱子的一边,被挡住了过不去的话,哪怕箱子那边是空档,你也无法向那个方向推动箱子。个人觉得这是与迷宫之类游戏的最大不同。

因此,建模过程中需要同时考虑人、箱子及其之间的相互关系。当然,墙壁和球也要考虑,但因为它们是固定不动了,相对简单。

但象这种多变量建模,还真没弄过。

另一方面,箱子和球都是没有编号的,任何箱子都能与任何球匹配。也就是说,箱子之间没有权重和优先级的区别,这一点有别于书上的八皇后问题和中国象棋,倒有点和围棋相似。



本人能力有限,敢问网上高手,有无解决方案?
...全文
660 3 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
icessl 2012-10-23
  • 打赏
  • 举报
回复
1) 用一个二维整型数组表示一个房间
2) 数组元素值各比特含义如下:
Bit0 表示是不是墙, 0 不是 1 是
Bit1 表示是不是箱子, 0 不是 1 是
Bit2 表示是不是目的地, 0 不是 1 是
3) 向量 <x,y,Room> 表示在 Room 中,人的位置是 [x,y]
4) 初始化 S={<x0,y0,Room0>}, 即 [x0,y0] 是人的初始位置,Room0 是初始房间格局
5) while S 不空
5.1) 从 S 取出一个元素,令它是 <x,y,Room>
5.2) for (i=1;i<=4;i++) // 1,2,3,4 表示推的4 个方向
{
if <x,y,Room> 可以在 i 方向上推一下 // 这个容易实现,略
{
令 <xx,yy,RRoom> 是推了一步之后的格局;
if <xx,yy,RRoom> 中所有箱子均到位 return 已完成;
if <xx,yy,RRoom> 不在 S 中 then S=S+{<xx,yy,RRoom>};
}
}
6) 返回:此题无解

为了能在最后输出推箱步骤,可在<x,y,Room>与<xx,yy,RRoom>之间用指针连接起来.
huangxy10 2012-10-04
  • 打赏
  • 举报
回复
在判断是否可达时,确实是一个走迷宫问题。
huangxy10 2012-10-04
  • 打赏
  • 举报
回复
一个二维矩阵表示地图,或者说是一种状态:
0:表示墙壁,小人不能通过
1:小人的位置
2:箱子
3:球 箱子的最终位置
4:空白 小人可以走的路

首先将游戏中的初始地图转换为上面的二维地图,得人工来转换了,对于你没有玩过去的关卡转换一下不难。

使用启发式搜索方法:

1,扩展结点的思路:
首先找的所有的箱子,再找该箱子某个附近是否小人能否到达(不需要最近距离,搜一下就行了),然后判定箱子能否推动,即小人和箱子的反方向是否可以放箱子,如果可以,那么这就是下一个可达状态。
根据初始位置,计算所有可达状态(即下一个可能的状态),将这些可能的状态放入队列中去。

2,如何启发式搜索
下面就是要从这些可达状态中找一个比较好的状态去扩展结点。
这需要评估这些状态中那个状态比较好,即启发式函数。可以计算每个状态中箱子的最少移动步数作为启发式函数,(计算最少移动步数时不用考虑小人的位置)。从可扩展状态中选出最好的状态,即最少移动步数最下的状态开始扩展。

3,结束
当有最少移动步数为0的状态出现,则搜索结束,输出搜索路径上的节点,即为解。

33,027

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧