- 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:
Agetian
2017-01-04 18:48:56 +00:00
parent 70ada910be
commit 2853fcc200
6 changed files with 99 additions and 3 deletions

View File

@@ -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;
}

View File

@@ -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);