From e382b29212f44f76dc9049519dbc62b1419d30af Mon Sep 17 00:00:00 2001 From: excessum Date: Sat, 10 May 2014 06:28:01 +0000 Subject: [PATCH] - Improved AI logic when attacking by applying AiBlockController logic block for each attacker --- .../java/forge/ai/AiAttackController.java | 3 ++ .../main/java/forge/ai/AiBlockController.java | 33 ++++++++++++++++--- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/AiAttackController.java b/forge-ai/src/main/java/forge/ai/AiAttackController.java index a3be3f9cf3b..9170afd7ece 100644 --- a/forge-ai/src/main/java/forge/ai/AiAttackController.java +++ b/forge-ai/src/main/java/forge/ai/AiAttackController.java @@ -1005,6 +1005,9 @@ public class AiAttackController { } } } + if (AiBlockController.canBeBlockedProfitably(defendingOpponent, attacker)) { + canKillAllDangerous = false; + } // if the creature cannot block and can kill all opponents they might as // well attack, they do nothing staying back diff --git a/forge-ai/src/main/java/forge/ai/AiBlockController.java b/forge-ai/src/main/java/forge/ai/AiBlockController.java index ca0ef9b7d19..95ae079e512 100644 --- a/forge-ai/src/main/java/forge/ai/AiBlockController.java +++ b/forge-ai/src/main/java/forge/ai/AiBlockController.java @@ -652,10 +652,10 @@ public class AiBlockController { /** Assigns blockers for the provided combat instance (in favor of player passes to ctor) */ public void assignBlockers(final Combat combat) { - assignBlockers(combat, null); + assignBlockers(combat, null, null); } - public void assignBlockers(final Combat combat, Card evalBlocker) { + public void assignBlockers(final Combat combat, Card evalBlocker, Card evalAttacker) { List possibleBlockers = null; if (evalBlocker == null) { @@ -664,8 +664,12 @@ public class AiBlockController { possibleBlockers = new ArrayList(); possibleBlockers.add(evalBlocker); } - - attackers = sortPotentialAttackers(combat); + if (evalAttacker == null) { + attackers = sortPotentialAttackers(combat); + } else { + attackers = new ArrayList(); + attackers.add(evalAttacker); + } if (attackers.isEmpty()) { return; @@ -843,10 +847,16 @@ public class AiBlockController { return first; } + /** + * Decide if a creature is going to be used as a blocker (is only used for AnimateAi so far) + * @param ai controller of creature + * @param blocker creature to be evaluated (must NOT already be in combat) + * @return creature will be a blocker + */ public static boolean shouldThisBlock(final Player ai, Card blocker) { AiBlockController aiBlk = new AiBlockController(ai); Combat combat = ai.getGame().getCombat(); - aiBlk.assignBlockers(combat, blocker); + aiBlk.assignBlockers(combat, blocker, null); if (combat.getAllBlockers().isEmpty()) { return false; } else { @@ -854,4 +864,17 @@ public class AiBlockController { return true; } } + /** + * Check if an attacker can be blocked profitably (ie. kill attacker) + * @param ai controller of attacking creature + * @param attacker attacking creature to evaluate + * @return attacker will die + */ + public static boolean canBeBlockedProfitably(final Player ai, Card attacker) { + AiBlockController aiBlk = new AiBlockController(ai); + Combat combat = new Combat(ai); + combat.addAttacker(attacker, ai); + aiBlk.assignBlockers(combat, null, attacker); + return ComputerUtilCombat.attackerWouldBeDestroyed(ai, attacker, combat); + } }