- Improved support for Illusions-Donate, added deck The Great and Powerful Trixie 2, changed the deck The Great and Powerful Trixie 3 to be a more standard Legacy-legal Trix.

This commit is contained in:
Agetian
2017-09-23 09:04:16 +00:00
parent e18dd07491
commit 1b1a56e77c
14 changed files with 125 additions and 33 deletions

View File

@@ -881,6 +881,9 @@ public class AiController {
}
if (prefCard == null) {
prefCard = ComputerUtil.getCardPreference(player, sourceCard, "DiscardCost", validCards);
if (prefCard != null && prefCard.hasSVar("DoNotDiscardIfAble")) {
prefCard = null;
}
}
if (prefCard != null) {
discardList.add(prefCard);
@@ -917,13 +920,29 @@ public class AiController {
if (numLandsInHand > 0) {
numLandsAvailable++;
}
//Discard unplayable card
if (validCards.get(0).getCMC() > numLandsAvailable) {
discardList.add(validCards.get(0));
validCards.remove(validCards.get(0));
boolean discardedUnplayable = false;
for (int j = 0; j < validCards.size(); j++) {
if (validCards.get(j).getCMC() > numLandsAvailable && !validCards.get(j).hasSVar("DoNotDiscardIfAble")) {
discardList.add(validCards.get(j));
validCards.remove(validCards.get(j));
discardedUnplayable = true;
break;
} else if (validCards.get(j).getCMC() <= numLandsAvailable) {
// cut short to avoid looping over cards which are guaranteed not to fit the criteria
break;
}
}
else { //Discard worst card
if (!discardedUnplayable) {
// discard worst card
Card worst = ComputerUtilCard.getWorstAI(validCards);
if (worst == null) {
// there were only instants and sorceries, and maybe cards that are not good to discard, so look
// for more discard options
worst = ComputerUtilCard.getCheapestSpellAI(validCards);
}
discardList.add(worst);
validCards.remove(worst);
}

View File

@@ -94,9 +94,10 @@ public enum AiProps { /** */
BOUNCE_ALL_TO_HAND_CREAT_EVAL_DIFF ("200"), /** */
BOUNCE_ALL_ELSEWHERE_CREAT_EVAL_DIFF ("200"), /** */
BOUNCE_ALL_TO_HAND_NONCREAT_EVAL_DIFF ("3"), /** */
BOUNCE_ALL_ELSEWHERE_NONCREAT_EVAL_DIFF ("3"), /** */
BOUNCE_ALL_ELSEWHERE_NONCREAT_EVAL_DIFF ("3"),
INTUITION_ALTERNATIVE_LOGIC ("false"); /** */
// Experimental features, must be removed after extensive testing and, ideally, defaulting
INTUITION_SPECIAL_LOGIC ("false"); /** */
// <-- There are no experimental options here -->
private final String strDefaultVal;

View File

@@ -350,7 +350,12 @@ public class ComputerUtilCard {
}
if (hasEnchantmants || hasArtifacts) {
final List<Card> ae = CardLists.filter(list, Predicates.<Card>or(CardPredicates.Presets.ARTIFACTS, CardPredicates.Presets.ENCHANTMENTS));
final List<Card> ae = CardLists.filter(list, Predicates.and(Predicates.<Card>or(CardPredicates.Presets.ARTIFACTS, CardPredicates.Presets.ENCHANTMENTS), new Predicate<Card>() {
@Override
public boolean apply(Card card) {
return !card.hasSVar("DoNotDiscardIfAble");
}
}));
return getCheapestPermanentAI(ae, null, false);
}
@@ -363,6 +368,28 @@ public class ComputerUtilCard {
return getCheapestPermanentAI(list, null, false);
}
public static final Card getCheapestSpellAI(final Iterable<Card> list) {
if (!Iterables.isEmpty(list)) {
CardCollection cc = CardLists.filter(new CardCollection(list),
Predicates.or(CardPredicates.isType("Instant"), CardPredicates.isType("Sorcery")));
Collections.sort(cc, CardLists.CmcComparatorInv);
Card cheapest = cc.getLast();
if (cheapest.hasSVar("DoNotDiscardIfAble")) {
for (int i = cc.size() - 1; i >= 0; i--) {
if (!cc.get(i).hasSVar("DoNotDiscardIfAble")) {
cheapest = cc.get(i);
break;
}
}
}
return cheapest;
}
return null;
}
public static final Comparator<Card> EvaluateCreatureComparator = new Comparator<Card>() {
@Override
public int compare(final Card a, final Card b) {

View File

@@ -537,7 +537,7 @@ public class SpecialCardAi {
public static class Intuition {
public static CardCollection considerMultiple(final Player ai, final SpellAbility sa) {
if (ai.getController().isAI()) {
if (!((PlayerControllerAi) ai.getController()).getAi().getBooleanProperty(AiProps.INTUITION_SPECIAL_LOGIC)) {
if (!((PlayerControllerAi) ai.getController()).getAi().getBooleanProperty(AiProps.INTUITION_ALTERNATIVE_LOGIC)) {
return new CardCollection(); // fall back to standard ChangeZoneAi considerations
}
}
@@ -556,14 +556,14 @@ public class SpecialCardAi {
cardAmount.add(c.getName());
}
// Trix: see if we can complete the combo (if it looks like we might win shortly)
// Trix: see if we can complete the combo (if it looks like we might win shortly or if we need to get a Donate stat)
boolean donateComboMightWin = false;
if (ai.getOpponentsSmallestLifeTotal() <= 20) {
int numIllusionsOTB = CardLists.filter(ai.getCardsIn(ZoneType.Battlefield), CardPredicates.nameEquals("Illusions of Grandeur")).size();
if (ai.getOpponentsSmallestLifeTotal() < 20 || numIllusionsOTB > 0) {
donateComboMightWin = true;
int numIllusionsInHand = CardLists.filter(ai.getCardsIn(ZoneType.Hand), CardPredicates.nameEquals("Illusions of Grandeur")).size();
int numDonateInHand = CardLists.filter(ai.getCardsIn(ZoneType.Hand), CardPredicates.nameEquals("Donate")).size();
int numIllusionsInLib = CardLists.filter(ai.getCardsIn(ZoneType.Library), CardPredicates.nameEquals("Illusions of Grandeur")).size();
int numIllusionsOTB = CardLists.filter(ai.getCardsIn(ZoneType.Battlefield), CardPredicates.nameEquals("Illusions of Grandeur")).size();
int numDonateInLib = CardLists.filter(ai.getCardsIn(ZoneType.Library), CardPredicates.nameEquals("Donate")).size();
CardCollection comboList = new CardCollection();
if ((numIllusionsInHand > 0 || numIllusionsOTB > 0) && numDonateInHand == 0 && numDonateInLib >= 3) {