diff --git a/forge-ai/src/main/java/forge/ai/AiAttackController.java b/forge-ai/src/main/java/forge/ai/AiAttackController.java index 89630290847..3870271a599 100644 --- a/forge-ai/src/main/java/forge/ai/AiAttackController.java +++ b/forge-ai/src/main/java/forge/ai/AiAttackController.java @@ -589,10 +589,9 @@ public class AiAttackController { // TODO might want to only calculate that if it's needed // TODO might want to factor in isManaSourceReserved int myFreeMana = ComputerUtilMana.getAvailableManaEstimate(ai, !nextTurn); - // skip attackers exceeding the attack tax + // skip attackers exceeding the attack tax that's payable // (this prevents the AI from only making a partial attack that could backfire) - - Pair tramplerFirst = getDamageFromBlockingTramplers(blockedAttackers, remainingAttackers, myFreeMana); + final Pair tramplerFirst = getDamageFromBlockingTramplers(blockedAttackers, remainingBlockers, myFreeMana); int trampleDamage = tramplerFirst.getLeft(); int tramplerTaxPaid = tramplerFirst.getRight(); @@ -623,7 +622,8 @@ public class AiAttackController { unblockedAttackers.removeAll(unblockableWithPaying); totalCombatDamage = dmgUnblockableAfterPaying; // recalculate the trampler damage with the reduced mana available now - trampleDamage = getDamageFromBlockingTramplers(blockedAttackers, remainingAttackers, myFreeMana - unblockableAttackTax).getLeft(); + myFreeMana -= unblockableAttackTax; + trampleDamage = getDamageFromBlockingTramplers(blockedAttackers, remainingBlockers, myFreeMana).getLeft(); } else { unblockedAttackers = unblockableWithoutCost; myFreeMana -= tramplerTaxPaid; diff --git a/forge-ai/src/main/java/forge/ai/AiBlockController.java b/forge-ai/src/main/java/forge/ai/AiBlockController.java index 92b54c16901..6768ab5f700 100644 --- a/forge-ai/src/main/java/forge/ai/AiBlockController.java +++ b/forge-ai/src/main/java/forge/ai/AiBlockController.java @@ -38,6 +38,7 @@ import forge.game.card.CardPredicates; import forge.game.card.CounterEnumType; import forge.game.combat.Combat; import forge.game.combat.CombatUtil; +import forge.game.cost.Cost; import forge.game.keyword.Keyword; import forge.game.player.Player; import forge.game.spellability.SpellAbility; @@ -1064,6 +1065,8 @@ public class AiBlockController { reinforceBlockersToKill(combat); } + lifeInDanger |= removeUnpayableBlocks(combat); + // == 2. If the AI life would still be in danger make a safer approach == if (lifeInDanger && ComputerUtilCombat.lifeInDanger(ai, combat)) { clearBlockers(combat, possibleBlockers); // reset every block assignment @@ -1339,4 +1342,26 @@ public class AiBlockController { && (creatureParityOrAllowedDiff || wantToTradeWithCreatInHand) && (MyRandom.percentTrue(chance) || wantToSavePlaneswalker); } + + private boolean removeUnpayableBlocks(final Combat combat) { + int myFreeMana = ComputerUtilMana.getAvailableManaEstimate(ai); + int currentBlockTax = 0; + final List oldBlockers = combat.getAllBlockers(); + CardLists.sortByPowerDesc(oldBlockers); + boolean modified = false; + + for (final Card blocker : oldBlockers) { + if (blocker.getController() == ai) { + Cost tax = CombatUtil.getBlockCost(blocker.getGame(), blocker, combat.getAttackersBlockedBy(blocker).get(0)); + int taxCMC = tax != null ? tax.getCostMana().getMana().getCMC() : 0; + if (myFreeMana < currentBlockTax + taxCMC) { + combat.removeFromCombat(blocker); + modified = true; + continue; + } + currentBlockTax += taxCMC; + } + } + return modified; + } }