From 6f555670c24624d4ad3d08dbcf7ff3c8b303eaa3 Mon Sep 17 00:00:00 2001 From: excessum Date: Sun, 11 May 2014 02:54:48 +0000 Subject: [PATCH] - Allow AI to use ChangeZone effects against a blocker before trying to bounce its own attacker. Ensure that the AI will use its removal on a blocker if it can save an attacker --- .../main/java/forge/ai/ComputerUtilCard.java | 27 +++++++++++++++++-- .../java/forge/ai/ability/ChangeZoneAi.java | 27 +++++++++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java b/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java index 0469866cfe3..d6655054bcd 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java @@ -901,11 +901,34 @@ public class ComputerUtilCard { public static boolean useRemovalNow(final SpellAbility sa, final Card c, final int dmg, ZoneType destination) { final Player ai = sa.getActivatingPlayer(); final Player opp = ai.getOpponent(); - final PhaseHandler ph = ai.getGame().getPhaseHandler(); + final Game game = ai.getGame(); + final PhaseHandler ph = game.getPhaseHandler(); final int costRemoval = sa.getHostCard().getCMC(); final int costTarget = c.getCMC(); + //interrupt 1:remove blocker to save my attacker + if (ph.is(PhaseType.COMBAT_DECLARE_BLOCKERS)) { + Combat currCombat = game.getCombat(); + if (currCombat != null && currCombat.getAllBlockers().contains(c)) { + for (Card attacker : currCombat.getAttackersBlockedBy(c)) { + List blockers = currCombat.getBlockers(attacker); + ComputerUtilCard.sortByEvaluateCreature(blockers); + Combat combat = new Combat(ai); + combat.addAttacker(attacker, opp); + for (Card blocker : blockers) { + if (blocker == c) { + continue; + } + combat.addBlocker(attacker, blocker); + } + if (!ComputerUtilCombat.attackerWouldBeDestroyed(ai, attacker, combat)) { + return true; + } + } + } + } + //burn and curse spells float valueBurn = 0; if (dmg > 0) { @@ -956,7 +979,7 @@ public class ComputerUtilCard { valueTempo *= 2; //prefer to cast at opponent EOT } - //interrupt 1:opponent pumping target (only works if the pump target is the chosen best target to begin with) + //interrupt 2:opponent pumping target (only works if the pump target is the chosen best target to begin with) final MagicStack stack = ai.getGame().getStack(); if (!stack.isEmpty()) { final SpellAbility topStack = stack.peekAbility(); diff --git a/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAi.java b/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAi.java index a2788bc07f9..18939220009 100644 --- a/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAi.java @@ -726,6 +726,33 @@ public class ChangeZoneAi extends SpellAbilityAi { // Don't blink cards that will die. aiPermanents = ComputerUtil.getSafeTargets(ai, sa, aiPermanents); + // Removal on blocker to save my creature + if (tgt.getMinTargets(sa.getHostCard(), sa) <= 1) { + if (game.getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS)) { + Combat currCombat = game.getCombat(); + for (Card attacker : currCombat.getAttackers()) { + if (ComputerUtilCombat.attackerWouldBeDestroyed(ai, attacker, currCombat) && !currCombat.getBlockers(attacker).isEmpty()) { + List blockers = currCombat.getBlockers(attacker); + ComputerUtilCard.sortByEvaluateCreature(blockers); + Combat combat = new Combat(ai); + combat.addAttacker(attacker, ai.getOpponent()); + for (Card blocker : blockers) { + combat.addBlocker(attacker, blocker); + } + for (Card blocker : blockers) { + combat.removeFromCombat(blocker); + if (!ComputerUtilCombat.attackerWouldBeDestroyed(ai, attacker, combat) && sa.canTarget(blocker)) { + sa.getTargets().add(blocker); + return true; + } else { + combat.addBlocker(attacker, blocker); + } + } + } + } + } + } + // if it's blink or bounce, try to save my about to die stuff if ((destination.equals(ZoneType.Hand) || (destination.equals(ZoneType.Exile) && (subApi == ApiType.DelayedTrigger || (subApi == ApiType.ChangeZone && subAffected.equals("Remembered")))))