Пролог как получить максимальный вариант из множества вариантов - PullRequest
2 голосов
/ 08 апреля 2020

Я пытаюсь определить максимальный урон, нанесенный в битве с покемонами в Прологе. У меня есть следующие факты.

pokemon(venusaur).
pokemon(blastoise).
pokemon(charizard).

is_type(venusaur, grass).
is_type(venusaur, poison).
is_type(blastoise, water).
is_type(charizard, fire).
is_type(charizard, flying).

speed(charizard, 100).
speed(blastoise, 78).
speed(venusaur, 80).

attack_of_type(flamethrower, fire).
attack_of_type(scald, water).
attack_of_type(solarbeam, grass).
attack_of_type(earthquake, ground).
attack_of_type(icebeam, ice).
attack_of_type(sludgebomb, poison).
attack_of_type(airslash, flying).
attack_of_type(darkpulse, dark).
attack_of_type(aurasphere, fighting).
attack_of_type(hpfire, fire).

has_attack(charizard, flamethrower).
has_attack(charizard, solarbeam).
has_attack(charizard, airslash).
has_attack(charizard, earthquake).
has_attack(blastoise, scald).
has_attack(blastoise, icebeam).
has_attack(blastoise, darkpulse).
has_attack(blastoise, aurasphere).
has_attack(venusaur, solarbeam).
has_attack(venusaur, sludgebomb).
has_attack(venusaur, earthquake).
has_attack(venusaur, hpfire).

has_power(flamethrower, 90).
has_power(solarbeam, 120).
has_power(airslash, 75).
has_power(earthquake, 100).
has_power(scald, 80).
has_power(icebeam, 90).
has_power(darkpulse, 80).
has_power(aurasphere, 80).
has_power(sludgebomb, 90).
has_power(hpfire, 60).

Я пытаюсь создать правило, которое наносит максимальный урон, но я не уверен, как go узнать об этом. До сих пор у меня есть правило, которое может определить, можно ли убить покемона в текущем ходу.

hit_supereffectively_by(Pkmn, AtkType) :- 
    is_type(Pkmn, Type), weak(Type, AtkType).

hit_notveryeffectively_by(Pkmn, AtkType) :- 
    is_type(Pkmn, Type), resist(Type, AtkType).

is_immune_to(Pkmn, AtkType) :- 
    is_type(Pkmn, Type), immune(Type, AtkType).

can_kill(Me, You, MyHP, YourHP, MyAttack) :- 
    has_attack(Me, MyAttack), has_power(MyAttack, MyAtkPower), (MyAtkPower / 2) >= YourHP.

can_kill(Me, You, MyHP, YourHP, MyAttack) :- 
    has_attack(Me, MyAttack), attack_of_type(MyAttack, MyAtkType), hit_supereffectively_by(You, MyAtkType), \+ is_immune_to(You, MyAtkType), \+ hit_notveryeffectively_by(You, MyAtkType), 
    has_power(MyAttack, MyAtkPower), MyAtkPower >= YourHP.

best_move(Me, You, MyHP, YourHP, MyAttack) :- 
    is_faster(Me, You), can_kill(Me, You, MyHP, YourHP, MyAttack).

Я пытаюсь расширить best_move до точки, где, если первая строка не является ' t true (быстрее и может убивать), затем возвращает ход, который нанесет наибольший урон, как MyAttack.

Может ли кто-нибудь указать мне правильное направление относительно того, как это сделать? Я новичок в декларативном программировании. Tyvm.

1 Ответ

1 голос
/ 08 апреля 2020

Из вашего описания видно, что должен быть не более одного лучшего хода. Таким образом, вы, вероятно, можете использовать управляющую конструкцию if-then-else :

best_move(Me, You, MyHP, YourHP, MyAttack) :- 
    (   is_faster(Me, You),
        can_kill(Me, You, MyHP, YourHP, MyAttack) ->
        true
    ;   % otherwise select move that does most damage
        ...
    ).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...