Смена списка в прологе

Следующий код приводит к бесконечному циклу с возможной ошибкой "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 массив, добавление превращает его в 1d, а арифметика в NextCell принимает длину строки, находит координаты соседней ячейки и возвращает значение этой ячейки. Призрак не может двигаться в этом направлении, если ячейка представляет собой "w" или "b". Вы можете предположить, что Карты это квадрат!

1 ответ

(Я предполагаю, что ваш вопрос - почему ваша программа зацикливается.)

Чтобы локализовать причину не прекращения вашей программы, я вставил цели false в вашу программу. Поскольку оставшаяся программа (срез ошибки) не завершается, ваша исходная программа также не завершается. Вам нужно что-то исправить в оставшейся видимой части. Или, иначе говоря: пока текущий фрагмент остается неизменным, проблема будет сохраняться! И как небольшое замечание, лучше избегать print/1 цели в чистой программе, как у тебя.

Для получения дополнительной информации см. Тег fail-slice

? - ghostPathing ([[m, g, b], [w, w, w]], путь), false.


пункт ('f'): - неверно.
пункт ('p'): - неверно.
пункт ('м').
элемент ('u'):- неверно.
пункт ('6'):- неверно.
пункт ('r'): - неверно.
пункт ('г').

anyCell (Cell): - неверно,
    настенный блок (сотовый).
anyCell (Cell): -
    пункт (Cell).

ghostPathing(Карты, Путь): -
    добавить (Карты, NewMap), 
    длина (Карты, N), 
    findGhost (NewMap, N, GX, GY), 
    findPacman (NewMap, N, MX, MY),
    moveGhost (NewMap, N, MX, MY, GX, GY, Path), false.

/* НАЙТИ КООРДИНАТЫ ПРИЗРАКА W= строка X= столбец */
findGhost(NewMap, N, X, Y):-
    findGhostSpot(NewMap, S),
    Х пол (S / N) + 1,
    Y (S мод N) +1 .

findGhostSpot(['g'|_], 0):-
    печать ("Найденный призрак").
findGhostSpot (['r' | _], 0): - false,
    печать ("Найденный призрак").
findGhostSpot (['6' | _], 0): - false,
    печать ("Найденный призрак").
findGhostSpot ([_ | Tail], S): -
    findGhostSpot (Tail, S1),
    S это S1+1 .

/* НАЙТИ КООРДИНАТЫ ПРИЗРАКА W= строка X= столбец */
findPacman(NewMap, N, X, Y):-
    findPacmanSpot(NewMap, S),
    Х пол (S / N) + 1,
    Y равен (S мод N) + 1.

findPacmanSpot(['m'|_], 0):-
    печать ("Найден Пакман").
findPacmanSpot ([_ | Tail], S): - false,
    findPacmanSpot (Tail, S1),
    S это S1 + 1.

/* Базовый случай, призрак на пакмане * /
moveGhost (_, _, X, Y, X, Y, []): - неверно.

/* ЕСЛИ ПАКМАН И ПРИЗРАК В ТО ЖЕ КОЛОННЕ * /
moveGhost (NewMap, N, MX, Y, GX, Y, ['u' | Rest]): - false,
    itemNext (NewMap, CN, Z),
    элемент (Z),
    moveGhost (NewMap, N, MX, Y, X, Y, Rest),
    GX - это X + 1,
    MX ,
    CN - это ((X * N) + Y).
moveGhost (NewMap, N, MX, Y, GX, Y, ['d' | Rest]): - false,
    itemNext (NewMap, CN, Z),
    элемент (Z),
    moveGhost (NewMap, N, MX, Y, X, Y, Rest),
    GX - X - 1,
    MX> GX,
    CN - это ((X * N) + Y).

/* ЕСЛИ ПАКМАН И ПРИЗРАК В ОДНОМ РЯДЕ */
moveGhost(NewMap, N, X, MY, X, GY, ['l'| Отдых]):-
    itemNext(NewMap, CN, Z),
    пункт (Z)
    moveGhost (NewMap, N, X, MY, X, Y, Rest), false,
    GY - это Y + 1,
    MY ,
    CN - это ((X * N) + Y).
moveGhost (NewMap, N, X, MY, X, GY, ['r' | Rest]): - false,
    itemNext (NewMap, CN, Z),
    элемент (Z),
    moveGhost (NewMap, N, X, MY, X, Y, Rest),
    GY - Y - 1,
    MY> GY,
    CN - это ((X * N) + Y).

itemNext ([Cell | _], 0, Cell): -
    пункт (Cell). 
itemNext([Первый | Отдых], CN, Cell):-
    anyCell(Первый),
    itemNext(Rest, N, Cell),
    CN - это N + 1.
Другие вопросы по тегам