From e65adb6dffc4a7fb2cd46823771d5d1b70d706d2 Mon Sep 17 00:00:00 2001 From: Agetian Date: Sun, 7 Sep 2014 05:56:20 +0000 Subject: [PATCH] - Improved the AttachAi to account for cases when attaching a card is useless even though basic evaluation of the target may show otherwise (e,g, it's useless to equip a creature if this creature can't attack or block or if it's tapped and won't untap normally during the untap step, even if the said creature is evaluated as the best creature for its high CMC in ComputerUtilCard.evaluateCreature). --- .../main/java/forge/ai/ability/AttachAi.java | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/forge-ai/src/main/java/forge/ai/ability/AttachAi.java b/forge-ai/src/main/java/forge/ai/ability/AttachAi.java index 9fa5c4a62a2..139e6d6693b 100644 --- a/forge-ai/src/main/java/forge/ai/ability/AttachAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/AttachAi.java @@ -1085,6 +1085,12 @@ public class AttachAi extends SpellAbilityAi { c = attachAIHighestEvaluationPreference(prefList); } + // Consider exceptional cases which break the normal evaluation rules + // (e.g. do not waste Equipment on a creature that can neither attack nor block) + if (!isUsefulAttachAction(c, sa)) { + return null; + } + return c; } @@ -1266,6 +1272,38 @@ public class AttachAi extends SpellAbilityAi { return true; } + /** + * Checks if it is useful to execute the attach action given the current context. + * + * @param card + * the card + * @param sa SpellAbility + * @return true, if the action is useful (beneficial) in the current minimal context (Card vs. Attach SpellAbility) + */ + private static boolean isUsefulAttachAction(Card c, SpellAbility sa) { + if (c == null) { + return false; + } + if (sa.getHostCard() == null) { + // FIXME: Not sure what should the resolution be if a SpellAbility has no host card. This should + // not happen normally. Possibly remove this block altogether? (if it's an impossible condition). + System.out.println("AttachAi: isUsefulAttachAction unexpectedly called with SpellAbility with no host card. Assuming it's a determined useful action."); + return true; + } + + ArrayList cardTypes = sa.getHostCard().getType(); + + if (cardTypes.contains("Equipment") && c.hasKeyword("CARDNAME can't attack or block.")) { + // useless to equip a creature that can't attack or block. + return false; + } else if (cardTypes.contains("Equipment") && c.isTapped() && c.hasKeyword("CARDNAME doesn't untap during your untap step.")) { + // useless to equip a creature that won't untap and is tapped. + return false; + } + + return true; + } + @Override public boolean confirmAction(Player player, SpellAbility sa, PlayerActionConfirmMode mode, String message) { return true;