From 563c089b9dc279b08ffd29df1b452ae638b007a7 Mon Sep 17 00:00:00 2001 From: Maxmtg Date: Tue, 14 Jan 2014 07:13:48 +0000 Subject: [PATCH] now GameFormat supports "Restricted" cards (ex: power 9 in Vintage) --- .../src/main/java/forge/game/GameFormat.java | 76 ++++++++++++++----- forge-gui/res/blockdata/formats.txt | 3 +- .../forge/quest/data/GameFormatQuest.java | 4 +- 3 files changed, 62 insertions(+), 21 deletions(-) diff --git a/forge-game/src/main/java/forge/game/GameFormat.java b/forge-game/src/main/java/forge/game/GameFormat.java index 79cfbb67eec..390adafaa0e 100644 --- a/forge-game/src/main/java/forge/game/GameFormat.java +++ b/forge-game/src/main/java/forge/game/GameFormat.java @@ -22,6 +22,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Map.Entry; import com.google.common.base.Function; import com.google.common.base.Predicate; @@ -30,7 +31,9 @@ import com.google.common.collect.Lists; import forge.StaticData; import forge.card.CardEdition; +import forge.deck.CardPool; import forge.deck.Deck; +import forge.deck.DeckSection; import forge.item.PaperCard; import forge.item.IPaperCard; import forge.util.FileSection; @@ -45,11 +48,12 @@ import forge.util.storage.StorageReaderFileSections; public class GameFormat implements Comparable { private final String name; // contains allowed sets, when empty allows all sets - protected final List allowedSetCodes; - protected final List bannedCardNames; + + protected final List allowedSetCodes; // this is mutable to support quest mode set unlocks protected final transient List allowedSetCodes_ro; protected final transient List bannedCardNames_ro; + protected final transient List restrictedCardNames_ro; protected final transient Predicate filterRules; protected final transient Predicate filterPrinted; @@ -67,38 +71,40 @@ public class GameFormat implements Comparable { * the banned cards */ public GameFormat(final String fName, final Iterable sets, final List bannedCards) { - this(fName, sets, bannedCards, 0); + this(fName, sets, bannedCards, null, 0); } - public static final GameFormat NoFormat = new GameFormat("(none)", null, null, Integer.MAX_VALUE); + public static final GameFormat NoFormat = new GameFormat("(none)", null, null, null, Integer.MAX_VALUE); - public GameFormat(final String fName, final Iterable sets, final List bannedCards, int compareIdx) { + public GameFormat(final String fName, final Iterable sets, final List bannedCards, final List restrictedCards, int compareIdx) { this.index = compareIdx; this.name = fName; - this.allowedSetCodes = sets == null ? new ArrayList() : Lists.newArrayList(sets); - this.bannedCardNames = bannedCards == null ? new ArrayList() : Lists.newArrayList(bannedCards); - + allowedSetCodes = sets == null ? new ArrayList() : Lists.newArrayList(sets); + final List bannedCardNames = bannedCards == null ? new ArrayList() : Lists.newArrayList(bannedCards); + final List restrictedCardNames = restrictedCards == null ? new ArrayList() : Lists.newArrayList(restrictedCards); + this.allowedSetCodes_ro = Collections.unmodifiableList(allowedSetCodes); this.bannedCardNames_ro = Collections.unmodifiableList(bannedCardNames); + this.restrictedCardNames_ro = Collections.unmodifiableList(restrictedCardNames); this.filterRules = this.buildFilterRules(); this.filterPrinted = this.buildFilterPrinted(); } private Predicate buildFilterPrinted() { - final Predicate banNames = Predicates.not(IPaperCard.Predicates.names(this.bannedCardNames)); - if (this.allowedSetCodes == null || this.allowedSetCodes.isEmpty()) { + final Predicate banNames = Predicates.not(IPaperCard.Predicates.names(this.bannedCardNames_ro)); + if (this.allowedSetCodes_ro.isEmpty()) { return banNames; } - return Predicates.and(banNames, IPaperCard.Predicates.printedInSets(this.allowedSetCodes, true)); + return Predicates.and(banNames, IPaperCard.Predicates.printedInSets(this.allowedSetCodes_ro, true)); } private Predicate buildFilterRules() { - final Predicate banNames = Predicates.not(IPaperCard.Predicates.names(this.bannedCardNames)); - if (this.allowedSetCodes == null || this.allowedSetCodes.isEmpty()) { + final Predicate banNames = Predicates.not(IPaperCard.Predicates.names(this.bannedCardNames_ro)); + if (this.allowedSetCodes_ro.isEmpty()) { return banNames; } - return Predicates.and(banNames, StaticData.instance().getCommonCards().wasPrintedInSets(this.allowedSetCodes)); + return Predicates.and(banNames, StaticData.instance().getCommonCards().wasPrintedInSets(this.allowedSetCodes_ro)); } /** @@ -128,6 +134,11 @@ public class GameFormat implements Comparable { return this.bannedCardNames_ro; } + public List getRestrictedCards() { + // TODO Auto-generated method stub + return restrictedCardNames_ro; + } + /** * Gets the filter rules. * @@ -154,7 +165,30 @@ public class GameFormat implements Comparable { * @return true, if is sets the legal */ public boolean isSetLegal(final String setCode) { - return this.allowedSetCodes.isEmpty() || this.allowedSetCodes.contains(setCode); + return this.allowedSetCodes_ro.isEmpty() || this.allowedSetCodes_ro.contains(setCode); + } + + public boolean isDeckLegal(final Deck deck) { + CardPool allCards = new CardPool(); // will count cards in this pool to enforce restricted + allCards.addAll(deck.getMain()); + if (deck.has(DeckSection.Sideboard)) + allCards.addAll(deck.get(DeckSection.Sideboard)); + if (deck.has(DeckSection.Commander)) + allCards.addAll(deck.get(DeckSection.Commander)); + + for (Entry poolEntry : allCards) { + if (!filterRules.apply(poolEntry.getKey())) { + return false; //all cards in deck must pass card predicate to pass deck predicate + } + } + + if(!restrictedCardNames_ro.isEmpty() ) { + for (Entry poolEntry : allCards) { + if( poolEntry.getValue().intValue() > 1 && restrictedCardNames_ro.contains(poolEntry.getKey().getName())) + return false; + } + } + return true; } /* @@ -204,6 +238,7 @@ public class GameFormat implements Comparable { protected GameFormat read(String title, Iterable body, int idx) { List sets = null; // default: all sets allowed List bannedCards = null; // default: nothing banned + List restrictedCards = null; // default: nothing restricted FileSection section = FileSection.parse(body, ":"); String strSets = section.get("sets"); @@ -214,8 +249,13 @@ public class GameFormat implements Comparable { if ( strCars != null ) { bannedCards = Arrays.asList(strCars.split("; ")); } + + strCars = section.get("restricted"); + if ( strCars != null ) { + restrictedCards = Arrays.asList(strCars.split("; ")); + } - GameFormat result = new GameFormat(title, sets, bannedCards, 1 + idx); + GameFormat result = new GameFormat(title, sets, bannedCards, restrictedCards, 1 + idx); naturallyOrdered.add(result); return result; } @@ -247,7 +287,7 @@ public class GameFormat implements Comparable { public GameFormat getFormatOfDeck(Deck deck) { for(GameFormat gf : naturallyOrdered) { - if ( Deck.createPredicate(gf.getFilterRules()).apply(deck) ) + if ( gf.isDeckLegal(deck) ) return gf; } @@ -257,7 +297,7 @@ public class GameFormat implements Comparable { public Iterable getAllFormatsOfDeck(Deck deck) { List result = new ArrayList(); for(GameFormat gf : naturallyOrdered) { - if ( Deck.createPredicate(gf.getFilterRules()).apply(deck) ) + if (gf.isDeckLegal(deck)) result.add(gf); } return result; diff --git a/forge-gui/res/blockdata/formats.txt b/forge-gui/res/blockdata/formats.txt index 96ed28e9ff3..354ae5fc373 100644 --- a/forge-gui/res/blockdata/formats.txt +++ b/forge-gui/res/blockdata/formats.txt @@ -13,4 +13,5 @@ Banned:Ancestral Vision; Ancient Den; Bitterblossom; Blazing Shoal; Bloodbraid E Banned:Amulet of Quoz; Ancestral Recall; Balance; Bazaar of Baghdad; Black Lotus; Black Vise; Bronze Tablet; Channel; Chaos Orb; Contract from Below; Darkpact; Demonic Attorney; Demonic Consultation; Demonic Tutor; Earthcraft; Falling Star; Fastbond; Flash; Frantic Search; Goblin Recruiter; Gush; Hermit Druid; Imperial Seal; Jeweled Bird; Land Tax; Library of Alexandria; Mana Crypt; Mana Drain; Mana Vault; Memory Jar; Mind Twist; Mind's Desire; Mishra's Workshop; Mox Emerald; Mox Jet; Mox Pearl; Mox Ruby; Mox Sapphire; Mystical Tutor; Necropotence; Oath of Druids; Rebirth; Shahrazad; Skullclamp; Sol Ring; Strip Mine; Survival of the Fittest; Tempest Efreet; Time Vault; Time Walk; Timetwister; Timmerian Fiends; Tinker; Tolarian Academy; Vampiric Tutor; Wheel of Fortune; Windfall; Worldgorger Dragon; Yawgmoth's Bargain; Yawgmoth's Will; Mental Misstep [Vintage] -Banned:Amulet of Quoz; Bronze Tablet; Chaos Orb; Contract from Below; Darkpact; Demonic Attorney; Falling Star; Jeweled Bird; Rebirth; Shahrazad; Tempest Efreet; Timmerian Fiends \ No newline at end of file +Banned:Amulet of Quoz; Bronze Tablet; Chaos Orb; Contract from Below; Darkpact; Demonic Attorney; Falling Star; Jeweled Bird; Rebirth; Shahrazad; Tempest Efreet; Timmerian Fiends +Restricted:Ancestral Recall; Balance; Black Lotus; Brainstorm; Channel; Demonic Consultation; Demonic Tutor; Fastbond; Flash; Gifts Ungiven; Imperial Seal; Library of Alexandria; Lion’s Eye Diamond; Lotus Petal; Mana Crypt; Mana Vault; Memory Jar; Merchant Scroll; Mind’s Desire; Mox Emerald; Mox Jet; Mox Pearl; Mox Ruby; Mox Sapphire; Mystical Tutor; Necropotence; Ponder; Sol Ring; Strip Mine; Thirst for Knowledge; Time Vault; Time Walk; Timetwister; Tinker; Tolarian Academy; Trinisphere; Vampiric Tutor; Wheel of Fortune; Windfall; Yawgmoth’s Bargain; Yawgmoth’s Will \ No newline at end of file diff --git a/forge-gui/src/main/java/forge/quest/data/GameFormatQuest.java b/forge-gui/src/main/java/forge/quest/data/GameFormatQuest.java index 04df85d125c..af9a329de61 100644 --- a/forge-gui/src/main/java/forge/quest/data/GameFormatQuest.java +++ b/forge-gui/src/main/java/forge/quest/data/GameFormatQuest.java @@ -65,7 +65,7 @@ public final class GameFormatQuest extends GameFormat { * @param allowSetUnlocks */ public GameFormatQuest(final GameFormat toCopy, boolean allowSetUnlocks) { - super(toCopy.getName(), toCopy.getAllowedSetCodes(), toCopy.getBannedCardNames(), toCopy.getIndex()); + super(toCopy.getName(), toCopy.getAllowedSetCodes(), toCopy.getBannedCardNames(), toCopy.getRestrictedCards(), toCopy.getIndex()); allowUnlocks = allowSetUnlocks; } @@ -96,7 +96,7 @@ public final class GameFormatQuest extends GameFormat { * @param setCode String, set code. */ public void unlockSet(final String setCode) { - if (!canUnlockSets() || this.allowedSetCodes.isEmpty() || this.allowedSetCodes.contains(setCode)) { + if (!canUnlockSets() || this.allowedSetCodes_ro.isEmpty() || this.allowedSetCodes_ro.contains(setCode)) { return; } this.allowedSetCodes.add(setCode);