- Updates to Attach and Pump AI.

This commit is contained in:
Sloth
2013-06-30 11:43:59 +00:00
parent 953c62f36c
commit 9641af3973
3 changed files with 24 additions and 17 deletions

View File

@@ -1,5 +1,6 @@
All creatures able to block CARDNAME do so. All creatures able to block CARDNAME do so.
CARDNAME attacks each turn if able. CARDNAME attacks each turn if able.
CARDNAME can attack as though it didn't have defender.
CARDNAME can't be regenerated. CARDNAME can't be regenerated.
CARDNAME must be blocked if able. CARDNAME must be blocked if able.
CantBeBlockedByAmount LT2 CantBeBlockedByAmount LT2

View File

@@ -749,7 +749,7 @@ public class AttachAi extends SpellAbilityAi {
magnetList = CardLists.filter(list, new Predicate<Card>() { magnetList = CardLists.filter(list, new Predicate<Card>() {
@Override @Override
public boolean apply(final Card c) { public boolean apply(final Card c) {
return c.isCreature(); return c.isCreature() && !c.isFortified();
} }
}); });
} }
@@ -876,6 +876,11 @@ public class AttachAi extends SpellAbilityAi {
} }
c = ComputerUtilCard.getBestAI(prefList); c = ComputerUtilCard.getBestAI(prefList);
} else { } else {
for (Card pref : prefList) {
if (pref.isLand() && pref.isUntapped()) {
return pref;
}
}
// If we grant abilities, we may want to put it on something Weak? // If we grant abilities, we may want to put it on something Weak?
// Possibly more defensive? // Possibly more defensive?
c = ComputerUtilCard.getWorstPermanentAI(prefList, false, false, false, false); c = ComputerUtilCard.getWorstPermanentAI(prefList, false, false, false, false);
@@ -1115,7 +1120,7 @@ public class AttachAi extends SpellAbilityAi {
return false; return false;
} }
} else if (keyword.equals("CARDNAME can attack as though it didn't have defender.")) { } else if (keyword.equals("CARDNAME can attack as though it didn't have defender.")) {
if (!card.hasKeyword("Defender") || card.hasKeyword("CARDNAME can attack as though it didn't have defender.")) { if (!card.hasKeyword("Defender") || card.getNetCombatDamage() + powerBonus <= 0) {
return false; return false;
} }
} else if (keyword.equals("Shroud") || keyword.equals("Hexproof")) { } else if (keyword.equals("Shroud") || keyword.equals("Hexproof")) {

View File

@@ -161,6 +161,7 @@ public abstract class PumpAiBase extends SpellAbilityAi {
final Combat combat = game.getCombat(); final Combat combat = game.getCombat();
final PhaseHandler ph = game.getPhaseHandler(); final PhaseHandler ph = game.getPhaseHandler();
final Player opp = ai.getOpponent(); final Player opp = ai.getOpponent();
final int newPower = card.getNetCombatDamage() + attack;
//int defense = getNumDefense(sa); //int defense = getNumDefense(sa);
if (!CardUtil.isStackingKeyword(keyword) && card.hasKeyword(keyword)) { if (!CardUtil.isStackingKeyword(keyword) && card.hasKeyword(keyword)) {
return false; return false;
@@ -174,7 +175,7 @@ public abstract class PumpAiBase extends SpellAbilityAi {
if (evasive) { if (evasive) {
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || combat != null && combat.isAttacking(card)) if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || combat != null && combat.isAttacking(card))
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)
|| card.getNetCombatDamage() <= 0 || newPower <= 0
|| CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)).isEmpty()) { || CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)).isEmpty()) {
return false; return false;
} }
@@ -190,7 +191,7 @@ public abstract class PumpAiBase extends SpellAbilityAi {
Predicate<Card> flyingOrReach = Predicates.or(CardPredicates.hasKeyword("Flying"), CardPredicates.hasKeyword("Reach")); Predicate<Card> flyingOrReach = Predicates.or(CardPredicates.hasKeyword("Flying"), CardPredicates.hasKeyword("Reach"));
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || (combat != null && combat.isAttacking(card))) if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || (combat != null && combat.isAttacking(card)))
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)
|| card.getNetCombatDamage() <= 0 || newPower <= 0
|| !Iterables.any(CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)), || !Iterables.any(CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)),
Predicates.not(flyingOrReach))) { Predicates.not(flyingOrReach))) {
return false; return false;
@@ -205,14 +206,14 @@ public abstract class PumpAiBase extends SpellAbilityAi {
} }
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || (combat != null && combat.isAttacking(card))) if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || (combat != null && combat.isAttacking(card)))
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)
|| card.getNetCombatDamage() <= 0 || newPower <= 0
|| CardLists.getNotKeyword(CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)), || CardLists.getNotKeyword(CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)),
"Horsemanship").isEmpty()) { "Horsemanship").isEmpty()) {
return false; return false;
} }
} else if (keyword.endsWith("Haste")) { } else if (keyword.endsWith("Haste")) {
if (!card.hasSickness() || ph.isPlayerTurn(opp) || card.isTapped() if (!card.hasSickness() || ph.isPlayerTurn(opp) || card.isTapped()
|| card.getNetCombatDamage() <= 0 || newPower <= 0
|| card.hasKeyword("CARDNAME can attack as though it had haste.") || card.hasKeyword("CARDNAME can attack as though it had haste.")
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)
|| !CombatUtil.canAttackNextTurn(card)) { || !CombatUtil.canAttackNextTurn(card)) {
@@ -243,13 +244,13 @@ public abstract class PumpAiBase extends SpellAbilityAi {
} else if (combatRelevant) { } else if (combatRelevant) {
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || (combat != null && combat.isAttacking(card))) if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || (combat != null && combat.isAttacking(card)))
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS)
|| (opp.getCreaturesInPlay().size() < 1) || opp.getCreaturesInPlay().size() < 1
|| CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)).isEmpty()) { || CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)).isEmpty()) {
return false; return false;
} }
} else if (keyword.equals("Double Strike")) { } else if (keyword.equals("Double Strike")) {
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || (combat != null && combat.isAttacking(card))) if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || (combat != null && combat.isAttacking(card)))
|| card.getNetCombatDamage() <= 0 || newPower <= 0
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS)) { || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS)) {
return false; return false;
} }
@@ -270,12 +271,12 @@ public abstract class PumpAiBase extends SpellAbilityAi {
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || (combat != null && combat.isAttacking(card))) if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || (combat != null && combat.isAttacking(card)))
|| !CombatUtil.canBeBlocked(card, opp) || !CombatUtil.canBeBlocked(card, opp)
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)
|| card.getNetCombatDamage() + attack <= 1 || newPower <= 1
|| CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)).isEmpty()) { || CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)).isEmpty()) {
return false; return false;
} }
} else if (keyword.equals("Infect")) { } else if (keyword.equals("Infect")) {
if (card.getNetCombatDamage() <= 0) { if (newPower <= 0) {
return false; return false;
} }
if (combat != null && combat.isBlocking(card)) { if (combat != null && combat.isBlocking(card)) {
@@ -287,12 +288,12 @@ public abstract class PumpAiBase extends SpellAbilityAi {
return false; return false;
} }
} else if (keyword.endsWith("Wither")) { } else if (keyword.endsWith("Wither")) {
if (card.getNetCombatDamage() <= 0) { if (newPower <= 0) {
return false; return false;
} }
return combat != null && ( combat.isBlocking(card) || (combat.isAttacking(card) && combat.isBlocked(card)) ); return combat != null && ( combat.isBlocking(card) || (combat.isAttacking(card) && combat.isBlocked(card)) );
} else if (keyword.equals("Lifelink")) { } else if (keyword.equals("Lifelink")) {
if (card.getNetCombatDamage() <= 0) { if (newPower <= 0) {
return false; return false;
} }
return combat != null && ( combat.isAttacking(card) || combat.isBlocking(card) ); return combat != null && ( combat.isAttacking(card) || combat.isBlocking(card) );
@@ -335,7 +336,7 @@ public abstract class PumpAiBase extends SpellAbilityAi {
} else if (keyword.equals("Islandwalk")) { } else if (keyword.equals("Islandwalk")) {
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || (combat != null && combat.isAttacking(card))) if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || (combat != null && combat.isAttacking(card)))
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)
|| card.getNetCombatDamage() <= 0 || newPower <= 0
|| CardLists.getType(opp.getLandsInPlay(), "Island").isEmpty() || CardLists.getType(opp.getLandsInPlay(), "Island").isEmpty()
|| CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)).isEmpty()) { || CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)).isEmpty()) {
return false; return false;
@@ -343,7 +344,7 @@ public abstract class PumpAiBase extends SpellAbilityAi {
} else if (keyword.equals("Swampwalk")) { } else if (keyword.equals("Swampwalk")) {
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || (combat != null && combat.isAttacking(card))) if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || (combat != null && combat.isAttacking(card)))
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)
|| card.getNetCombatDamage() <= 0 || newPower <= 0
|| CardLists.getType(opp.getLandsInPlay(), "Swamp").isEmpty() || CardLists.getType(opp.getLandsInPlay(), "Swamp").isEmpty()
|| CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)).isEmpty()) { || CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)).isEmpty()) {
return false; return false;
@@ -351,7 +352,7 @@ public abstract class PumpAiBase extends SpellAbilityAi {
} else if (keyword.equals("Mountainwalk")) { } else if (keyword.equals("Mountainwalk")) {
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || (combat != null && combat.isAttacking(card))) if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || (combat != null && combat.isAttacking(card)))
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)
|| card.getNetCombatDamage() <= 0 || newPower <= 0
|| CardLists.getType(opp.getLandsInPlay(), "Mountain").isEmpty() || CardLists.getType(opp.getLandsInPlay(), "Mountain").isEmpty()
|| CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)).isEmpty()) { || CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)).isEmpty()) {
return false; return false;
@@ -359,7 +360,7 @@ public abstract class PumpAiBase extends SpellAbilityAi {
} else if (keyword.equals("Forestwalk")) { } else if (keyword.equals("Forestwalk")) {
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || (combat != null && combat.isAttacking(card))) if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || (combat != null && combat.isAttacking(card)))
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)
|| card.getNetCombatDamage() <= 0 || newPower <= 0
|| CardLists.getType(opp.getLandsInPlay(), "Forest").isEmpty() || CardLists.getType(opp.getLandsInPlay(), "Forest").isEmpty()
|| CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)).isEmpty()) { || CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)).isEmpty()) {
return false; return false;
@@ -367,7 +368,7 @@ public abstract class PumpAiBase extends SpellAbilityAi {
} else if (keyword.endsWith("CARDNAME can attack as though it didn't have defender.")) { } else if (keyword.endsWith("CARDNAME can attack as though it didn't have defender.")) {
if (!ph.isPlayerTurn(ai) || !card.hasKeyword("Defender") if (!ph.isPlayerTurn(ai) || !card.hasKeyword("Defender")
|| ph.getPhase().isAfter(PhaseType.COMBAT_BEGIN) || ph.getPhase().isAfter(PhaseType.COMBAT_BEGIN)
|| card.isTapped()) { || card.isTapped() || newPower <= 0) {
return false; return false;
} }
} }