mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 20:58:03 +00:00
- Added AI logic to play a simple Illusions-Donate Trix deck.
- Added a quest opponent The Great and Powerful Trixie 4, a mono blue Trix combo deck with Illusions of Grandeur and Donate and a wide array of permission. It may be a little haphazard and not always very consistent, but it does beat many hard and very hard opponents with a decent chance.
This commit is contained in:
@@ -19,6 +19,7 @@ import forge.game.phase.PhaseType;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.zone.ZoneType;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public class PermanentAi extends SpellAbilityAi {
|
||||
|
||||
@@ -150,6 +151,46 @@ public class PermanentAi extends SpellAbilityAi {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check for specific AI preferences
|
||||
if (card.hasSVar("AICastPreference")) {
|
||||
String pref = card.getSVar("AICastPreference");
|
||||
String[] groups = StringUtils.split(pref, "|");
|
||||
for (String group : groups) {
|
||||
String[] elems = StringUtils.split(group.trim(), '$');
|
||||
String param = elems[0].trim();
|
||||
String value = elems[1].trim();
|
||||
if (param.equals("MustHaveInHand")) {
|
||||
// Only cast if another card is present in hand (e.g. Illusions of Grandeur followed by Donate)
|
||||
boolean hasCard = CardLists.filter(ai.getCardsIn(ZoneType.Hand), CardPredicates.nameEquals(value)).size() > 0;
|
||||
if (!hasCard) {
|
||||
return false;
|
||||
}
|
||||
} else if (param.equals("MaxControlled")) {
|
||||
// Only cast unless there are X or more cards like this on the battlefield under AI control already
|
||||
int numControlled = CardLists.filter(ai.getCardsIn(ZoneType.Battlefield), CardPredicates.nameEquals(card.getName())).size();
|
||||
if (numControlled >= Integer.parseInt(value)) {
|
||||
return false;
|
||||
}
|
||||
} else if (elems[0].trim().equals("NumManaSources")) {
|
||||
// Only cast if there are X or more mana sources controlled by the AI
|
||||
CardCollection m = ComputerUtilMana.getAvailableMana(ai, true);
|
||||
if (m.size() < Integer.parseInt(value)) {
|
||||
return false;
|
||||
}
|
||||
} else if (elems[0].trim().equals("NumManaSourcesNextTurn")) {
|
||||
// Only cast if there are X or more mana sources controlled by the AI *or*
|
||||
// if there are X-1 mana sources in play but the AI has an extra land in hand
|
||||
CardCollection m = ComputerUtilMana.getAvailableMana(ai, true);
|
||||
int hasExtraLandInHand = CardLists.filter(ai.getCardsIn(ZoneType.Hand), CardPredicates.Presets.LANDS).size() > 0 ? 1 : 0;
|
||||
if (m.size() + hasExtraLandInHand < Integer.parseInt(value)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import forge.game.Game;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardCollection;
|
||||
import forge.game.card.CardCollectionView;
|
||||
import forge.game.card.CardLists;
|
||||
import forge.game.card.CounterType;
|
||||
import forge.game.card.CardPredicates.Presets;
|
||||
@@ -93,6 +94,20 @@ public class PumpAi extends PumpAiBase {
|
||||
sa.getTargets().add(lowest);
|
||||
return true;
|
||||
}
|
||||
} else if (sa.hasParam("AILogic") && sa.getParam("AILogic").startsWith("Donate")) {
|
||||
// Donate currently supports only one special code path (Illusions of Grandeur)
|
||||
CardCollectionView aiList = ai.getCardsIn(ZoneType.Battlefield, "Illusions of Grandeur");
|
||||
if (aiList.size() > 0) {
|
||||
// Donate an Illusions of Grandeur, step 1 - target the opponent.
|
||||
if (sa.getParam("AILogic").equals("DonateTargetPlayer")) {
|
||||
sa.resetTargets();
|
||||
sa.getTargets().add(ai.getOpponents().get(0)); // TODO: expand this to donate to an opp who doesn't have Illusions yet
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// AI currently does not know how to handle Donate effectively otherwise
|
||||
// TODO: enhance this for other cases (e.g. Donating a card with bad drawback to the opponent)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ComputerUtil.preventRunAwayActivations(sa)) {
|
||||
@@ -233,6 +248,13 @@ public class PumpAi extends PumpAiBase {
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else if (sa.getParam("AILogic").equals("DonateTargetPerm")) {
|
||||
// Illusions of Grandeur + Donate, step 2 - target Illusions.
|
||||
CardCollectionView aiList = ai.getCardsIn(ZoneType.Battlefield, "Illusions of Grandeur");
|
||||
if (aiList.size() > 0) {
|
||||
sa.getTargets().add(aiList.get(0));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (isFight) {
|
||||
return FightAi.canFightAi(ai, sa, attack, defense);
|
||||
|
||||
Reference in New Issue
Block a user