2

我是 prolog 的初学者,我正在尝试使用 netlogo 和 prolog 让 pacman 自行移动。所以这是我的代码的一部分:

walkfront(_,_,_,_,_,_,Pacman,DirP,Lab,Ghost,_,Pellet,_,_,Decision) :- findall(Dir, ( member(Dir,[0,90,180,270]), \+ ( member((G,false),Ghost), dangerous(Pacman,G,2,Dir,_) ) ), L), findall(Dir,(member(Dir,[0,90,180,270]),(member(P,Pellet))),T), chooseNotDangerous(L,Pacman,DirP,Lab,Dir,T)

walkfront(_,_,_,_,_,_,Pacman,DirP,Lab,Ghost,_,Pellet,_,_,Decision)这一行包含我从 netlogo 获得的所有信息列表,Pacman 有 pacman (x,y) 的位置,DirP 是 pacman 面对的方向,Lab 是迷宫中的空闲空间,Ghost 是ghosts (x,y,eaten?),Pellet 是所有小球 (x,y) 位置的列表,Decision 是 pacman 选择的输出。
第一个 findall 应该给我所有没有鬼和不危险的方向 (Dir),并将它们保存在一个名为 L
的列表中。第二个 findall,我希望它给我所有有的方向颗粒并将它们保存在一个名为 T 的列表中。
我的问题是这个 findall 是否正确,因为我的代码由于某种原因无法正常工作,我认为这可能是因为第二个 findall。
感谢你们对我的帮助 :)。

4

1 回答 1

2

从技术上讲, findall/3 永远不会失败,因为如果没有任何调用成功,它将以一个空的结果列表完成(当然,如果您的 Prolog 实现了异常,则例外)。

当然,如果没有所有代码,就不可能回答你的问题。并且可能,即使有所有可用的代码,您也将获得很少的帮助(如果有的话),因为structure您的程序似乎比建议的要复杂。

Prolog 是一种具有关系数据模型的语言,当可以保持关系干净时,最好使用这种数据模型,最好是规范化。现在你有了一个有16 个参数的谓词。您将如何确保所有这些都正确播放?

我想说 -现在不要改变你的程序的结构,如果你成功调试它就可以了。但是下一个程序——如果有的话——使用另一种风格,以及 Prolog 提供的实现数据隐藏的工具。

普通的旧 Prolog 'only' 有复合术语:你的代码应该是

  packman(CurrPackManState, CurrGhostsState, NextPackManState, NextGhostsState) :-
    ...

其中 CurrGhostsState 应该是 CurrGhostState 的列表,并且该列表的每个元素都应与适当的结构统一,隐藏有关位置、颜色、形状等的信息...

SWI-Prolog 现在有dicts,任何 Prolog 都可以让你使用 DCG 来降低代码的复杂性。请参阅Markus Triska 的此页面,查找“隐式传递状态”。

此外,您始终可以选择将一些更新频率较低的信息(例如迷宫结构)放入全局数据库中,并使用断言/撤回。

于 2014-04-10T06:21:54.440 回答