- Some work on the AI for new keywords.

- NPE prevention in AI code.
This commit is contained in:
Agetian
2018-12-22 20:30:54 +03:00
committed by Hanmac
parent b87f247c09
commit 2a02fd124e
3 changed files with 55 additions and 43 deletions

View File

@@ -20,6 +20,7 @@ package forge.ai;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.base.Predicates; import com.google.common.base.Predicates;
import com.google.common.collect.*; import com.google.common.collect.*;
import forge.ai.ability.ChooseGenericEffectAi;
import forge.ai.ability.ProtectAi; import forge.ai.ability.ProtectAi;
import forge.ai.ability.TokenAi; import forge.ai.ability.TokenAi;
import forge.card.CardType; import forge.card.CardType;
@@ -986,6 +987,11 @@ public class ComputerUtil {
return true; return true;
} }
if (card.hasKeyword(Keyword.RIOT) && ChooseGenericEffectAi.preferHasteForRiot(sa, ai)) {
// Planning to choose Haste for Riot, so do this in Main 1
return true;
}
// if we have non-persistent mana in our pool, would be good to try to use it and not waste it // if we have non-persistent mana in our pool, would be good to try to use it and not waste it
if (ai.getManaPool().willManaBeLostAtEndOfPhase()) { if (ai.getManaPool().willManaBeLostAtEndOfPhase()) {
boolean canUseToPayCost = false; boolean canUseToPayCost = false;

View File

@@ -1455,7 +1455,7 @@ public class ComputerUtilCombat {
continue; continue;
} }
if (ability.hasParam("Adapt") && blocker.getCounters(CounterType.P1P1) > 0) { if (ability.hasParam("Adapt") && blocker != null && blocker.getCounters(CounterType.P1P1) > 0) {
continue; continue;
} }

View File

@@ -350,7 +350,15 @@ public class ChooseGenericEffectAi extends SpellAbilityAi {
} }
} else if ("Riot".equals(logic)) { } else if ("Riot".equals(logic)) {
SpellAbility counterSA = spells.get(0), hasteSA = spells.get(1); SpellAbility counterSA = spells.get(0), hasteSA = spells.get(1);
return preferHasteForRiot(sa, player) ? hasteSA : counterSA;
}
return spells.get(0); // return first choice if no logic found
}
public static boolean preferHasteForRiot(SpellAbility sa, Player player) {
// returning true means preferring Haste, returning false means preferring a +1/+1 counter
final Card host = sa.getHostCard();
final Game game = host.getGame();
final Card copy = CardUtil.getLKICopy(host); final Card copy = CardUtil.getLKICopy(host);
copy.setLastKnownZone(player.getZone(ZoneType.Battlefield)); copy.setLastKnownZone(player.getZone(ZoneType.Battlefield));
@@ -362,22 +370,22 @@ public class ChooseGenericEffectAi extends SpellAbilityAi {
// can't gain counters, use Haste // can't gain counters, use Haste
if (!copy.canReceiveCounters(CounterType.P1P1)) { if (!copy.canReceiveCounters(CounterType.P1P1)) {
return hasteSA; return true;
} }
// already has Haste, use counter // already has Haste, use counter
if (copy.hasKeyword(Keyword.HASTE)) { if (copy.hasKeyword(Keyword.HASTE)) {
return counterSA; return false;
} }
// not AI turn // not AI turn
if (!game.getPhaseHandler().isPlayerTurn(player)) { if (!game.getPhaseHandler().isPlayerTurn(player)) {
return counterSA; return false;
} }
// not before Combat // not before Combat
if (!game.getPhaseHandler().getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS)) { if (!game.getPhaseHandler().getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS)) {
return counterSA; return false;
} }
// TODO check other opponents too if able // TODO check other opponents too if able
@@ -385,13 +393,11 @@ public class ChooseGenericEffectAi extends SpellAbilityAi {
if (opp != null) { if (opp != null) {
// TODO add predict Combat Damage? // TODO add predict Combat Damage?
if (opp.getLife() < copy.getNetPower()) { if (opp.getLife() < copy.getNetPower()) {
return hasteSA; return true;
} }
} }
// haste might not be good enough? // haste might not be good enough?
return counterSA; return false;
}
return spells.get(0); // return first choice if no logic found
} }
} }