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.
This commit is contained in:
Hanmac
2016-05-16 15:26:07 +00:00
parent 692bfd7e81
commit 59ce1abe00
4 changed files with 52 additions and 28 deletions

View File

@@ -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"); 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); 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;
}
} }

View File

@@ -1412,20 +1412,6 @@ public class AttachAi extends SpellAbilityAi {
return true; 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 @Override
public boolean confirmAction(Player player, SpellAbility sa, PlayerActionConfirmMode mode, String message) { public boolean confirmAction(Player player, SpellAbility sa, PlayerActionConfirmMode mode, String message) {
return true; return true;

View File

@@ -43,6 +43,15 @@ public class LegendaryRuleAi extends SpellAbilityAi {
} }
} }
return best; 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; return firstOption;

View File

@@ -5,28 +5,51 @@ import forge.ai.SpellAbilityAi;
import forge.game.GlobalRuleChange; import forge.game.GlobalRuleChange;
import forge.game.card.Card; import forge.game.card.Card;
import forge.game.card.CardState; import forge.game.card.CardState;
import forge.game.card.CounterType;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbility;
import forge.game.zone.ZoneType;
public class SetStateAi extends SpellAbilityAi { public class SetStateAi extends SpellAbilityAi {
@Override @Override
protected boolean canPlayAI(Player aiPlayer, SpellAbility sa) { protected boolean checkApiLogic(final Player aiPlayer, final SpellAbility sa) {
// Prevent transform into legendary creature if copy already exists
final Card source = sa.getHostCard(); 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 // Check first if Legend Rule does still apply
if (!aiPlayer.getGame().getStaticEffects().getGlobalRuleChange(GlobalRuleChange.noLegendRule)) { 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(); final CardState other = source.getAlternateState();
if (other != null && other.getType().isLegendary() && aiPlayer.isCardInPlay(other.getName())) { if (other != null && other.getType().isLegendary() && aiPlayer.isCardInPlay(other.getName())) {
if (!other.getType().isCreature()) {
return false; 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"))) { if (sa.getTargetRestrictions() == null && "Transform".equals(sa.getParam("Mode"))) {
return !source.hasKeyword("CARDNAME can't transform"); return !source.hasKeyword("CARDNAME can't transform");
} }
if ("Flip".equals(sa.getParam("Mode"))) {
return true;
}
return false; return false;
} }
@@ -36,13 +59,4 @@ public class SetStateAi extends SpellAbilityAi {
// states more powerful // states more powerful
return !sa.getHostCard().isInAlternateState(); 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;
}
} }