Я пытаюсь решить проблему с оружием, у которого есть два варианта урона (опция: s, опция: c). Опция s дает урон D, а опция c удваивает текущий урон до 2 * D. Структура правила такова:
evaluate_damage(D,List,TotalDamage).
D - начальный урон.
Список - это список, в котором есть компиляция s и c.
TotalDamage - это общий урон, нанесенный списком.
Вот несколько примеров.
?- evaluate_damage(1, [s,s], TotalDamage).
TotalDamage = 2
Yes
?- evaluate_damage(1, [s,c,s,c], TotalDamage).
TotalDamage = 3
Yes
?- evaluate_damage(1, [s,c,s,c,s,s], TotalDamage).
TotalDamage = 11
Yes
?- evaluate_damage(2, [s,s], TotalDamage).
TotalDamage = 4
Yes
Сам по себе он прекрасно работает, но когда я использую его в другом правиле, он не дает ожидаемого результата. В частности, у меня есть другое правило в моей программе, которое меняет порядок символов для достижения меньшего ущерба.
Структура этого правила такова:
hack(List,Max,NewProgram,N).
Где List - список элементов.
Max - максимальный ущерб, который может нанести перестроенный список
NewProgram - переставленный список,
N - это количество свопов, выполненных для перехода к переупорядоченному списку NewProgram.
Вот ожидаемые результаты этого правила:
?- hack([c, s], 1, NewProgram, N).
NewProgram = [s, c]
N = 1
Yes
?- hack([s, s], 1, NewProgram, N).
No
?- hack([s, c, c, s, s, c], 6, NewProgram, N).
NewProgram = [s, s, c, c, s, c]
N = 2
Yes
?- hack([c, s, c, s, s], 3, NewProgram, N).
NewProgram = [s, s, s, c, c]
N = 5
Yes
Это мой код.
evaluate_damage(_,[],0).
evaluate_damage(D,s,D).
evaluate_damage(D,c,Damage) :-
Damage is D*2.
evaluate_damage(D,[H|List],TotalDamage) :-
evaluate_damage(D,H,Damage),
(Damage=D;Damage=0),
evaluate_damage(D,List,TDamage),
TotalDamage is D+TDamage.
evaluate_damage(D,[H|List],TotalDamage) :-
evaluate_damage(D,H,Damage),
Damage>D,
evaluate_damage(Damage,List,TotalDamage).
cutList(List,List1,[c|List2]) :-
append(List1,[c|List2], List),!.
hack(List,Max,NewProgram,N) :-
cutList(List,L1,[c|L2]),
length(L2,Length2),
append(L2,c,NewList2),
append(L1,NewList2,NewList),
evaluate_damage(1,NewList,SecondDamage),
SecondDamage=<Max,
N is Length2,
NewProgram is NewList.
Фактический вывод
?- hack([c, s], 1, NewProgram, N).
No (0.00s cpu)
Я отлаживал его через tracer (опция в Tools - tkEclipse), и проблема в том, что когда
evaluate_damage(D,Program,TotalDamage)
вызывается внутри
hack(Program,Max,NewProgram,N)
не дает ожидаемого результата. Это действительно странно, потому что когда
evaluate_damage (D, Программа, TotalDamage)
называется сам по себе, работает отлично. Кто-нибудь знает в чем проблема?