- Added a more conservative version of AILogic PayEnergy for PutCounter AI that only pays energy if the creature is in combat (attacking/blocking) or if there's more energy available than the most expensive energy cost of a permanent SA on the battlefield requires plus whatever the PutCounter SA requires.

- Set this logic for Longtusk Cub and Bristling Hydra.
- TODO: maybe somehow teach the AI to pay energy if it can save the creature from lethal damage from a spell?
This commit is contained in:
Agetian
2017-06-16 10:30:13 +00:00
parent 146e21c8df
commit d4c4afcf0b
5 changed files with 49 additions and 3 deletions

View File

@@ -40,6 +40,8 @@ import forge.game.card.CardUtil;
import forge.game.card.CounterType; import forge.game.card.CounterType;
import forge.game.combat.Combat; import forge.game.combat.Combat;
import forge.game.combat.CombatUtil; import forge.game.combat.CombatUtil;
import forge.game.cost.CostPart;
import forge.game.cost.CostPayEnergy;
import forge.game.keyword.Keyword; import forge.game.keyword.Keyword;
import forge.game.phase.PhaseHandler; import forge.game.phase.PhaseHandler;
import forge.game.phase.PhaseType; import forge.game.phase.PhaseType;
@@ -1587,4 +1589,28 @@ public class ComputerUtilCard {
public static boolean isPresentOnBattlefield(final Game game, final String cardName) { public static boolean isPresentOnBattlefield(final Game game, final String cardName) {
return !CardLists.filter(game.getCardsIn(ZoneType.Battlefield), CardPredicates.nameEquals(cardName)).isEmpty(); return !CardLists.filter(game.getCardsIn(ZoneType.Battlefield), CardPredicates.nameEquals(cardName)).isEmpty();
} }
public static int getMaxSAEnergyCostOnBattlefield(final Player ai) {
// returns the maximum energy cost of an ability that permanents on the battlefield under AI's control have
CardCollectionView otb = ai.getCardsIn(ZoneType.Battlefield);
int maxEnergyCost = 0;
for (Card c : otb) {
for (SpellAbility sa : c.getSpellAbilities()) {
if (sa.getPayCosts() == null) {
continue;
}
CostPayEnergy energyCost = sa.getPayCosts().getCostEnergy();
if (energyCost != null) {
int amount = energyCost.convertAmount();
if (amount > maxEnergyCost) {
maxEnergyCost = amount;
}
}
}
}
return maxEnergyCost;
}
} }

View File

@@ -217,8 +217,19 @@ public class CountersPutAi extends SpellAbilityAi {
} }
if ("PayEnergy".equals(sa.getParam("AILogic"))) { if ("PayEnergy".equals(sa.getParam("AILogic"))) {
return false;
}
if ("PayEnergyConservatively".equals(sa.getParam("AILogic"))) {
if (ai.getGame().getCombat() != null && sa.getHostCard() != null) {
if (ai.getGame().getCombat().isAttacking(sa.getHostCard()) || ai.getGame().getCombat().isBlocking(sa.getHostCard())) {
return true; return true;
} }
}
if (ai.getCounters(CounterType.ENERGY) > ComputerUtilCard.getMaxSAEnergyCostOnBattlefield(ai) + sa.getPayCosts().getCostEnergy().convertAmount()) {
return true;
}
}
if (sa.getConditions() != null && !sa.getConditions().areMet(sa) && sa.getSubAbility() == null) { if (sa.getConditions() != null && !sa.getConditions().areMet(sa) && sa.getSubAbility() == null) {
return false; return false;

View File

@@ -494,6 +494,15 @@ public class Cost {
return null; return null;
} }
public final CostPayEnergy getCostEnergy() {
for (final CostPart part : this.costParts) {
if (part instanceof CostPayEnergy) {
return (CostPayEnergy) part;
}
}
return null;
}
/** /**
* <p> * <p>
* refundPaidCost. * refundPaidCost.

View File

@@ -4,7 +4,7 @@ Types:Creature Hydra
PT:4/3 PT:4/3
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigEnergy | TriggerDescription$ When CARDNAME enters the battlefield, you get {E}{E}{E} (three energy counters). T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigEnergy | TriggerDescription$ When CARDNAME enters the battlefield, you get {E}{E}{E} (three energy counters).
SVar:TrigEnergy:DB$ PutCounter | Defined$ You | CounterType$ ENERGY | CounterNum$ 3 SVar:TrigEnergy:DB$ PutCounter | Defined$ You | CounterType$ ENERGY | CounterNum$ 3
A:AB$ PutCounter | Cost$ PayEnergy<3> | CounterType$ P1P1 | CounterNum$ 1 | SubAbility$ DBPump | SpellDescription$ Put a +1/+1 counter on CARDNAME. It gains hexproof until end of turn. A:AB$ PutCounter | Cost$ PayEnergy<3> | CounterType$ P1P1 | CounterNum$ 1 | SubAbility$ DBPump | AILogic$ PayEnergyConservatively | SpellDescription$ Put a +1/+1 counter on CARDNAME. It gains hexproof until end of turn.
SVar:DBPump:DB$Pump | Defined$ Self | KW$ Hexproof SVar:DBPump:DB$Pump | Defined$ Self | KW$ Hexproof
SVar:Picture:http://www.wizards.com/global/images/magic/general/bristling_hydra.jpg SVar:Picture:http://www.wizards.com/global/images/magic/general/bristling_hydra.jpg
Oracle:When Bristling Hydra enters the battlefield, you gain {E}{E}{E} (three energy counters).\nPay {E}{E}{E}: Put a +1/+1 counter on Bristling Hydra. It gains hexproof until end of turn. Oracle:When Bristling Hydra enters the battlefield, you gain {E}{E}{E} (three energy counters).\nPay {E}{E}{E}: Put a +1/+1 counter on Bristling Hydra. It gains hexproof until end of turn.

View File

@@ -4,7 +4,7 @@ Types:Creature Cat
PT:2/2 PT:2/2
T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | Execute$ TrigEnergy | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, you get {E}{E} (two energy counters). T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | Execute$ TrigEnergy | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, you get {E}{E} (two energy counters).
SVar:TrigEnergy:DB$PutCounter | Defined$ You | CounterType$ ENERGY | CounterNum$ 2 SVar:TrigEnergy:DB$PutCounter | Defined$ You | CounterType$ ENERGY | CounterNum$ 2
A:AB$ PutCounter | Cost$ PayEnergy<2> | CounterType$ P1P1 | CounterNum$ 1 | SpellDescription$ Put a +1/+1 counter on CARDNAME. A:AB$ PutCounter | Cost$ PayEnergy<2> | CounterType$ P1P1 | CounterNum$ 1 | AILogic$ PayEnergyConservatively | SpellDescription$ Put a +1/+1 counter on CARDNAME.
DeckHints:Ability$Energy DeckHints:Ability$Energy
DeckHas:Ability$Counters DeckHas:Ability$Counters
SVar:Picture:http://www.wizards.com/global/images/magic/general/longtusk_cub.jpg SVar:Picture:http://www.wizards.com/global/images/magic/general/longtusk_cub.jpg