From 03c0794b484b4ff6ffbc54948e56dedb49dc51bd Mon Sep 17 00:00:00 2001 From: Agetian Date: Fri, 15 Sep 2017 15:08:31 +0000 Subject: [PATCH] - Some improvements to the Aristocrats and Electrostatic Pummeler AI logic. --- .../src/main/java/forge/ai/SpecialCardAi.java | 18 ++++++++++++------ .../src/main/java/forge/ai/ability/PumpAi.java | 9 ++++----- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/SpecialCardAi.java b/forge-ai/src/main/java/forge/ai/SpecialCardAi.java index b89b9c8a56a..a84303c48d3 100644 --- a/forge-ai/src/main/java/forge/ai/SpecialCardAi.java +++ b/forge-ai/src/main/java/forge/ai/SpecialCardAi.java @@ -287,12 +287,11 @@ public class SpecialCardAi { // Electrostatic Pummeler public static class ElectrostaticPummeler { - // TODO: use getNetCombatDamage() instead of getNetPower() for cases where damage is assigned by toughness public static boolean consider(final Player ai, final SpellAbility sa) { final Card source = sa.getHostCard(); Game game = ai.getGame(); Combat combat = game.getCombat(); - Pair predictedPT = getPumpedPT(ai, source.getNetPower(), source.getNetToughness()); + Pair predictedPT = getPumpedPT(ai, source.getNetCombatDamage(), source.getNetToughness()); // Try to save the Pummeler from death by pumping it if it's threatened with a damage spell if (ComputerUtil.predictThreatenedObjects(ai, null, true).contains(source)) { @@ -330,7 +329,7 @@ public class SpecialCardAi { boolean cantDie = ComputerUtilCombat.attackerCantBeDestroyedInCombat(ai, source); CardCollection opposition = isBlocking ? combat.getAttackersBlockedBy(source) : combat.getBlockers(source); - int oppP = Aggregates.sum(opposition, CardPredicates.Accessors.fnGetNetPower); + int oppP = Aggregates.sum(opposition, CardPredicates.Accessors.fnGetAttack); int oppT = Aggregates.sum(opposition, CardPredicates.Accessors.fnGetNetToughness); boolean oppHasFirstStrike = false; @@ -340,7 +339,13 @@ public class SpecialCardAi { if (!isBlocking && combat.getDefenderByAttacker(source) instanceof Card) { int loyalty = ((Card)combat.getDefenderByAttacker(source)).getCounters(CounterType.LOYALTY); - if (source.getNetPower() >= oppT + loyalty) { + int totalDamageToPW = 0; + for (Card atk : (combat.getAttackersOf(combat.getDefenderByAttacker(source)))) { + if (combat.isUnblocked(atk)) { + totalDamageToPW += atk.getNetCombatDamage(); + } + } + if (totalDamageToPW >= oppT + loyalty) { // Already enough damage to take care of the planeswalker return false; } @@ -348,6 +353,7 @@ public class SpecialCardAi { // Can pump to kill the planeswalker, go for it return true; } + } for (Card c : opposition) { @@ -378,7 +384,7 @@ public class SpecialCardAi { // Can't pump enough to kill the blockers and survive, don't pump return false; } - if (source.getNetPower() > oppT && source.getNetToughness() > oppP) { + if (source.getNetCombatDamage() > oppT && source.getNetToughness() > oppP) { // Already enough to kill the blockers and survive, don't overpump return false; } @@ -405,7 +411,7 @@ public class SpecialCardAi { } } - Pair predictedPT = getPumpedPT(ai, source.getNetPower(), source.getNetToughness()); + Pair predictedPT = getPumpedPT(ai, source.getNetCombatDamage(), source.getNetToughness()); int oppT = Aggregates.sum(potentialBlockers, CardPredicates.Accessors.fnGetNetToughness); if (potentialBlockers.isEmpty() || (sa.getHostCard().hasKeyword("Trample") && predictedPT.getLeft() - oppT >= oppLife)) { diff --git a/forge-ai/src/main/java/forge/ai/ability/PumpAi.java b/forge-ai/src/main/java/forge/ai/ability/PumpAi.java index 48f9466e4dd..f5dc5b855a2 100644 --- a/forge-ai/src/main/java/forge/ai/ability/PumpAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/PumpAi.java @@ -739,7 +739,6 @@ public class PumpAi extends PumpAiBase { public boolean doAristocratLogic(final SpellAbility sa, final Player ai) { // A logic for cards that say "Sacrifice a creature: CARDNAME gets +X/+X until EOT" - // TODO: use getNetCombatDamage() instead of getNetPower() for cases where damage is assigned by toughness final Game game = ai.getGame(); final Combat combat = game.getCombat(); final Card source = sa.getHostCard(); @@ -804,11 +803,11 @@ public class PumpAi extends PumpAiBase { final boolean isInfect = source.hasKeyword("Infect"); // Flesh-Eater Imp final int lethalDmg = isInfect ? 10 - defPlayer.getPoisonCounters() : defPlayer.getLife(); - final int numCreatsToSac = (lethalDmg - source.getNetPower()) / powerBonus; + final int numCreatsToSac = (lethalDmg - source.getNetCombatDamage()) / powerBonus; if (defTappedOut || numCreatsToSac < numOtherCreats / 2) { - return source.getNetPower() < lethalDmg - && source.getNetPower() + numOtherCreats * powerBonus >= lethalDmg; + return source.getNetCombatDamage() < lethalDmg + && source.getNetCombatDamage() + numOtherCreats * powerBonus >= lethalDmg; } else { return false; } @@ -833,7 +832,7 @@ public class PumpAi extends PumpAiBase { final int DefP = Aggregates.sum(combat.getBlockers(source), CardPredicates.Accessors.fnGetNetPower); // Make sure we don't over-sacrifice, only sac until we can survive and kill a creature - return source.getNetToughness() - source.getDamage() <= DefP || source.getNetPower() < minDefT; + return source.getNetToughness() - source.getDamage() <= DefP || source.getNetCombatDamage() < minDefT; } } else { // We can't deal lethal, check if there's any sac fodder than can be used for other circumstances