相邻位置的Prolog遍历列表

时间:2014-04-15 10:21:27

标签: list prolog conditional-statements

我正在编程一个pacman AI(是的它的功课),但是我很新,我想找到所有相邻的位置(上,下,左和右)到pacman的当前位置。现在我有一个列表,列出了关卡中所有空位,但我想删除所有与当前位置不相邻的位置。这是我的相邻规则:

adjacent((X,Y), (Xx,Yy)) :-
    X+1=Xx,
    Y=Yy.
adjacent((X,Y), (Xx,Yy)) :-
    X-1=Xx,
    Y=Yy.
adjacent((X,Y), (Xx,Yy)) :-
    X=Xx,
    Y+1=Yy. 
adjacent((X,Y), (Xx,Yy)) :-
    X=Xx
    Y-1=Yy.

现在我想使用一个位置列表(Xx,Yy),并且只使用满足相邻规则之一的位置。 所以我必须遍历列表,使用相邻(Prolog将检查所有4条规则,更正?)如果为true,则将它们添加到新列表中。

这样的事情

    find_adjacent((X,Y),[(Xx,Yy)|T], Z] :-
        adjacent((X,Y),(Xx,Yy) -> add_to_new_list((Xx,Yy),Z);

这是Prolog的正确思考方式吗?有人能指出我正确的方向吗?

感谢。

1 个答案:

答案 0 :(得分:4)

如果您在没有约束的情况下使用Prolog,则必须首先对表达式进行标准化/计算。那就是:

adjacent((X,Y), (Xx,Yy)) :-
   Xx is X+1,
   Yy = Y.
...

更简单,更快捷的是

adjacent((X,Y), (X, Yy)) :-
   ( Yy is Y+1 ; Yy is Y-1 ).
adjacent((X,Y), (Xx, Y)) :-
   ( Xx is X+1 ; Xx is X-1).

如果第二个参数始终是基础(无变量):

adjacent((X,Y), (Xx, Yy)) :-
   abs(X-XX)+abs(Y-Yy) =:= 1.

你可以考虑使用library(clpfd),它允许你像上面的版本一样紧凑地陈述所有四个规则,但仍然允许变量到处都是。

adjacent((X,Y), (Xx, Yy)) :-
   abs(X-Xx)+abs(Y-Yy) #= 1.

然而,作为初学者,有更好的例子可以熟悉library(clpfd)