mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 12:18:00 +00:00
- 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:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user