首页 > 解决方案 > Prolog如何从许多选项中获得最大选项

问题描述

我正在尝试确定 Prolog 中神奇宝贝战斗中造成的最大伤害。我有以下事实。

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).

我正在尝试制定一个规则来最大程度地造成伤害,但我不确定如何去做。到目前为止,我有一个规则可以确定是否可以在当前回合杀死神奇宝贝。

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到这样的程度,如果第一行不正确(更快并且可以杀死),那么它将返回将造成最大伤害的移动作为 MyAttack。

谁能指出我如何做到这一点的正确方向?我是声明式编程的新手。特维姆。

标签: prolog

解决方案


从你的描述看来,最多应该有一个最好的举动。因此,您可能会使用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
        ...
    ).

推荐阅读