Смена списка в прологе
Следующий код приводит к бесконечному циклу с возможной ошибкой "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.