mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 11:48:02 +00:00
- Improve AI for Aether Vial, Ratchet Bomb.
This commit is contained in:
@@ -305,7 +305,11 @@ public class CountersPutAi extends CountersAi {
|
|||||||
AiCardMemory.rememberCard(ai, source, AiCardMemory.MemorySet.HELD_MANA_SOURCES_FOR_MAIN2);
|
AiCardMemory.rememberCard(ai, source, AiCardMemory.MemorySet.HELD_MANA_SOURCES_FOR_MAIN2);
|
||||||
}
|
}
|
||||||
return willActivate;
|
return willActivate;
|
||||||
}
|
} else if (logic.equals("ChargeToBestCMC")) {
|
||||||
|
return doChargeToCMCLogic(ai, sa);
|
||||||
|
} else if (logic.equals("ChargeToBestOppControlledCMC")) {
|
||||||
|
return doChargeToOppCtrlCMCLogic(ai, sa);
|
||||||
|
}
|
||||||
|
|
||||||
if (!sa.metConditions() && sa.getSubAbility() == null) {
|
if (!sa.metConditions() && sa.getSubAbility() == null) {
|
||||||
return false;
|
return false;
|
||||||
@@ -740,6 +744,7 @@ public class CountersPutAi extends CountersAi {
|
|||||||
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) {
|
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) {
|
||||||
final SpellAbility root = sa.getRootAbility();
|
final SpellAbility root = sa.getRootAbility();
|
||||||
final Card source = sa.getHostCard();
|
final Card source = sa.getHostCard();
|
||||||
|
final String aiLogic = sa.getParamOrDefault("AILogic", "");
|
||||||
// boolean chance = true;
|
// boolean chance = true;
|
||||||
boolean preferred = true;
|
boolean preferred = true;
|
||||||
CardCollection list;
|
CardCollection list;
|
||||||
@@ -747,6 +752,7 @@ public class CountersPutAi extends CountersAi {
|
|||||||
final boolean divided = sa.isDividedAsYouChoose();
|
final boolean divided = sa.isDividedAsYouChoose();
|
||||||
final int amount = AbilityUtils.calculateAmount(source, amountStr, sa);
|
final int amount = AbilityUtils.calculateAmount(source, amountStr, sa);
|
||||||
int left = amount;
|
int left = amount;
|
||||||
|
|
||||||
final String[] types;
|
final String[] types;
|
||||||
String type = "";
|
String type = "";
|
||||||
if (sa.hasParam("CounterType")) {
|
if (sa.hasParam("CounterType")) {
|
||||||
@@ -759,6 +765,12 @@ public class CountersPutAi extends CountersAi {
|
|||||||
type = types[0];
|
type = types[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ("ChargeToBestCMC".equals(aiLogic)) {
|
||||||
|
return doChargeToCMCLogic(ai, sa) || mandatory;
|
||||||
|
} else if ("ChargeToBestOppControlledCMC".equals(aiLogic)) {
|
||||||
|
return doChargeToOppCtrlCMCLogic(ai, sa) || mandatory;
|
||||||
|
}
|
||||||
|
|
||||||
if (!sa.usesTargeting()) {
|
if (!sa.usesTargeting()) {
|
||||||
// No target. So must be defined. (Unused at the moment)
|
// No target. So must be defined. (Unused at the moment)
|
||||||
// list = AbilityUtils.getDefinedCards(source, sa.getParam("Defined"), sa);
|
// list = AbilityUtils.getDefinedCards(source, sa.getParam("Defined"), sa);
|
||||||
@@ -1206,4 +1218,38 @@ public class CountersPutAi extends CountersAi {
|
|||||||
return max;
|
return max;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean doChargeToCMCLogic(Player ai, SpellAbility sa) {
|
||||||
|
Card source = sa.getHostCard();
|
||||||
|
CardCollectionView ownLib = CardLists.filter(ai.getCardsIn(ZoneType.Library), CardPredicates.isType("Creature"));
|
||||||
|
int numCtrs = source.getCounters(CounterEnumType.CHARGE);
|
||||||
|
int maxCMC = Aggregates.max(ownLib, CardPredicates.Accessors.fnGetCmc);
|
||||||
|
int optimalCMC = 0;
|
||||||
|
int curAmount = 0;
|
||||||
|
// Assume the AI knows its deck list and realizes what it has left in its library. Could be improved to make this less cheat-y.
|
||||||
|
for (int cmc = numCtrs; cmc <= maxCMC; cmc++) {
|
||||||
|
int numPerCMC = CardLists.filter(ownLib, CardPredicates.hasCMC(cmc)).size();
|
||||||
|
if (numPerCMC >= curAmount) {
|
||||||
|
curAmount = numPerCMC;
|
||||||
|
optimalCMC = cmc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return numCtrs < optimalCMC;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean doChargeToOppCtrlCMCLogic(Player ai, SpellAbility sa) {
|
||||||
|
Card source = sa.getHostCard();
|
||||||
|
CardCollectionView oppInPlay = CardLists.filter(ai.getOpponents().getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.NONLAND_PERMANENTS);
|
||||||
|
int numCtrs = source.getCounters(CounterEnumType.CHARGE);
|
||||||
|
int maxCMC = Aggregates.max(oppInPlay, CardPredicates.Accessors.fnGetCmc);
|
||||||
|
int optimalCMC = 0;
|
||||||
|
int curAmount = 0;
|
||||||
|
for (int cmc = numCtrs; cmc <= maxCMC; cmc++) {
|
||||||
|
int numPerCMC = CardLists.filter(oppInPlay, CardPredicates.hasCMC(cmc)).size();
|
||||||
|
if (numPerCMC >= curAmount) {
|
||||||
|
curAmount = numPerCMC;
|
||||||
|
optimalCMC = cmc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return numCtrs < optimalCMC;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,6 @@ ManaCost:1
|
|||||||
Types:Artifact
|
Types:Artifact
|
||||||
A:AB$ ChangeZone | Cost$ T | Origin$ Hand | Destination$ Battlefield | ChangeType$ Creature.cmcEQX+YouCtrl | Optional$ You | SpellDescription$ You may put a creature card with mana value equal to the number of charge counters on CARDNAME from your hand onto the battlefield. | StackDescription$ SpellDescription
|
A:AB$ ChangeZone | Cost$ T | Origin$ Hand | Destination$ Battlefield | ChangeType$ Creature.cmcEQX+YouCtrl | Optional$ You | SpellDescription$ You may put a creature card with mana value equal to the number of charge counters on CARDNAME from your hand onto the battlefield. | StackDescription$ SpellDescription
|
||||||
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigPutCounter | TriggerDescription$ At the beginning of your upkeep, you may put a charge counter on CARDNAME.
|
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigPutCounter | TriggerDescription$ At the beginning of your upkeep, you may put a charge counter on CARDNAME.
|
||||||
SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ CHARGE | CounterNum$ 1
|
SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ CHARGE | CounterNum$ 1 | AILogic$ ChargeToBestCMC
|
||||||
SVar:X:Count$CardCounters.CHARGE
|
SVar:X:Count$CardCounters.CHARGE
|
||||||
Oracle:At the beginning of your upkeep, you may put a charge counter on Aether Vial.\n{T}: You may put a creature card with mana value equal to the number of charge counters on Aether Vial from your hand onto the battlefield.
|
Oracle:At the beginning of your upkeep, you may put a charge counter on Aether Vial.\n{T}: You may put a creature card with mana value equal to the number of charge counters on Aether Vial from your hand onto the battlefield.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
Name:Ratchet Bomb
|
Name:Ratchet Bomb
|
||||||
ManaCost:2
|
ManaCost:2
|
||||||
Types:Artifact
|
Types:Artifact
|
||||||
A:AB$ PutCounter | Cost$ T | CounterType$ CHARGE | CounterNum$ 1 | SpellDescription$ Put a charge counter on CARDNAME.
|
A:AB$ PutCounter | Cost$ T | CounterType$ CHARGE | CounterNum$ 1 | AILogic$ ChargeToBestOppControlledCMC | SpellDescription$ Put a charge counter on CARDNAME.
|
||||||
A:AB$ DestroyAll | Cost$ T Sac<1/CARDNAME> | ValidCards$ Permanent.nonLand+cmcEQX | SpellDescription$ Destroy each nonland permanent with mana value equal to the number of charge counters on CARDNAME.
|
A:AB$ DestroyAll | Cost$ T Sac<1/CARDNAME> | ValidCards$ Permanent.nonLand+cmcEQX | SpellDescription$ Destroy each nonland permanent with mana value equal to the number of charge counters on CARDNAME.
|
||||||
SVar:X:Count$CardCounters.CHARGE
|
SVar:X:Count$CardCounters.CHARGE
|
||||||
Oracle:{T}: Put a charge counter on Ratchet Bomb.\n{T}, Sacrifice Ratchet Bomb: Destroy each nonland permanent with mana value equal to the number of charge counters on Ratchet Bomb.
|
Oracle:{T}: Put a charge counter on Ratchet Bomb.\n{T}, Sacrifice Ratchet Bomb: Destroy each nonland permanent with mana value equal to the number of charge counters on Ratchet Bomb.
|
||||||
|
|||||||
Reference in New Issue
Block a user