From 59ce1abe0033136a6ffdce6f49bb82fa1d961456 Mon Sep 17 00:00:00 2001 From: Hanmac Date: Mon, 16 May 2016 15:26:07 +0000 Subject: [PATCH] AI: move check for isUseless from AttachAi to SpellAbilityAi update SetStateAi to use new canPlay() add check for useless Legendary in SetStateAi (try to replace Legendary if current one is useless) add extra check for Legendary KI creatures, more counters are better. --- .../main/java/forge/ai/SpellAbilityAi.java | 15 +++++++ .../main/java/forge/ai/ability/AttachAi.java | 14 ------- .../forge/ai/ability/LegendaryRuleAi.java | 9 ++++ .../java/forge/ai/ability/SetStateAi.java | 42 ++++++++++++------- 4 files changed, 52 insertions(+), 28 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/SpellAbilityAi.java b/forge-ai/src/main/java/forge/ai/SpellAbilityAi.java index 6437e024b2a..b94c167629c 100644 --- a/forge-ai/src/main/java/forge/ai/SpellAbilityAi.java +++ b/forge-ai/src/main/java/forge/ai/SpellAbilityAi.java @@ -239,4 +239,19 @@ public abstract class SpellAbilityAi { System.err.println("Warning: default (ie. inherited from base class) implementation of chooseSingleEntity is used for " + this.getClass().getName() + ". Consider declaring an overloaded method"); return Iterables.getFirst(options, null); } + + + protected static boolean isUselessCreature(Player ai, Card c) { + if (c == null) { + return true; + } + + if (c.hasKeyword("CARDNAME can't attack or block.") + || (c.hasKeyword("CARDNAME doesn't untap during your untap step.") && c.isTapped()) + || (c.getOwner() == ai && ai.getOpponents().contains(c.getController()))) { + return true; + } + + return false; + } } 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 491fd230181..ca68016584a 100644 --- a/forge-ai/src/main/java/forge/ai/ability/AttachAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/AttachAi.java @@ -1412,20 +1412,6 @@ public class AttachAi extends SpellAbilityAi { return true; } - private static boolean isUselessCreature(Player ai, Card c) { - if (c == null) { - return true; - } - - if (c.hasKeyword("CARDNAME can't attack or block.") - || (c.hasKeyword("CARDNAME doesn't untap during your untap step.") && c.isTapped()) - || (c.getOwner() == ai && ai.getOpponents().contains(c.getController()))) { - return true; - } - - return false; - } - @Override public boolean confirmAction(Player player, SpellAbility sa, PlayerActionConfirmMode mode, String message) { return true; diff --git a/forge-ai/src/main/java/forge/ai/ability/LegendaryRuleAi.java b/forge-ai/src/main/java/forge/ai/ability/LegendaryRuleAi.java index 49e4e483b8a..9246024dfb8 100644 --- a/forge-ai/src/main/java/forge/ai/ability/LegendaryRuleAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/LegendaryRuleAi.java @@ -43,6 +43,15 @@ public class LegendaryRuleAi extends SpellAbilityAi { } } return best; + } else if (firstOption.getCounters(CounterType.KI) > 0) { + // Extra Rule for KI counter + Card best = firstOption; + for (Card c : options) { + if (c.getCounters(CounterType.KI) > best.getCounters(CounterType.KI)) { + best = c; + } + } + return best; } return firstOption; diff --git a/forge-ai/src/main/java/forge/ai/ability/SetStateAi.java b/forge-ai/src/main/java/forge/ai/ability/SetStateAi.java index 323aa5ebfb7..7a3425476fc 100644 --- a/forge-ai/src/main/java/forge/ai/ability/SetStateAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/SetStateAi.java @@ -5,28 +5,51 @@ import forge.ai.SpellAbilityAi; import forge.game.GlobalRuleChange; import forge.game.card.Card; import forge.game.card.CardState; +import forge.game.card.CounterType; import forge.game.player.Player; import forge.game.spellability.SpellAbility; +import forge.game.zone.ZoneType; public class SetStateAi extends SpellAbilityAi { @Override - protected boolean canPlayAI(Player aiPlayer, SpellAbility sa) { - // Prevent transform into legendary creature if copy already exists + protected boolean checkApiLogic(final Player aiPlayer, final SpellAbility sa) { final Card source = sa.getHostCard(); - + + if (!source.hasAlternateState()) { + System.err.println("Warning: SetState without ALTERNATE on " + source.getName() + "."); + return false; + } + + // Prevent transform into legendary creature if copy already exists // Check first if Legend Rule does still apply if (!aiPlayer.getGame().getStaticEffects().getGlobalRuleChange(GlobalRuleChange.noLegendRule)) { - // check if the other side is legendary and if such Card already is in Play + // check if the other side is legendary and if such Card already is in Play final CardState other = source.getAlternateState(); + if (other != null && other.getType().isLegendary() && aiPlayer.isCardInPlay(other.getName())) { - return false; + if (!other.getType().isCreature()) { + return false; + } + + final Card othercard = aiPlayer.getCardsIn(ZoneType.Battlefield, other.getName()).getFirst(); + + // for legendary KI counter creatures + if (othercard.getCounters(CounterType.KI) >= source.getCounters(CounterType.KI)) { + // if the other legendary is useless try to replace it + if (!isUselessCreature(aiPlayer, othercard)) { + return false; + } + } } } if (sa.getTargetRestrictions() == null && "Transform".equals(sa.getParam("Mode"))) { return !source.hasKeyword("CARDNAME can't transform"); } + if ("Flip".equals(sa.getParam("Mode"))) { + return true; + } return false; } @@ -36,13 +59,4 @@ public class SetStateAi extends SpellAbilityAi { // states more powerful return !sa.getHostCard().isInAlternateState(); } - - - /* (non-Javadoc) - * @see forge.card.abilityfactory.SpellAiLogic#doTriggerAINoCost(forge.game.player.Player, java.util.Map, forge.card.spellability.SpellAbility, boolean) - */ - @Override - protected boolean doTriggerAINoCost(Player aiPlayer, SpellAbility sa, boolean mandatory) { - return true; - } }