mirror of
https://github.com/Relintai/mtg-forge-ios.git
synced 2024-12-21 07:16:52 +01: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.
git-svn-id: http://svn.slightlymagic.net/forge/trunk@35719 269b9781-a132-4a9b-9d4e-f004f1b56b58
This commit is contained in:
parent
d3bfe5a0b2
commit
5e7442af9d
@ -881,6 +881,9 @@ public class AiController {
|
|||||||
}
|
}
|
||||||
if (prefCard == null) {
|
if (prefCard == null) {
|
||||||
prefCard = ComputerUtil.getCardPreference(player, sourceCard, "DiscardCost", validCards);
|
prefCard = ComputerUtil.getCardPreference(player, sourceCard, "DiscardCost", validCards);
|
||||||
|
if (prefCard != null && prefCard.hasSVar("DoNotDiscardIfAble")) {
|
||||||
|
prefCard = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (prefCard != null) {
|
if (prefCard != null) {
|
||||||
discardList.add(prefCard);
|
discardList.add(prefCard);
|
||||||
@ -917,13 +920,29 @@ public class AiController {
|
|||||||
if (numLandsInHand > 0) {
|
if (numLandsInHand > 0) {
|
||||||
numLandsAvailable++;
|
numLandsAvailable++;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Discard unplayable card
|
//Discard unplayable card
|
||||||
if (validCards.get(0).getCMC() > numLandsAvailable) {
|
boolean discardedUnplayable = false;
|
||||||
discardList.add(validCards.get(0));
|
for (int j = 0; j < validCards.size(); j++) {
|
||||||
validCards.remove(validCards.get(0));
|
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);
|
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);
|
discardList.add(worst);
|
||||||
validCards.remove(worst);
|
validCards.remove(worst);
|
||||||
}
|
}
|
||||||
|
@ -94,9 +94,10 @@ public enum AiProps { /** */
|
|||||||
BOUNCE_ALL_TO_HAND_CREAT_EVAL_DIFF ("200"), /** */
|
BOUNCE_ALL_TO_HAND_CREAT_EVAL_DIFF ("200"), /** */
|
||||||
BOUNCE_ALL_ELSEWHERE_CREAT_EVAL_DIFF ("200"), /** */
|
BOUNCE_ALL_ELSEWHERE_CREAT_EVAL_DIFF ("200"), /** */
|
||||||
BOUNCE_ALL_TO_HAND_NONCREAT_EVAL_DIFF ("3"), /** */
|
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
|
// 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;
|
private final String strDefaultVal;
|
||||||
|
|
||||||
|
@ -350,7 +350,12 @@ public class ComputerUtilCard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (hasEnchantmants || hasArtifacts) {
|
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);
|
return getCheapestPermanentAI(ae, null, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -363,6 +368,28 @@ public class ComputerUtilCard {
|
|||||||
return getCheapestPermanentAI(list, null, false);
|
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>() {
|
public static final Comparator<Card> EvaluateCreatureComparator = new Comparator<Card>() {
|
||||||
@Override
|
@Override
|
||||||
public int compare(final Card a, final Card b) {
|
public int compare(final Card a, final Card b) {
|
||||||
|
@ -537,7 +537,7 @@ public class SpecialCardAi {
|
|||||||
public static class Intuition {
|
public static class Intuition {
|
||||||
public static CardCollection considerMultiple(final Player ai, final SpellAbility sa) {
|
public static CardCollection considerMultiple(final Player ai, final SpellAbility sa) {
|
||||||
if (ai.getController().isAI()) {
|
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
|
return new CardCollection(); // fall back to standard ChangeZoneAi considerations
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -556,14 +556,14 @@ public class SpecialCardAi {
|
|||||||
cardAmount.add(c.getName());
|
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;
|
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;
|
donateComboMightWin = true;
|
||||||
int numIllusionsInHand = CardLists.filter(ai.getCardsIn(ZoneType.Hand), CardPredicates.nameEquals("Illusions of Grandeur")).size();
|
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 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 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();
|
int numDonateInLib = CardLists.filter(ai.getCardsIn(ZoneType.Library), CardPredicates.nameEquals("Donate")).size();
|
||||||
CardCollection comboList = new CardCollection();
|
CardCollection comboList = new CardCollection();
|
||||||
if ((numIllusionsInHand > 0 || numIllusionsOTB > 0) && numDonateInHand == 0 && numDonateInLib >= 3) {
|
if ((numIllusionsInHand > 0 || numIllusionsOTB > 0) && numDonateInHand == 0 && numDonateInLib >= 3) {
|
||||||
|
@ -164,3 +164,9 @@ BOUNCE_ALL_ELSEWHERE_CREAT_EVAL_DIFF=200
|
|||||||
# on both side of the battlefield
|
# on both side of the battlefield
|
||||||
BOUNCE_ALL_TO_HAND_NONCREAT_EVAL_DIFF=3
|
BOUNCE_ALL_TO_HAND_NONCREAT_EVAL_DIFF=3
|
||||||
BOUNCE_ALL_ELSEWHERE_NONCREAT_EVAL_DIFF=3
|
BOUNCE_ALL_ELSEWHERE_NONCREAT_EVAL_DIFF=3
|
||||||
|
|
||||||
|
# If enabled, the AI will try to pair up cards to present to the opponent so that a specific card may be picked,
|
||||||
|
# it'll also try to grab Accumulated Knowledge and Take Inventory more actively, as well as interact with the Trix
|
||||||
|
# combo deck more appropriately. In Reanimator decks, this logic will make the AI pick the fattest threats in the
|
||||||
|
# library to put some into the graveyard.
|
||||||
|
INTUITION_ALTERNATIVE_LOGIC=true
|
||||||
|
@ -165,3 +165,8 @@ BOUNCE_ALL_ELSEWHERE_CREAT_EVAL_DIFF=200
|
|||||||
BOUNCE_ALL_TO_HAND_NONCREAT_EVAL_DIFF=3
|
BOUNCE_ALL_TO_HAND_NONCREAT_EVAL_DIFF=3
|
||||||
BOUNCE_ALL_ELSEWHERE_NONCREAT_EVAL_DIFF=3
|
BOUNCE_ALL_ELSEWHERE_NONCREAT_EVAL_DIFF=3
|
||||||
|
|
||||||
|
# If enabled, the AI will try to pair up cards to present to the opponent so that a specific card may be picked,
|
||||||
|
# it'll also try to grab Accumulated Knowledge and Take Inventory more actively, as well as interact with the Trix
|
||||||
|
# combo deck more appropriately. In Reanimator decks, this logic will make the AI pick the fattest threats in the
|
||||||
|
# library to put some into the graveyard.
|
||||||
|
INTUITION_ALTERNATIVE_LOGIC=true
|
||||||
|
@ -165,11 +165,14 @@ BOUNCE_ALL_ELSEWHERE_CREAT_EVAL_DIFF=400
|
|||||||
BOUNCE_ALL_TO_HAND_NONCREAT_EVAL_DIFF=5
|
BOUNCE_ALL_TO_HAND_NONCREAT_EVAL_DIFF=5
|
||||||
BOUNCE_ALL_ELSEWHERE_NONCREAT_EVAL_DIFF=5
|
BOUNCE_ALL_ELSEWHERE_NONCREAT_EVAL_DIFF=5
|
||||||
|
|
||||||
|
# If enabled, the AI will try to pair up cards to present to the opponent so that a specific card may be picked,
|
||||||
|
# it'll also try to grab Accumulated Knowledge and Take Inventory more actively, as well as interact with the Trix
|
||||||
|
# combo deck more appropriately. In Reanimator decks, this logic will make the AI pick the fattest threats in the
|
||||||
|
# library to put some into the graveyard.
|
||||||
|
INTUITION_ALTERNATIVE_LOGIC=true
|
||||||
|
|
||||||
# -- Experimental feature toggles which only exist until the testing procedure for the relevant --
|
# -- Experimental feature toggles which only exist until the testing procedure for the relevant --
|
||||||
# -- features is over. These toggles will be removed later, or may be reintroduced under a --
|
# -- features is over. These toggles will be removed later, or may be reintroduced under a --
|
||||||
# -- different name if necessary --
|
# -- different name if necessary --
|
||||||
|
|
||||||
# Experimental logic for Intuition that makes it work better in reanimator decks, combo decks like Trix,
|
# <-- there are no options here at the moment -->
|
||||||
# and generally tries to either grab cards that are also good to put in the graveyard or that are available
|
|
||||||
# in multiples in the deck.
|
|
||||||
INTUITION_SPECIAL_LOGIC=true
|
|
||||||
|
@ -164,3 +164,9 @@ BOUNCE_ALL_ELSEWHERE_CREAT_EVAL_DIFF=200
|
|||||||
# on both side of the battlefield
|
# on both side of the battlefield
|
||||||
BOUNCE_ALL_TO_HAND_NONCREAT_EVAL_DIFF=3
|
BOUNCE_ALL_TO_HAND_NONCREAT_EVAL_DIFF=3
|
||||||
BOUNCE_ALL_ELSEWHERE_NONCREAT_EVAL_DIFF=3
|
BOUNCE_ALL_ELSEWHERE_NONCREAT_EVAL_DIFF=3
|
||||||
|
|
||||||
|
# If enabled, the AI will try to pair up cards to present to the opponent so that a specific card may be picked,
|
||||||
|
# it'll also try to grab Accumulated Knowledge and Take Inventory more actively, as well as interact with the Trix
|
||||||
|
# combo deck more appropriately. In Reanimator decks, this logic will make the AI pick the fattest threats in the
|
||||||
|
# library to put some into the graveyard.
|
||||||
|
INTUITION_ALTERNATIVE_LOGIC=true
|
||||||
|
@ -7,5 +7,6 @@ SVar:D2:DB$ Pump | ValidTgts$ Permanent.YouCtrl | TgtPrompt$ Select target perma
|
|||||||
SVar:D3:DB$ GainControl | Defined$ Targeted | NewController$ Remembered | SubAbility$ D4
|
SVar:D3:DB$ GainControl | Defined$ Targeted | NewController$ Remembered | SubAbility$ D4
|
||||||
SVar:D4:DB$ Cleanup | ClearRemembered$ True
|
SVar:D4:DB$ Cleanup | ClearRemembered$ True
|
||||||
SVar:RemRandomDeck:True
|
SVar:RemRandomDeck:True
|
||||||
|
SVar:DoNotDiscardIfAble:TRUE
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/donate.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/donate.jpg
|
||||||
Oracle:Target player gains control of target permanent you control.
|
Oracle:Target player gains control of target permanent you control.
|
||||||
|
@ -4,12 +4,13 @@ Types:Enchantment
|
|||||||
K:Cumulative upkeep:2
|
K:Cumulative upkeep:2
|
||||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigGainLife | TriggerDescription$ When CARDNAME enters the battlefield, you gain 20 life.
|
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigGainLife | TriggerDescription$ When CARDNAME enters the battlefield, you gain 20 life.
|
||||||
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | ValidCard$ Card.Self | Execute$ TrigLoseLife | TriggerController$ TriggeredCardController | TriggerDescription$ When CARDNAME leaves the battlefield, you lose 20 life.
|
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | ValidCard$ Card.Self | Execute$ TrigLoseLife | TriggerController$ TriggeredCardController | TriggerDescription$ When CARDNAME leaves the battlefield, you lose 20 life.
|
||||||
SVar:TrigGainLife:AB$GainLife | Cost$ 0 | Defined$ TriggeredCardController | LifeAmount$ 20
|
SVar:TrigGainLife:DB$ GainLife | Defined$ TriggeredCardController | LifeAmount$ 20
|
||||||
SVar:TrigLoseLife:AB$LoseLife | Cost$ 0 | Defined$ TriggeredCardController | LifeAmount$ 20
|
SVar:TrigLoseLife:DB$ LoseLife | Defined$ TriggeredCardController | LifeAmount$ 20
|
||||||
SVar:AICastPreference:MustHaveInHand$ Donate | MaxControlled$ 1 | NumManaSourcesNextTurn$ 5 | AlwaysCastIfLifeBelow$ 4
|
SVar:AICastPreference:MustHaveInHand$ Donate | MaxControlled$ 1 | NumManaSourcesNextTurn$ 5 | AlwaysCastIfLifeBelow$ 4
|
||||||
SVar:RemRandomDeck:True
|
SVar:RemRandomDeck:True
|
||||||
SVar:DeckNeeds:Name$Donate
|
SVar:DeckNeeds:Name$Donate
|
||||||
SVar:DonateMe:5
|
SVar:DonateMe:5
|
||||||
SVar:PlayMain1:TRUE
|
SVar:PlayMain1:TRUE
|
||||||
|
SVar:DoNotDiscardIfAble:TRUE
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/illusions_of_grandeur.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/illusions_of_grandeur.jpg
|
||||||
Oracle:Cumulative upkeep {2} (At the beginning of your upkeep, put an age counter on this permanent, then sacrifice it unless you pay its upkeep cost for each age counter on it.)\nWhen Illusions of Grandeur enters the battlefield, you gain 20 life.\nWhen Illusions of Grandeur leaves the battlefield, you lose 20 life.
|
Oracle:Cumulative upkeep {2} (At the beginning of your upkeep, put an age counter on this permanent, then sacrifice it unless you pay its upkeep cost for each age counter on it.)\nWhen Illusions of Grandeur enters the battlefield, you gain 20 life.\nWhen Illusions of Grandeur leaves the battlefield, you lose 20 life.
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
[duel]
|
||||||
|
[metadata]
|
||||||
|
Name=The Great and Powerful Trixie 2
|
||||||
|
Title=The Great and Powerful Trixie
|
||||||
|
Difficulty=hard
|
||||||
|
Description=U splash W Trix combo deck with Illusions of Grandeur and Donate
|
||||||
|
Icon=The Great and Powerful Trixie.jpg
|
||||||
|
Deck Type=constructed
|
||||||
|
Profile=Cautious
|
||||||
|
[main]
|
||||||
|
3 Arcane Denial
|
||||||
|
2 Cancel
|
||||||
|
3 Disdainful Stroke
|
||||||
|
4 Donate
|
||||||
|
1 Enlightened Tutor
|
||||||
|
3 Essence Scatter
|
||||||
|
4 Glacial Fortress
|
||||||
|
4 Illusions of Grandeur
|
||||||
|
14 Island
|
||||||
|
3 Mana Leak
|
||||||
|
1 Mystical Tutor
|
||||||
|
1 Plains
|
||||||
|
4 Sapphire Medallion
|
||||||
|
2 Seachrome Coast
|
||||||
|
3 Unsummon
|
||||||
|
4 Vapor Snag
|
||||||
|
4 Wrath of God
|
@ -3,25 +3,19 @@
|
|||||||
Name=The Great and Powerful Trixie 3
|
Name=The Great and Powerful Trixie 3
|
||||||
Title=The Great and Powerful Trixie
|
Title=The Great and Powerful Trixie
|
||||||
Difficulty=hard
|
Difficulty=hard
|
||||||
Description=U splash W Trix combo deck with Illusions of Grandeur and Donate
|
Description=Mono U Trix combo deck with Illusions of Grandeur and Donate
|
||||||
Icon=The Great and Powerful Trixie.jpg
|
Icon=The Great and Powerful Trixie.jpg
|
||||||
Deck Type=constructed
|
Deck Type=constructed
|
||||||
[main]
|
[main]
|
||||||
1 Ancestral Recall
|
4 Accumulated Knowledge
|
||||||
4 Arcane Denial
|
4 Capsize
|
||||||
1 Black Lotus
|
|
||||||
4 Counterspell
|
|
||||||
3 Disdainful Stroke
|
|
||||||
4 Donate
|
4 Donate
|
||||||
3 Essence Scatter
|
4 Frantic Search
|
||||||
4 Glacial Fortress
|
4 Helm of Awakening
|
||||||
|
2 Hoodwink
|
||||||
4 Illusions of Grandeur
|
4 Illusions of Grandeur
|
||||||
10 Island
|
4 Intuition
|
||||||
1 Mox Pearl
|
21 Island
|
||||||
1 Mox Sapphire
|
1 Merchant Scroll
|
||||||
4 Sapphire Medallion
|
4 Sapphire Medallion
|
||||||
1 Timetwister
|
4 Stroke of Genius
|
||||||
4 Tundra
|
|
||||||
3 Unsummon
|
|
||||||
4 Vapor Snag
|
|
||||||
4 Wrath of God
|
|
||||||
|
@ -6,6 +6,7 @@ Difficulty=very hard
|
|||||||
Description=UB Necro-Donate Trix combo deck with Necropotence, Illusions of Grandeur and Donate
|
Description=UB Necro-Donate Trix combo deck with Necropotence, Illusions of Grandeur and Donate
|
||||||
Icon=The Great and Powerful Trixie.jpg
|
Icon=The Great and Powerful Trixie.jpg
|
||||||
Deck Type=constructed
|
Deck Type=constructed
|
||||||
|
Profile=Cautious
|
||||||
[main]
|
[main]
|
||||||
1 Ancestral Recall
|
1 Ancestral Recall
|
||||||
3 Arcane Denial
|
3 Arcane Denial
|
||||||
|
Loading…
Reference in New Issue
Block a user