Я делаю «игру» в Прологе, начиная с начальной позиции в массиве, игра должна возвращать все возможные пути, где весь массив равен -1, а текущая позиция установлена в 0. Необходимо записать все возможные маршруты в .txt файле
Редактирование возвышенным, компиляция с использованием SWI-Prolog.
Начальная функция, получающая начальную позицию X, Y в матрице
inicia(X,Y,Matriz,Caminho) :- jogar(Matriz,X,Y,Caminho), escreveArq(Caminho).
Матрица отпечатков
imprimeMatriz([]).
imprimeMatriz([H|T]) :- imprimeLista(H),nl, imprimeMatriz(T).
imprimeLista([]).
imprimeLista([H|T]) :- write(H), write(", "), imprimeLista(T).
Запись в файл
escreveArq([]).
escreveArq(Rota) :- open('caminho.txt', write, ID), writeq(ID,Rota), write(ID,'\n'), close(ID).
восстановить элемент X Y
recuperaElemento(X, Y, Elemento,Matriz) :- achaElemento(X,0,Matriz,ListaX), achaElemento(Y,0,ListaX,Elemento).
achaElemento(_,_,[],_) :- false.
achaElemento(Elemento,Aux,[H|_],H) :- Elemento == Aux.
achaElemento(Elemento,Aux,[_|HT],R) :- Aux1 is Aux + 1, achaElemento(Elemento,Aux1,HT,R).
поиск соседнего элемента
elementoSuperior(X,Y,Elemento,Matriz) :- N is X-1, recuperaElemento(N,Y,Elemento, Matriz).
elementoSuperior(_,_,-5,_).
elementoInferior(X,Y,Elemento,Matriz) :- N is X+1, recuperaElemento(N,Y,Elemento,Matriz).
elementoInferior(_,_,-5,_).
elementoDireita(X,Y,Elemento,Matriz) :- N is Y+1, recuperaElemento(X,N,Elemento,Matriz).
elementoDireita(_,_,-5,_).
elementoEsquerda(X,Y,Elemento,Matriz) :- N is Y-1, recuperaElemento(X,N,Elemento,Matriz).
elementoEsquerda(_,_,-5,_).
проверить конец игры
fimDeJogo(Matriz) :- verificaFim(Matriz,R), R == 1.
verificaFim([],X) :- X is 0.
verificaFim([H|T],X) :- verificaFimColuna(H,X1), verificaFim(T,X2), X is X1 + X2.
verificaFimColuna([],X) :- X is 0, !.
verificaFimColuna([H|T],R) :- H == -1, verificaFimColuna(T, R).
verificaFimColuna([H|T],X) :- H == 0, verificaFimColuna(T, R), X is R+1.
impossivelJogar(Matriz, X,Y) :- elementosVizinhos(X,Y,Resp,Matriz), verifica(Resp).
verifica([]).
verifica([H|T]) :- H < 0, verifica(T).
Играть в игру
добавляет S, как он поднимается в массиве
И добавляет, когда он идет влево
добавить D при движении направо
добавить I, когда он падает
jogar(Matriz, _,_,_) :- fimDeJogo(Matriz).
jogar(Matriz, X,Y,["S"|Rota]) :- elementoSuperior(X,Y,Z,Matriz),Z > -1,decrementa(X,Y,Matriz,NMAtriz),
NX is X-1,jogar(NMAtriz, NX, Y,Rota).
jogar(Matriz, X,Y,["I"|Rota]) :- elementoInferior(X,Y,Z,Matriz),Z > -1,decrementa(X,Y,Matriz,NMAtriz),
NX is X+1,jogar(NMAtriz, NX, Y,Rota).
jogar(Matriz, X,Y,["E"|Rota]) :- elementoEsquerda(X,Y,Z,Matriz),Z > -1,decrementa(X,Y,Matriz,NMAtriz),
NY is Y-1,jogar(NMAtriz, X, NY,Rota).
jogar(Matriz, X,Y,["D"|Rota]) :- elementoDireita(X,Y,Z,Matriz) ,Z > -1,decrementa(X,Y,Matriz,NMAtriz),
NY is Y+1,jogar(NMAtriz, X, NY,Rota).
уменьшает значение X в матрице
decrementa(X,Y,Matriz, MatrizAtualizada) :- reduzX(X,Y,0,0,Matriz,MatrizAtualizada).
reduzX(_,_, _, _, [], []) .
reduzX(X,Y, X, AuxY, [H|T], [LAlt|Mat]) :- NX is X+1,reduzY(X,Y, AuxY, AuxY, H, LAlt), reduzX(X,Y,NX, AuxY, T, Mat).
reduzX(X,Y, AuxX, AuxY, [H|T], [ H|Mat]) :- NAuxX is AuxX+1, reduzX(X,Y,NAuxX, AuxY, T, Mat).
reduzY(_,_, _, _, [], []) .
reduzY(_,Y, _, Y, [H|T], [NH|MAT]) :- NH is H-1, NY is Y+1, reduzY(_,Y, _, NY, T, MAT).
reduzY(_,Y, _, AuxY, [H|T], [ H|MAT]) :- NY is AuxY+1, reduzY(_,Y, _, NY, T, MAT).
для некоторых матриц, например [[1,1,1], [1,1,1], [1,1,1] генерирует неправильный путь и представляет только путь.
Я полагаю, что ошибка, связанная с указанием неверных указаний, содержится в следующем фрагменте кода:
jogar(Matriz, _,_, []) :- fimDeJogo(Matriz).
jogar(Matriz, X,Y, _) :- impossivelJogar(Matriz, X,Y).
jogar(Matriz, X,Y,["S"|Rota]) :- elementoSuperior(X,Y,Z,Matriz),Z > -1,decrementa(X,Y,Matriz,NMatriz),
NX is X-1,jogar(NMatriz, NX, Y,Rota).
jogar(Matriz, X,Y,["I"|Rota]) :- elementoInferior(X,Y,Z,Matriz),Z > -1,decrementa(X,Y,Matriz,NMatriz),
NX is X+1,jogar(NMatriz, NX, Y,Rota).
jogar(Matriz, X,Y,["E"|Rota]) :- elementoEsquerda(X,Y,Z,Matriz),Z > -1,decrementa(X,Y,Matriz,NMatriz),
NY is Y-1,jogar(NMatriz, X, NY,Rota).
jogar(Matriz, X,Y,["D"|Rota]) :- elementoDireita(X,Y,Z,Matriz) ,Z > -1,decrementa(X,Y,Matriz,NMatriz),
NY is Y+1,jogar(NMatriz, X, NY,Rota).
Когда игра не заканчивается и играть невозможно, программа должна вернуться и попробовать другой путь, вместо этого она проверяет следующие параметры и «форсирует» путь. Как можно не продолжить и вернуться, чтобы попробовать новый путь, чтобы увидеть, что больше нет возможности?