PDDL规划:解决谓词名报错后出现击杀怪物位置异常
PDDL规划逻辑异常的核心原因与修正点
1. 核心逻辑硬伤:位移类动作未清除玩家原位置的状态
所有涉及玩家位置跳变的动作,效果部分都存在状态冗余遗漏:
Kill动作的效果仅添加了玩家在目标位置的playerat事实,未移除玩家出发位置的playerat,执行完击杀后玩家会同时存在于两个位置的状态。比如玩家在b房间击杀c房间的怪物后,系统会同时保留
playerat pl b和playerat pl c两个事实,后续规划器触发动作时会随机选取任意一个匹配的位置事实作为前置,这就是你看到“击杀后明明显示在c房间,下一个状态直接跳回b房间”的根本原因。FlyOverMonster、FlyOverTrap两个飞行动作存在完全相同的bug,同样没有在效果里清除玩家出发位置的playerat事实,进一步放大状态混乱的问题。
2. 动作参数的冗余设计导致规划器生成大量无意义实例
多个动作绑定了完全不参与前置判断、也不参与效果计算的冗余参数,大幅提高了规划器的状态搜索空间,容易出现无意义的路径选择:
Move动作强制绑定独立的怪物参数?M,仅用not(monsterat ?M ?B)判断目标位置安全——这个判断逻辑完全无效:只要地图上任意一个怪物不在目标位置,该条件就会满足,哪怕目标位置实际站着另一个怪物,Move动作也能触发。同时冗余的?M参数会让规划器把每个怪物都和移动动作绑定一遍,生成大量重复的无效动作实例。Kill动作的参数定义中额外绑定的?M、两个FlyOver动作中完全没用到的?F参数,均属于无意义冗余,会让规划器无差别绑定所有同类型对象生成动作,容易优先选择路径长度更短的无意义折返动作,而非符合逻辑的前进方向。
3. 隐性笔误带来的解析隐患
- 谓词定义中
treasureat的参数名拼写为?trasure,虽然不影响解析,但和其他动作中调用该谓词的参数逻辑对应时,容易出现隐性的参数错配问题。
修正方向
- 给所有位移类动作(Move、Kill、FlyOver系列)补全效果:跳转到新位置时,必须同时移除玩家原位置的
playerat事实,杜绝多位置共存的状态冗余。 - 移除所有不参与逻辑判断的冗余动作参数:Move动作去掉多余的
?M,把目标位置的安全判断改成直接检测目标位置是否存在怪物;FlyOver系列去掉完全没用到的?F参数,减少无意义的动作实例。 - 修正谓词定义中的参数拼写错误,保持全文档的命名一致性。
内容的提问来源于stack exchange,提问作者Dimitrios Konstantinidis
相关产品推荐
相关产品推荐

