From 0261f259960a4b2f5f44a1bbfa7f916dfa96537d Mon Sep 17 00:00:00 2001 From: Agetian Date: Sat, 16 Sep 2017 10:41:37 +0000 Subject: [PATCH] - AiBlockController: added a routine to try to block a Menace creature with two creatures that don't kill it but neither of which get killed as well. --- .../main/java/forge/ai/AiBlockController.java | 56 +++++++++++++++++-- 1 file changed, 50 insertions(+), 6 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/AiBlockController.java b/forge-ai/src/main/java/forge/ai/AiBlockController.java index 82825232de3..629807c7707 100644 --- a/forge-ai/src/main/java/forge/ai/AiBlockController.java +++ b/forge-ai/src/main/java/forge/ai/AiBlockController.java @@ -361,9 +361,9 @@ public class AiBlockController { final List firstStrikeBlockers = new ArrayList<>(); final List blockGang = new ArrayList<>(); for (Card blocker : blockers) { - if (ComputerUtilCombat.canDestroyBlockerBeforeFirstStrike(blocker, attacker, false)) { - continue; - } + if (ComputerUtilCombat.canDestroyBlockerBeforeFirstStrike(blocker, attacker, false)) { + continue; + } if (blocker.hasFirstStrike() || blocker.hasDoubleStrike()) { firstStrikeBlockers.add(blocker); } @@ -457,9 +457,9 @@ public class AiBlockController { // The attacker will be killed && (absorbedDamage2 + absorbedDamage > attacker.getNetCombatDamage() // only one blocker can be killed - || currentValue + addedValue - 50 <= evalAttackerValue + || currentValue + addedValue - 50 <= evalAttackerValue // or attacker is worth more - || (lifeInDanger && ComputerUtilCombat.lifeInDanger(ai, combat))) + || (lifeInDanger && ComputerUtilCombat.lifeInDanger(ai, combat))) // or life is in danger && CombatUtil.canBlock(attacker, blocker, combat)) { // this is needed for attackers that can't be blocked by @@ -509,7 +509,7 @@ public class AiBlockController { && !(damageNeeded > currentDamage + additionalDamage2 + additionalDamage3) // The attacker will be killed && ((absorbedDamage2 + absorbedDamage > netCombatDamage && absorbedDamage3 + absorbedDamage > netCombatDamage - && absorbedDamage3 + absorbedDamage2 > netCombatDamage) + && absorbedDamage3 + absorbedDamage2 > netCombatDamage) // only one blocker can be killed || currentValue + addedValue2 + addedValue3 - 50 <= evalAttackerValue // or attacker is worth more @@ -536,6 +536,50 @@ public class AiBlockController { } attackersLeft = (new ArrayList<>(currentAttackers)); + + // Try to block a Menace attacker with two blockers, neither of which will die + for (final Card attacker : attackersLeft) { + if (!attacker.hasKeyword("Menace") && !attacker.hasStartOfKeyword("CantBeBlockedByAmount LT2")) { + continue; + } + + blockers = getPossibleBlockers(combat, attacker, blockersLeft, false); + List usableBlockers; + final List blockGang = new ArrayList<>(); + int absorbedDamage; // The amount of damage needed to kill the first blocker + + usableBlockers = CardLists.filter(blockers, new Predicate() { + @Override + public boolean apply(final Card c) { + return c.getNetToughness() > attacker.getNetCombatDamage(); + } + }); + if (usableBlockers.size() < 2) { + return; + } + + final Card leader = ComputerUtilCard.getBestCreatureAI(usableBlockers); + blockGang.add(leader); + usableBlockers.remove(leader); + absorbedDamage = ComputerUtilCombat.getEnoughDamageToKill(leader, attacker.getNetCombatDamage(), attacker, true); + + // consider a double block + for (final Card blocker : usableBlockers) { + final int absorbedDamage2 = ComputerUtilCombat.getEnoughDamageToKill(blocker, attacker.getNetCombatDamage(), attacker, true); + // only do it if neither blocking creature will die + if (absorbedDamage > attacker.getNetCombatDamage() && absorbedDamage2 > attacker.getNetCombatDamage()) { + currentAttackers.remove(attacker); + combat.addBlocker(attacker, blocker); + if (CombatUtil.canBlock(attacker, leader, combat)) { + combat.addBlocker(attacker, leader); + } + break; + } + } + } + + attackersLeft = (new ArrayList<>(currentAttackers)); + } // Bad Trade Blocks (should only be made if life is in danger)