列表在Prolog中转移

时间:2012-12-03 07:59:37

标签: list prolog failure-slice

以下代码导致无限循环,最终出现“Out of Local Stack”错误基本上我将GX的值递减,直到它与MX相同为止。 样本输入[[m,g,b],[w,w,w]],路径

wallBlock('w').
wallBlock('b').
item('f').
item('p').
item('m').
item('u').
item('6').
item('r').
item('g').
anyCell(Cell) :- 
    wallBlock(Cell).
anyCell(Cell) :-
    item(Cell).


ghostPathing(Maps, Path) :-
    append(Maps, NewMap), 
    length(Maps, N), 
    findGhost(NewMap, N, GX, GY), 
    findPacman(NewMap, N, MX, MY),
    moveGhost(NewMap, N, MX, MY, GX, GY, Path).

/*FINDS THE COORDINATES OF THE GHOST W=row X=column*/
findGhost(NewMap, N, X, Y) :-
    findGhostSpot(NewMap, S),
    X is floor(S / N) + 1,
    Y is (S mod N) +1 .

findGhostSpot(['g'|_], 0) :-
    print('Found Ghost. ').
findGhostSpot(['r'|_], 0) :-
    print('Found Ghost. ').
findGhostSpot(['6'|_], 0) :-
    print('Found Ghost. ').
findGhostSpot([_|Tail], S) :-
    findGhostSpot(Tail, S1),
    S is S1+1 .

/*FINDS THE COORDINATES OF THE GHOST W=row X=column*/
findPacman(NewMap, N, X, Y) :-
    findPacmanSpot(NewMap, S),
    X is floor(S / N) + 1,
    Y is (S mod N) + 1.

findPacmanSpot(['m'|_], 0) :-
    print('Found Pacman. ').
findPacmanSpot([_|Tail], S) :-
    findPacmanSpot(Tail, S1),
    S is S1+1 .

/* Base Case, Ghost is on the Pacman*/
moveGhost(_, _, X, Y, X, Y, []).

/*IF PACMAN AND THE GHOST ARE IN THE SAME COLUMN*/
moveGhost(NewMap, N, MX, Y, GX, Y, ['u'|Rest]) :-
    itemNext(NewMap, CN, Z),
    item(Z),
    moveGhost(NewMap, N, MX, Y, X, Y, Rest),
    GX is X + 1,
    MX < GX,
    CN is ((X * N) + Y).
moveGhost(NewMap, N, MX, Y, GX, Y, ['d'|Rest]) :-
    itemNext(NewMap, CN, Z),
    item(Z),
    moveGhost(NewMap, N, MX, Y, X, Y, Rest),
    GX is X - 1,
    MX > GX,
    CN is ((X * N) + Y).

/*IF PACMAN AND THE GHOST ARE IN THE SAME ROW*/
moveGhost(NewMap, N, X, MY, X, GY, ['l'|Rest]) :-
    itemNext(NewMap, CN, Z),
    item(Z),
    moveGhost(NewMap, N, X, MY, X, Y, Rest),
    GY is Y + 1,
    MY < GY,
    CN is ((X * N) + Y).
moveGhost(NewMap, N, X, MY, X, GY, ['r'|Rest]) :-
    itemNext(NewMap, CN, Z),
    item(Z),
    moveGhost(NewMap, N, X, MY, X, Y, Rest),
    GY is Y - 1,
    MY > GY,
    CN is ((X * N) + Y).

itemNext([Cell|_], 0, Cell) :-
    item(Cell). 
itemNext([First|Rest], CN, Cell) :-
    anyCell(First),
    itemNext(Rest, N, Cell),
    CN is N + 1.

因为它是一个2d数组,所以append将其转换为1d,NextCell中的算术取一行的长度并找到相邻单元格的坐标并返回该单元格的值。如果单元格是'w'或'b',则鬼魂不能朝那个方向移动。你可以假设地图是SQUARE!

1 个答案:

答案 0 :(得分:1)

(我认为你的问题是你的程序循环的原因。)

要本地化未终止程序的原因,我已将 false 目标插入您的计划中。由于剩余的程序(故障片)没有终止,原始程序也不会终止。您需要在剩余的可见部分中修复某些内容。或者,换句话说:只要当前片段保持不变,问题就会持续存在!作为一个小问题,最好在纯粹的程序中避免print/1目标。

有关详情,请参阅标记

?- ghostPathing([[m,g,b],[w,w,w]],Path), false.


item('f') :- false.
item('p') :- false.
item('m').
item('u') :- false.
item('6') :- false.
item('r') :- false.
item('g').

anyCell(Cell) :- false,
    wallBlock(Cell).
anyCell(Cell) :-
    item(Cell).

ghostPathing(Maps, Path) :-
    append(Maps, NewMap), 
    length(Maps, N), 
    findGhost(NewMap, N, GX, GY), 
    findPacman(NewMap, N, MX, MY),
    moveGhost(NewMap, N, MX, MY, GX, GY, Path), false.

/*FINDS THE COORDINATES OF THE GHOST W=row X=column*/
findGhost(NewMap, N, X, Y) :-
    findGhostSpot(NewMap, S),
    X is floor(S / N) + 1,
    Y is (S mod N) +1 .

findGhostSpot(['g'|_], 0) :-
    print('Found Ghost. ').
findGhostSpot(['r'|_], 0) :- false,
    print('Found Ghost. ').
findGhostSpot(['6'|_], 0) :- false,
    print('Found Ghost. ').
findGhostSpot([_|Tail], S) :-
    findGhostSpot(Tail, S1),
    S is S1+1 .

/*FINDS THE COORDINATES OF THE GHOST W=row X=column*/
findPacman(NewMap, N, X, Y) :-
    findPacmanSpot(NewMap, S),
    X is floor(S / N) + 1,
    Y is (S mod N) + 1.

findPacmanSpot(['m'|_], 0) :-
    print('Found Pacman. ').
findPacmanSpot([_|Tail], S) :- false,
    findPacmanSpot(Tail, S1),
    S is S1+1 .

/* Base Case, Ghost is on the Pacman*/
moveGhost(_, _, X, Y, X, Y, []) :- false.

/*IF PACMAN AND THE GHOST ARE IN THE SAME COLUMN*/
moveGhost(NewMap, N, MX, Y, GX, Y, ['u'|Rest]) :- false,
    itemNext(NewMap, CN, Z),
    item(Z),
    moveGhost(NewMap, N, MX, Y, X, Y, Rest),
    GX is X + 1,
    MX < GX,
    CN is ((X * N) + Y).
moveGhost(NewMap, N, MX, Y, GX, Y, ['d'|Rest]) :-  false,
    itemNext(NewMap, CN, Z),
    item(Z),
    moveGhost(NewMap, N, MX, Y, X, Y, Rest),
    GX is X - 1,
    MX > GX,
    CN is ((X * N) + Y).

/*IF PACMAN AND THE GHOST ARE IN THE SAME ROW*/
moveGhost(NewMap, N, X, MY, X, GY, ['l'|Rest]) :-
    itemNext(NewMap, CN, Z),
    item(Z),
    moveGhost(NewMap, N, X, MY, X, Y, Rest), false,
    GY is Y + 1,
    MY < GY,
    CN is ((X * N) + Y).
moveGhost(NewMap, N, X, MY, X, GY, ['r'|Rest]) :- false,
    itemNext(NewMap, CN, Z),
    item(Z),
    moveGhost(NewMap, N, X, MY, X, Y, Rest),
    GY is Y - 1,
    MY > GY,
    CN is ((X * N) + Y).

itemNext([Cell|_], 0, Cell) :-
    item(Cell). 
itemNext([First|Rest], CN, Cell) :-
    anyCell(First),
    itemNext(Rest, N, Cell),
    CN is N + 1.