我是 prolog 的初学者,我正在尝试使用 netlogo 和 prolog 让 pacman 自行移动。这是我的代码的一部分:
walkfront(_,_,_,_,_,_,Pacman,DirP,Lab,Ghost,_,Pellet,_,_,决定) :-
查找所有(目录,
( 成员(目录,[0,90,180,270]),
\+ ( 成员((G,false),幽灵), 危险(Pacman,G,2,Dir,_) ) ),
L),
findall(Dir,(成员(Dir,[0,90,180,270]),(成员(P,佩莱))),T),
选择NotDangerous(L,Pacman,DirP,Lab,Dir,T)
walkfront(_,_,_,_,_,_,Pacman,DirP,Lab,Ghost,_,Pellet,_,_,Decision)
这一行包含所有信息列表我从netlogo得到,Pacman有pacman的位置(x,y),DirP是pacman面对的方向,Lab是迷宫中的自由空间,Ghost是鬼魂的位置(x,y,吃? ), Pellet 是所有粒子位置 (x,y) 的列表,Decision 是 pacman 选择的输出。
第一个 findall 应该给我所有没有幽灵且不危险的方向(Dir),并将它们保存在名为 L 的列表中。
第二个 findall,我希望它给我所有有颗粒的方向,并将它们保存在名为 T 的列表中。
我的问题是这个 findall 是否正确,因为我的代码由于某种原因无法工作,我认为这可能是因为第二个 findall 。
谢谢你帮助我:)。
最佳答案
从技术上讲,findall/3 永远不会失败,因为如果没有一个调用成功,它将以空结果列表完成(好吧,如果您的 Prolog 实现了异常(exception)情况)。
当然,如果没有所有代码,就不可能回答您的问题。而且,即使有所有可用的代码,您也可能得不到任何帮助(如果有的话),因为程序的结构
似乎比建议的更复杂。
Prolog 是一种具有关系数据模型的语言,当可以保持关系干净(最好规范化)时,可以更好地使用这种数据模型。现在您有一个带有 16 个参数的谓词。您将如何确保它们全部一起正确播放?
我想说 - 如果你成功调试它,那么现在就不要改变你的程序的结构。但是下一个程序(如果有的话)使用另一种风格,以及 Prolog 提供的工具来实现数据隐藏。
普通的旧 Prolog “仅”有复合术语:您的代码可能应该是
packman(CurrPackManState, CurrGhostsState, NextPackManState, NextGhostsState) :-
...
其中 CurrGhostsState 应该是 CurrGhostState 的列表,并且该列表中的每个元素都应该与适当的结构统一,隐藏有关位置、颜色、形状等信息...
SWI-Prolog 现在有 dicts ,任何 Prolog 都会让您使用 DCG 来降低代码的复杂性。请参阅this page来自 Markus Triska,查找“隐式传递状态”。
此外,您始终可以选择使用断言/撤回将一些不经常更新的信息(例如迷宫结构)放入全局数据库中。
关于prolog - Findall 包含 Pacman netlogo 游戏列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22977446/