- Some improvements for Pump AI related to pump spells with pure energy cost, makes Electrostatic Pummeler a little better in AI's hands.

This commit is contained in:
Agetian
2017-08-23 14:45:01 +00:00
parent 7a8267a772
commit 989331cbb4
2 changed files with 55 additions and 8 deletions

View File

@@ -60,11 +60,7 @@ import forge.game.card.CardPredicates.Presets;
import forge.game.card.CounterType;
import forge.game.combat.Combat;
import forge.game.combat.CombatUtil;
import forge.game.cost.Cost;
import forge.game.cost.CostDiscard;
import forge.game.cost.CostPart;
import forge.game.cost.CostPutCounter;
import forge.game.cost.CostRemoveCounter;
import forge.game.cost.*;
import forge.game.mana.ManaCostBeingPaid;
import forge.game.player.Player;
import forge.game.player.PlayerActionConfirmMode;
@@ -729,7 +725,26 @@ public class AiController {
} else if (ApiType.RollPlanarDice == b.getApi() && b.getHostCard().hasSVar("AIRollPlanarDieParams") && b.getHostCard().getSVar("AIRollPlanarDieParams").toLowerCase().matches(".*lowpriority\\$\\s*true.*")) {
return -1;
}
// deprioritize pump spells with pure energy cost (can be activated last,
// since energy is generally scarce, plus can benefit e.g. Electrostatic Pummeler)
int a2 = 0, b2 = 0;
if (a.getApi() == ApiType.Pump && a.getPayCosts() != null && a.getPayCosts().getCostEnergy() != null) {
if (a.getPayCosts().hasOnlySpecificCostType(CostPayEnergy.class)) {
a2 = a.getPayCosts().getCostEnergy().convertAmount();
}
}
if (b.getApi() == ApiType.Pump && b.getPayCosts() != null && b.getPayCosts().getCostEnergy() != null) {
if (b.getPayCosts().hasOnlySpecificCostType(CostPayEnergy.class)) {
b2 = b.getPayCosts().getCostEnergy().convertAmount();
}
}
if (a2 == 0 && b2 > 0) {
return -1;
} else if (b2 == 0 && a2 > 0) {
return 1;
}
// cast 0 mana cost spells first (might be a Mox)
if (a1 == 0 && b1 > 0 && ApiType.Mana != a.getApi()) {
return -1;

View File

@@ -2,7 +2,10 @@ package forge.ai;
import com.google.common.base.Function;
import forge.game.ability.ApiType;
import forge.game.card.Card;
import forge.game.card.CounterType;
import forge.game.cost.CostPayEnergy;
import forge.game.spellability.SpellAbility;
public class CreatureEvaluator implements Function<Card, Integer> {
@@ -184,7 +187,7 @@ public class CreatureEvaluator implements Function<Card, Integer> {
for (final SpellAbility sa : c.getSpellAbilities()) {
if (sa.isAbility()) {
value += addValue(10, "sa: " + sa);
value += addValue(evaluateSpecialAbility(sa), "sa: " + sa);
}
}
if (!c.getManaAbilities().isEmpty()) {
@@ -203,9 +206,38 @@ public class CreatureEvaluator implements Function<Card, Integer> {
if (!c.getEncodedCards().isEmpty()) {
value += addValue(24, "encoded");
}
return value;
}
private int evaluateSpecialAbility(SpellAbility sa) {
// Pump abilities
if (sa.getApi() == ApiType.Pump) {
if ("+X".equals(sa.getParam("NumAtt"))
&& "+X".equals(sa.getParam("NumDef"))
&& !sa.usesTargeting()
&& (!sa.hasParam("Defined") || "Self".equals(sa.getParam("Defined")))) {
// Pump abilities that grant +X/+X to the card
if (sa.getPayCosts() != null && sa.getPayCosts().hasOnlySpecificCostType(CostPayEnergy.class)) {
// Electrostatic Pummeler
int initPower = getEffectivePower(sa.getHostCard());
int pumpedPower = initPower;
int energy = sa.getHostCard().getController().getCounters(CounterType.ENERGY);
if (energy > 0) {
int numActivations = energy / 3;
for (int i = 0; i < numActivations; i++) {
pumpedPower *= 2;
}
return (pumpedPower - initPower) * 15;
}
}
}
}
// default value
return 10;
}
protected int addValue(int value, String text) {
return value;
}