Prolog - 递归运动

时间:2013-11-26 12:17:05

标签: prolog

我为pacman游戏制作了这个prolog函数:

% I want this to return 0, 1, 2 or 3 to make a move.
other-moves([[Xpacman,Ypacman]], Listpellets, Listwall, Movepacman) :-
   count_pellets_above(Listpellets,A), 
   count_pellets_bellow(Listpellets,B), 
   A > B, 
   repeat, 
   choose(4,2,Movepacman), 
   iswall(Xpacman,Ypacman,Movepacman,Listwall),
   !.
other-moves([[Xpacman,Ypacman]], Listpellets, Listwall, Movepacman) :- 
   count_pellets_above(Listpellets,C), 
   count_pellets_bellow(Listpellets,D), 
   C =< D, 
   repeat, 
   choose(4,3,Movepacman), 
   iswall(Xpacman,Ypacman,Movepacman,Listwall),
   !.

% verifies if the coordinate is a wall.
iswall(Xpacman, Ypacman, Random,Listwall) :- 
   Random==0, 
   X1 is Xpacman-1, 
   (member([X1,Ypacman], Listwall)),
   !.
iswall(Xpacman, Ypacman, Random,Listwall) :- 
   Random==1, 
   X1 is Xpacman+1, 
   (member([X1,Ypacman],Listwall)),
   !.
iswall(Xpacman, Ypacman, Random,Listwall) :- 
   Random==2, 
   Y1 is Ypacman-1, 
   (member([Xpacman,Y1],Listwall)),
   !.
iswall(Xpacman, Ypacman, Random,Listwall) :- 
   Random==3, 
   Y1 is Ypacman+1, 
   (member([Xpacman,Y1],Listwall)),
   !.

% gives a random number
choose(A, C, B) :- 
   repeat, 
   B is random(A), 
   B \= C,
   !.

%count the number of pellets above the coordinate (0,0).
count_pellets_above([],0).
count_pellets_above([[_,Y]|T],N) :- 
   Y>=0, 
   count_pellets_above(T,M), 
   N is M+1,
   !.
count_pellets_above([[_,Y]|T],N) :- 
   Y<0, 
   count_pellets_above(T,M), 
   N is M,
   !.

% count the number of pellets bellow the coordinate (0,0).
count_pellets_bellow([],0).
count_pellets_bellow([[_,Y]|T],N) :- 
   Y=<0, 
   count_pellets_bellow(T,M), 
   N is M+1,
   !.
count_pellets_bellow([[_,Y]|T],N) :- 
   Y>0, 
   count_pellets_bellow(T,M), 
   N is M,
   !.   

我希望其他动作能够返回与移动墙不同的数字。当我发出这个命令时,我不知道为什么其他动作会返回false而不是数字:

other-moves([[1,2]],[[]],[[1,3]],C).

感谢。

1 个答案:

答案 0 :(得分:1)

other-moves不是有效的Prolog标识符。它被解析为

other - moves([[Xpacman,Ypacman]], Listpellets, Listwall, Movepacman)

因此,您可以在原子-和某些other条款上有效地定义moves/4

使用下划线而不是破折号。