Reputation: 105
I'm programming a pacman AI (yes it's homework), however I'm fairly new and I want to find all the adjacent positions (up, down, left and right) to pacman's current position. Now I have a list of all positions that are free in the level but I want to remove all those that aren't adjacent to the current position. Here's my adjacent rules:
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.
Now I want to use a list of positions (Xx,Yy) and only use the positions that fulfill one of the adjacent rules. So I have to traverse the list, use adjacent (Prolog will check all 4 rules, correct?) and if true, add them to a new list.
So something like this
find_adjacent((X,Y),[(Xx,Yy)|T], Z] :-
adjacent((X,Y),(Xx,Yy) -> add_to_new_list((Xx,Yy),Z);
Is this the correct way of thinking in Prolog? Could someone point me in the right direction?
Thanks.
Upvotes: 3
Views: 841
Reputation: 10102
If you are using Prolog without constraints, you will have to normalize/evaluate the expression first. That is:
adjacent((X,Y), (Xx,Yy)) :-
Xx is X+1,
Yy = Y.
...
Even simpler and faster would be
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).
And if the second argument is always ground (no variables):
adjacent((X,Y), (Xx, Yy)) :-
abs(X-XX)+abs(Y-Yy) =:= 1.
You might consider using library(clpfd)
which would permit you to state all four rules just as compactly as above version, but still would permit variables everywhere.
adjacent((X,Y), (Xx, Yy)) :-
abs(X-Xx)+abs(Y-Yy) #= 1.
However, as a beginner, there are better examples getting acquainted with library(clpfd)
.
Upvotes: 4