CardDb - split DB in two parts: one is for common cards and another one is for avatars, planes, schemes and phenomena (CardDb.variants)

ChooseCardName - cards are sorted and filtered if criteria is nonland, basic or creature
This commit is contained in:
Maxmtg
2013-02-16 00:07:10 +00:00
parent 04549ba5e2
commit edf05dacb4
32 changed files with 224 additions and 187 deletions

View File

@@ -2061,7 +2061,7 @@ public class Card extends GameEntity implements Comparable<Card> {
// Vanguard Modifiers // Vanguard Modifiers
if (this.isType("Vanguard")) { if (this.isType("Vanguard")) {
final CardPrinted avatar = CardDb.instance().getCard(this); final CardPrinted avatar = CardDb.getCard(this);
sb.append("Hand Modifier: "); sb.append("Hand Modifier: ");
sb.append(avatar.getCard().getHand()); sb.append(avatar.getCard().getHand());
sb.append("\r\nLife Modifier: "); sb.append("\r\nLife Modifier: ");

View File

@@ -122,7 +122,7 @@ public class BoosterGenerator {
public BoosterGenerator(Predicate<CardPrinted> filter) { public BoosterGenerator(Predicate<CardPrinted> filter) {
this(); this();
for (final CardPrinted c : Iterables.filter(CardDb.instance().getAllTraditionalCards(), filter)) { for (final CardPrinted c : Iterables.filter(CardDb.instance().getAllCards(), filter)) {
this.addToRarity(c); this.addToRarity(c);
// System.out.println(c); // System.out.println(c);
} }

View File

@@ -186,7 +186,7 @@ public final class CardEdition implements Comparable<CardEdition> { // immutable
public static final Predicate<CardEdition> hasBasicLands = new Predicate<CardEdition>() { public static final Predicate<CardEdition> hasBasicLands = new Predicate<CardEdition>() {
@Override @Override
public boolean apply(CardEdition ed) { public boolean apply(CardEdition ed) {
return CardDb.instance().isCardSupported("Plains", ed.getCode()); return null != CardDb.instance().tryGetCard("Plains", ed.getCode());
}; };
}; };

View File

@@ -415,4 +415,9 @@ public final class CardRules {
} }
public boolean isTraditional() {
return !(getType().isVanguard() || getType().isScheme() || getType().isPlane() || getType().isPhenomenon());
}
} }

View File

@@ -226,7 +226,7 @@ public class MetaSet {
// NOTE: The following code is far from ideal in a number of ways. If someone can // NOTE: The following code is far from ideal in a number of ways. If someone can
// think of a way to improve it, please do so. --BBU // think of a way to improve it, please do so. --BBU
// ItemPool<CardPrinted> cardPool = new ItemPool<CardPrinted>(CardPrinted.class); // ItemPool<CardPrinted> cardPool = new ItemPool<CardPrinted>(CardPrinted.class);
for (CardPrinted aCard : CardDb.instance().getAllTraditionalCards()) { for (CardPrinted aCard : CardDb.instance().getAllCards()) {
if (data.indexOf(aCard.getEdition()) > -1) { if (data.indexOf(aCard.getEdition()) > -1) {
cardPool.add(aCard); cardPool.add(aCard);
// System.out.println("Added card" + aCard.getName()); // System.out.println("Added card" + aCard.getName());
@@ -293,7 +293,7 @@ public class MetaSet {
if (mSet.type.equalsIgnoreCase("meta") || mSet.type.equalsIgnoreCase("booster") if (mSet.type.equalsIgnoreCase("meta") || mSet.type.equalsIgnoreCase("booster")
|| mSet.type.equalsIgnoreCase("pack")) { || mSet.type.equalsIgnoreCase("pack")) {
final String mData = new String(mSet.data); final String mData = new String(mSet.data);
for (CardPrinted aCard : CardDb.instance().getAllTraditionalCards()) { for (CardPrinted aCard : CardDb.instance().getAllCards()) {
if (mData.indexOf(aCard.getEdition()) > -1) { if (mData.indexOf(aCard.getEdition()) > -1) {
if (!cardPool.contains(aCard)) { if (!cardPool.contains(aCard)) {
cardPool.add(aCard); cardPool.add(aCard);

View File

@@ -785,7 +785,7 @@ public class ChangeZoneEffect extends SpellEffect {
} }
} }
if (sa.hasParam("Reveal") && !movedCards.isEmpty()) { if (sa.hasParam("Reveal") && !movedCards.isEmpty()) {
GuiChoose.one(card + " - Revealed card: ", movedCards.toArray()); GuiChoose.one(card + " - Revealed card: ", movedCards);
} }
if ((origin.contains(ZoneType.Library) && !destination.equals(ZoneType.Library) && !defined) if ((origin.contains(ZoneType.Library) && !destination.equals(ZoneType.Library) && !defined)

View File

@@ -1,13 +1,20 @@
package forge.card.ability.effects; package forge.card.ability.effects;
import java.util.Collections;
import java.util.List; import java.util.List;
import org.apache.commons.lang3.StringUtils;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates; import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import forge.Card; import forge.Card;
import forge.CardLists; import forge.CardLists;
import forge.Singletons; import forge.Singletons;
import forge.CardPredicates.Presets; import forge.CardPredicates.Presets;
import forge.card.CardRulesPredicates;
import forge.card.ability.SpellEffect; import forge.card.ability.SpellEffect;
import forge.card.cardfactory.CardFactoryUtil; import forge.card.cardfactory.CardFactoryUtil;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
@@ -51,10 +58,29 @@ public class ChooseCardNameEffect extends SpellEffect {
boolean ok = false; boolean ok = false;
while (!ok) { while (!ok) {
if (p.isHuman()) { if (p.isHuman()) {
final String message = validDesc.equals("card") ? "Name a card" : "Name a " + validDesc
+ " card. (Case sensitive)";
CardPrinted cp = GuiChoose.one(message, CardDb.instance().getAllUniqueCards()); final String message = validDesc.equals("card") ? "Name a card" : "Name a " + validDesc + " card.";
List<CardPrinted> cards = Lists.newArrayList(CardDb.instance().getAllUniqueCards());
if ( StringUtils.containsIgnoreCase(valid, "nonland") )
{
Predicate<CardPrinted> cpp = Predicates.compose(CardRulesPredicates.Presets.IS_NON_LAND, CardPrinted.FN_GET_RULES);
cards = Lists.newArrayList(Iterables.filter(cards, cpp));
}
if ( StringUtils.containsIgnoreCase(valid, "nonbasic") )
{
Predicate<CardPrinted> cpp = Predicates.compose(Predicates.not(CardRulesPredicates.Presets.IS_BASIC_LAND), CardPrinted.FN_GET_RULES);
cards = Lists.newArrayList(Iterables.filter(cards, cpp));
}
if ( StringUtils.containsIgnoreCase(valid, "creature") )
{
Predicate<CardPrinted> cpp = Predicates.compose(CardRulesPredicates.Presets.IS_CREATURE, CardPrinted.FN_GET_RULES);
cards = Lists.newArrayList(Iterables.filter(cards, cpp));
}
Collections.sort(cards);
CardPrinted cp = GuiChoose.one(message, cards);
if (cp.getMatchingForgeCard().isValid(valid, host.getController(), host)) { if (cp.getMatchingForgeCard().isValid(valid, host.getController(), host)) {
host.setNamedCard(cp.getName()); host.setNamedCard(cp.getName());
ok = true; ok = true;

View File

@@ -82,7 +82,7 @@ public class CopyPermanentEffect extends SpellEffect {
if (!c.isToken() || c.isCopiedToken()) { if (!c.isToken() || c.isCopiedToken()) {
// copy creature and put it onto the battlefield // copy creature and put it onto the battlefield
copy = Singletons.getModel().getCardFactory().getCard(CardDb.instance().getCard(c), sa.getActivatingPlayer()); copy = Singletons.getModel().getCardFactory().getCard(CardDb.getCard(c), sa.getActivatingPlayer());
// when copying something stolen: // when copying something stolen:
copy.addController(controller); copy.addController(controller);

View File

@@ -150,7 +150,7 @@ public class PlayEffect extends SpellEffect {
source.clearRemembered(); source.clearRemembered();
} }
if (sa.hasParam("CopyCard")) { if (sa.hasParam("CopyCard")) {
tgtCard = Singletons.getModel().getCardFactory().getCard(CardDb.instance().getCard(tgtCard), sa.getActivatingPlayer()); tgtCard = Singletons.getModel().getCardFactory().getCard(CardDb.getCard(tgtCard), sa.getActivatingPlayer());
// when copying something stolen: // when copying something stolen:
tgtCard.addController(sa.getActivatingPlayer()); tgtCard.addController(sa.getActivatingPlayer());

View File

@@ -99,7 +99,7 @@ public class CardFactory {
if (in.isInAlternateState()) { if (in.isInAlternateState()) {
in.setState(CardCharacteristicName.Original); in.setState(CardCharacteristicName.Original);
} }
final Card out = this.getCard(CardDb.instance().getCard(in), in.getOwner()); final Card out = this.getCard(CardDb.getCard(in), in.getOwner());
out.setUniqueNumber(in.getUniqueNumber()); out.setUniqueNumber(in.getUniqueNumber());
CardFactoryUtil.copyCharacteristics(in, out); CardFactoryUtil.copyCharacteristics(in, out);

View File

@@ -58,7 +58,7 @@ public class CardPool extends ItemPool<CardPrinted> {
public void set(final Iterable<String> cardNames) { public void set(final Iterable<String> cardNames) {
this.clear(); this.clear();
for (final String name : cardNames) { for (final String name : cardNames) {
this.add(CardDb.instance().getCard(name)); this.add(name);
} }
} }
@@ -69,7 +69,7 @@ public class CardPool extends ItemPool<CardPrinted> {
* the card * the card
*/ */
public void add(final Card card) { public void add(final Card card) {
this.add(CardDb.instance().getCard(card)); this.add(CardDb.getCard(card));
} }
/** /**
@@ -81,7 +81,7 @@ public class CardPool extends ItemPool<CardPrinted> {
* the set code * the set code
*/ */
public void add(final String cardName, final String setCode) { public void add(final String cardName, final String setCode) {
this.add(CardDb.instance().getCard(cardName, setCode)); this.add(cardName, setCode, 1);
} }
/** /**
@@ -92,7 +92,14 @@ public class CardPool extends ItemPool<CardPrinted> {
* @param amount the amount * @param amount the amount
*/ */
public void add(final String cardName, final String setCode, final int amount) { public void add(final String cardName, final String setCode, final int amount) {
this.add(CardDb.instance().getCard(cardName, setCode), amount); CardPrinted cp = CardDb.instance().tryGetCard(cardName, setCode);
if ( cp == null )
cp = CardDb.variants().tryGetCard(cardName, setCode);
if ( cp != null)
this.add(cp, amount);
else
throw new RuntimeException(String.format("Card %s from %s is not supported by Forge, as it's neither a known common card nor one of casual variants' card.", cardName, setCode ));
} }
/** /**
@@ -125,7 +132,14 @@ public class CardPool extends ItemPool<CardPrinted> {
* @param cardName the card name * @param cardName the card name
*/ */
public void add(final String cardName) { public void add(final String cardName) {
this.add(CardDb.instance().getCard(cardName)); CardPrinted cp = CardDb.instance().tryGetCard(cardName);
if ( cp == null )
cp = CardDb.variants().tryGetCard(cardName);
if ( cp != null)
this.add(cp);
else
throw new RuntimeException(String.format("Card %s is not supported by Forge, as it's neither a known common card nor one of casual variants' card.", cardName));
} }
/** /**

View File

@@ -189,7 +189,7 @@ public class DeckRecognizer {
* Token(cardName, amount); } * Token(cardName, amount); }
*/ */
else { else {
if (CardDb.instance().isCardSupported(line)) { if (null != CardDb.instance().tryGetCard(line)) {
return Token.knownCard(CardDb.instance().getCard(line, newestEdition), 1); return Token.knownCard(CardDb.instance().getCard(line, newestEdition), 1);
} }
result = DeckRecognizer.recognizeNonCard(line, 1); result = DeckRecognizer.recognizeNonCard(line, 1);
@@ -198,7 +198,7 @@ public class DeckRecognizer {
} }
private static Token recognizePossibleNameAndNumber(final String name, final int n, final boolean newestEdition) { private static Token recognizePossibleNameAndNumber(final String name, final int n, final boolean newestEdition) {
if (CardDb.instance().isCardSupported(name)) { if (null != CardDb.instance().tryGetCard(name)) {
return Token.knownCard(CardDb.instance().getCard(name, newestEdition), n); return Token.knownCard(CardDb.instance().getCard(name, newestEdition), n);
} }

View File

@@ -314,7 +314,7 @@ public class DeckgenUtil {
public static CardPool generateSchemeDeck() { public static CardPool generateSchemeDeck() {
CardPool schemes = new CardPool(); CardPool schemes = new CardPool();
List<CardPrinted> allSchemes = new ArrayList<CardPrinted>(); List<CardPrinted> allSchemes = new ArrayList<CardPrinted>();
for (CardPrinted c : CardDb.instance().getAllNonTraditionalCards()) { for (CardPrinted c : CardDb.variants().getAllCards()) {
if (c.getCard().getType().isScheme()) { if (c.getCard().getType().isScheme()) {
allSchemes.add(c); allSchemes.add(c);
} }
@@ -339,7 +339,7 @@ public class DeckgenUtil {
public static CardPool generatePlanarDeck() { public static CardPool generatePlanarDeck() {
CardPool res = new CardPool(); CardPool res = new CardPool();
List<CardPrinted> allPlanars = new ArrayList<CardPrinted>(); List<CardPrinted> allPlanars = new ArrayList<CardPrinted>();
for (CardPrinted c : CardDb.instance().getAllNonTraditionalCards()) { for (CardPrinted c : CardDb.variants().getAllCards()) {
if (c.getCard().getType().isPlane() || c.getCard().getType().isPhenomenon()) { if (c.getCard().getType().isPlane() || c.getCard().getType().isPhenomenon()) {
allPlanars.add(c); allPlanars.add(c);
} }

View File

@@ -224,7 +224,7 @@ public abstract class GenerateColoredDeckBase {
if (!Singletons.getModel().getPreferences().getPrefBoolean(FPref.DECKGEN_ARTIFACTS)) { if (!Singletons.getModel().getPreferences().getPrefBoolean(FPref.DECKGEN_ARTIFACTS)) {
hasColor = Predicates.or(hasColor, GenerateDeckUtil.COLORLESS_CARDS); hasColor = Predicates.or(hasColor, GenerateDeckUtil.COLORLESS_CARDS);
} }
return Iterables.filter(CardDb.instance().getAllTraditionalCards(), Predicates.compose(Predicates.and(canPlay, hasColor), CardPrinted.FN_GET_RULES)); return Iterables.filter(CardDb.instance().getAllCards(), Predicates.compose(Predicates.and(canPlay, hasColor), CardPrinted.FN_GET_RULES));
} }
protected static Map<String, Integer> countLands(ItemPool<CardPrinted> outList) { protected static Map<String, Integer> countLands(ItemPool<CardPrinted> outList) {

View File

@@ -265,7 +265,7 @@ public class LimitedDeck {
private void findBasicLandSets() { private void findBasicLandSets() {
Set<String> sets = new HashSet<String>(); Set<String> sets = new HashSet<String>();
for (CardPrinted cp : aiPlayables) { for (CardPrinted cp : aiPlayables) {
if (CardDb.instance().isCardSupported("Plains", cp.getEdition())) { if (null != CardDb.instance().tryGetCard("Plains", cp.getEdition())) {
sets.add(cp.getEdition()); sets.add(cp.getEdition());
} }
} }

View File

@@ -89,7 +89,7 @@ public class GuiDialog {
* @return a boolean. * @return a boolean.
*/ */
public static boolean flipCoin(final Player caller, final Card source) { public static boolean flipCoin(final Player caller, final Card source) {
String choice = ""; String choice;
final String[] choices = { "heads", "tails" }; final String[] choices = { "heads", "tails" };
final boolean flip = MyRandom.getRandom().nextBoolean(); final boolean flip = MyRandom.getRandom().nextBoolean();
@@ -99,7 +99,7 @@ public class GuiDialog {
choice = choices[MyRandom.getRandom().nextInt(2)]; choice = choices[MyRandom.getRandom().nextInt(2)];
} }
final boolean winFlip = flip == choice.equals("heads"); final boolean winFlip = flip == choice.equals(choices[0]);
final String winMsg = winFlip ? " wins flip." : " loses flip."; final String winMsg = winFlip ? " wins flip." : " loses flip.";
// Play the Flip A Coin sound // Play the Flip A Coin sound

View File

@@ -491,7 +491,7 @@ public final class GuiMigrateLocalMWSSetPicturesHQ extends DefaultBoundedRangeMo
final String urlBase = "C:\\MTGForge\\HQPICS\\"; final String urlBase = "C:\\MTGForge\\HQPICS\\";
String imgFN = ""; String imgFN = "";
for (final CardPrinted cp : CardDb.instance().getAllTraditionalCards()) { for (final CardPrinted cp : CardDb.instance().getAllCards()) {
// String url = c.getSVar("Picture"); // String url = c.getSVar("Picture");
// String[] URLs = url.split("\\\\"); // String[] URLs = url.split("\\\\");

View File

@@ -152,7 +152,7 @@ public final class CEditorConstructed extends ACEditorBase<CardPrinted, Deck> {
@Override @Override
public void resetTables() { public void resetTables() {
// Constructed mode can use all cards, no limitations. // Constructed mode can use all cards, no limitations.
this.getTableCatalog().setDeck(ItemPool.createFrom(CardDb.instance().getAllTraditionalCards(), CardPrinted.class), true); this.getTableCatalog().setDeck(ItemPool.createFrom(CardDb.instance().getAllCards(), CardPrinted.class), true);
this.getTableDeck().setDeck(this.controller.getModel().getMain()); this.getTableDeck().setDeck(this.controller.getModel().getMain());
} }
@@ -179,7 +179,7 @@ public final class CEditorConstructed extends ACEditorBase<CardPrinted, Deck> {
} else { } else {
lstCatalogCols.remove(SColumnUtil.getColumn(ColumnName.CAT_QUANTITY)); lstCatalogCols.remove(SColumnUtil.getColumn(ColumnName.CAT_QUANTITY));
this.getTableCatalog().setAvailableColumns(lstCatalogCols); this.getTableCatalog().setAvailableColumns(lstCatalogCols);
this.getTableCatalog().setDeck(ItemPool.createFrom(CardDb.instance().getAllTraditionalCards(), CardPrinted.class), true); this.getTableCatalog().setDeck(ItemPool.createFrom(CardDb.instance().getAllCards(), CardPrinted.class), true);
this.getTableDeck().setDeck(this.controller.getModel().getMain()); this.getTableDeck().setDeck(this.controller.getModel().getMain());
} }

View File

@@ -96,7 +96,7 @@ public final class CEditorQuestCardShop extends ACEditorBase<InventoryItem, Deck
private ItemPoolView<InventoryItem> cardsForSale; private ItemPoolView<InventoryItem> cardsForSale;
private final ItemPool<InventoryItem> fullCatalogCards = private final ItemPool<InventoryItem> fullCatalogCards =
ItemPool.createFrom(CardDb.instance().getAllTraditionalCards(), InventoryItem.class); ItemPool.createFrom(CardDb.instance().getAllCards(), InventoryItem.class);
private boolean showingFullCatalog = false; private boolean showingFullCatalog = false;
private DragCell allDecksParent = null; private DragCell allDecksParent = null;
private DragCell deckGenParent = null; private DragCell deckGenParent = null;

View File

@@ -141,7 +141,7 @@ public final class CEditorVariant extends ACEditorBase<CardPrinted, Deck> {
*/ */
@Override @Override
public void resetTables() { public void resetTables() {
Iterable<CardPrinted> allNT = CardDb.instance().getAllNonTraditionalCards(); Iterable<CardPrinted> allNT = CardDb.variants().getAllCards();
allNT = Iterables.filter(allNT, cardPoolCondition); allNT = Iterables.filter(allNT, cardPoolCondition);
this.getTableCatalog().setDeck(ItemPool.createFrom(allNT, CardPrinted.class), true); this.getTableCatalog().setDeck(ItemPool.createFrom(allNT, CardPrinted.class), true);

View File

@@ -92,7 +92,7 @@ public class GuiDownloadSetPicturesLQ extends GuiDownloader {
// read token names and urls // read token names and urls
final ArrayList<DownloadObject> cList = new ArrayList<DownloadObject>(); final ArrayList<DownloadObject> cList = new ArrayList<DownloadObject>();
Iterable<CardPrinted> allPrinted = Iterables.concat(CardDb.instance().getAllTraditionalCards(), CardDb.instance().getAllNonTraditionalCards()); Iterable<CardPrinted> allPrinted = Iterables.concat(CardDb.instance().getAllCards(), CardDb.variants().getAllCards());
for (final CardPrinted c : allPrinted) { for (final CardPrinted c : allPrinted) {
final String setCode3 = c.getEdition(); final String setCode3 = c.getEdition();

View File

@@ -358,7 +358,7 @@ public enum VSubmenuVanguard implements IVSubmenu<CSubmenuVanguard> {
*/ */
public Iterable<CardPrinted> getAllAvatars() { public Iterable<CardPrinted> getAllAvatars() {
if ( allAvatars.isEmpty() ) { if ( allAvatars.isEmpty() ) {
for(CardPrinted c : CardDb.instance().getAllNonTraditionalCards()) { for(CardPrinted c : CardDb.variants().getAllCards()) {
if( c.getCard().getType().isVanguard()) if( c.getCard().getType().isVanguard())
allAvatars.add(c); allAvatars.add(c);
} }

View File

@@ -135,7 +135,7 @@ public class ControlWinLose {
Deck oDeck = match.getPlayersOriginalDeck(loser.getLobbyPlayer()); Deck oDeck = match.getPlayersOriginalDeck(loser.getLobbyPlayer());
for (Card c : compAntes) { for (Card c : compAntes) {
CardPrinted toRemove = CardDb.instance().getCard(c); CardPrinted toRemove = CardDb.getCard(c);
cDeck.getMain().remove(toRemove); cDeck.getMain().remove(toRemove);
if ( cDeck != oDeck ) if ( cDeck != oDeck )
oDeck.getMain().remove(toRemove); oDeck.getMain().remove(toRemove);

View File

@@ -135,7 +135,7 @@ public class QuestWinLose extends ControlWinLose {
continue; continue;
} }
for (Card c : p.getCardsIn(ZoneType.Ante)) { for (Card c : p.getCardsIn(ZoneType.Ante)) {
anteCards.add(CardDb.instance().getCard(c)); anteCards.add(CardDb.getCard(c));
} }
} }

View File

@@ -20,12 +20,12 @@ package forge.item;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Hashtable;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.TreeMap;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@@ -37,7 +37,6 @@ import com.google.common.collect.Iterables;
import forge.Card; import forge.Card;
import forge.card.CardInSet; import forge.card.CardInSet;
import forge.card.CardRules; import forge.card.CardRules;
import forge.card.MtgDataParser;
import forge.util.Aggregates; import forge.util.Aggregates;
@@ -50,8 +49,8 @@ import forge.util.Aggregates;
* @version $Id: CardDb.java 9708 2011-08-09 19:34:12Z jendave $ * @version $Id: CardDb.java 9708 2011-08-09 19:34:12Z jendave $
*/ */
public final class CardDb { public final class CardDb {
private static volatile CardDb onlyInstance = null; // 'volatile' keyword private static volatile CardDb commonCards = null; // 'volatile' keyword makes this working
// makes this working private static volatile CardDb variantCards = null; // 'volatile' keyword makes this working
private final String foilSuffix = " foil"; private final String foilSuffix = " foil";
/** /**
@@ -60,12 +59,20 @@ public final class CardDb {
* @return the card db * @return the card db
*/ */
public static CardDb instance() { public static CardDb instance() {
if (CardDb.onlyInstance == null) { if (CardDb.commonCards == null) {
throw new NullPointerException("CardDb has not yet been initialized, run setup() first"); throw new NullPointerException("CardDb has not yet been initialized, run setup() first");
} }
return CardDb.onlyInstance; return CardDb.commonCards;
} }
public static CardDb variants() {
if (CardDb.variantCards == null) {
throw new NullPointerException("CardDb has not yet been initialized, run setup() first");
}
return CardDb.variantCards;
}
/** /**
* Sets the up. * Sets the up.
* *
@@ -73,14 +80,14 @@ public final class CardDb {
* the new up * the new up
*/ */
public static void setup(final Iterator<CardRules> list) { public static void setup(final Iterator<CardRules> list) {
if (CardDb.onlyInstance != null) { if (CardDb.commonCards != null) {
throw new RuntimeException("CardDb has already been initialized, don't do it twice please"); throw new RuntimeException("CardDb has already been initialized, don't do it twice please");
} }
synchronized (CardDb.class) { synchronized (CardDb.class) {
if (CardDb.onlyInstance == null) { // It's broken under 1.4 and if (CardDb.commonCards == null) { // It's broken under 1.4 and below, on 1.5+ works again!
// below, on CardSorter cs = new CardSorter(list);
// 1.5+ works again! commonCards = new CardDb(cs.uniqueCommonCards, cs.allCommonCardsFlat, cs.allCommonCardsBySet);
CardDb.onlyInstance = new CardDb(list); variantCards = new CardDb(cs.uniqueSpecialCards, cs.allSpecialCardsFlat, cs.allSpecialCardsBySet);
} }
} }
} }
@@ -92,12 +99,11 @@ public final class CardDb {
// Here are refs, get them by name // Here are refs, get them by name
private final Map<String, CardPrinted> uniqueCards; private final Map<String, CardPrinted> uniqueCards;
// need this to obtain cardReference by name+set+artindex
private final Map<String, Map<String, CardPrinted[]>> allCardsBySet = new Hashtable<String, Map<String, CardPrinted[]>>();
// this is the same list in flat storage
private final List<CardPrinted> allTraditionalCardsFlat = new ArrayList<CardPrinted>();
private final List<CardPrinted> allNonTraditionalCardsFlat = new ArrayList<CardPrinted>(); // need this to obtain cardReference by name+set+artindex
private final Map<String, Map<String, CardPrinted[]>> allCardsBySet;
// this is the same list in flat storage
private final List<CardPrinted> allCardsFlat;
// Lambda to get rules for selects from list of printed cards // Lambda to get rules for selects from list of printed cards
/** The Constant fnGetCardPrintedByForgeCard. */ /** The Constant fnGetCardPrintedByForgeCard. */
@@ -108,80 +114,10 @@ public final class CardDb {
} }
}; };
private CardDb() { private CardDb(Map<String, CardPrinted> uniqueCards, List<CardPrinted> cardsFlat, Map<String, Map<String, CardPrinted[]>> cardsBySet) {
this(new MtgDataParser()); // I wish cardname.txt parser was here. this.uniqueCards = Collections.unmodifiableMap(uniqueCards);
} this.allCardsFlat = Collections.unmodifiableList(cardsFlat);
this.allCardsBySet = cardsBySet;
private CardDb(final Iterator<CardRules> parser) {
Map<String, CardPrinted> uniques = new Hashtable<String, CardPrinted>();
while (parser.hasNext()) {
this.addNewCard(parser.next(), uniques);
}
this.uniqueCards = Collections.unmodifiableMap(uniques);
}
/**
* Adds the new card.
*
* @param card
* the card
*/
private void addNewCard(final CardRules card, Map<String, CardPrinted> uniques) {
if (null == card) {
return;
} // consider that a success
// System.out.println(card.getName());
final String cardName = card.getName().toLowerCase();
// 1. register among oracle uniques
// cards.put(cardName, card);
// 2. Save refs into two lists: one flat and other keyed with sets &
// name
CardPrinted lastAdded = null;
for (final Entry<String, CardInSet> s : card.getSetsPrinted()) {
lastAdded = this.addToLists(card, cardName, s);
}
uniques.put(cardName, lastAdded);
}
/**
* Adds the to lists.
*
* @param card
* the card
* @param cardName
* the card name
* @param s
* the s
* @return the card printed
*/
public CardPrinted addToLists(final CardRules card, final String cardName, final Entry<String, CardInSet> s) {
CardPrinted lastAdded = null;
final String set = s.getKey();
// get this set storage, if not found, create it!
Map<String, CardPrinted[]> setMap = this.allCardsBySet.get(set);
if (null == setMap) {
setMap = new Hashtable<String, CardPrinted[]>();
this.allCardsBySet.put(set, setMap);
}
final int count = s.getValue().getCopiesCount();
final CardPrinted[] cardCopies = new CardPrinted[count];
setMap.put(cardName, cardCopies);
for (int i = 0; i < count; i++) {
lastAdded = CardPrinted.build(card, set, s.getValue().getRarity(), i);
if (lastAdded.isTraditional()) {
this.allTraditionalCardsFlat.add(lastAdded);
} else {
this.allNonTraditionalCardsFlat.add(lastAdded);
}
cardCopies[i] = lastAdded;
}
return lastAdded;
} }
/** /**
@@ -223,29 +159,29 @@ public final class CardDb {
* the card name * the card name
* @return true, if is card supported * @return true, if is card supported
*/ */
public boolean isCardSupported(final String cardName0) { public CardPrinted tryGetCard(final String cardName0) {
if (null == cardName0) { if (null == cardName0) {
return false; // obviously return null; // obviously
} }
final boolean isFoil = this.isFoil(cardName0); final boolean isFoil = this.isFoil(cardName0);
final String cardName = isFoil ? this.removeFoilSuffix(cardName0) : cardName0; final String cardName = isFoil ? this.removeFoilSuffix(cardName0) : cardName0;
final ImmutablePair<String, String> nameWithSet = CardDb.splitCardName(cardName); final ImmutablePair<String, String> nameWithSet = CardDb.splitCardName(cardName);
if (nameWithSet.right == null) { if (nameWithSet.right == null) {
return this.uniqueCards.containsKey(nameWithSet.left.toLowerCase()); return this.uniqueCards.get(nameWithSet.left);
} }
return isCardSupported(nameWithSet.left, nameWithSet.right); return tryGetCard(nameWithSet.left, nameWithSet.right);
} }
public boolean isCardSupported(final String cardName, String setName) { public CardPrinted tryGetCard(final String cardName, String setName) {
// Set exists? // Set exists?
final Map<String, CardPrinted[]> cardsFromset = this.allCardsBySet.get(setName.toUpperCase()); final Map<String, CardPrinted[]> cardsFromset = this.allCardsBySet.get(setName.toUpperCase());
if (cardsFromset == null) { if (cardsFromset == null) {
return false; return null;
} }
// Card exists? // Card exists?
final CardPrinted[] cardCopies = cardsFromset.get(cardName.toLowerCase()); final CardPrinted[] cardCopies = cardsFromset.get(cardName.toLowerCase());
return (cardCopies != null) && (cardCopies.length > 0); return cardCopies != null ? cardCopies[0] : null;
} }
// Single fetch // Single fetch
@@ -318,27 +254,17 @@ public final class CardDb {
* the forge card * the forge card
* @return the card * @return the card
*/ */
public CardPrinted getCard(final Card forgeCard) { public static CardPrinted getCard(final Card forgeCard) {
final String name = forgeCard.getName(); final String name = forgeCard.getName();
final String set = forgeCard.getCurSetCode(); final String set = forgeCard.getCurSetCode();
if (StringUtils.isNotBlank(set)) {
return this.getCard(name, set);
}
return this.getCard(name);
}
/** if (StringUtils.isNotBlank(set)) {
* Gets the cards from latest sets. CardPrinted cp = variants().tryGetCard(name, set);
*
* @param names the names return cp == null ? instance().getCard(name, set) : cp;
* @return the cards from latest sets
*/
public List<CardPrinted> getCardsFromLatestSets(final Iterable<String> names) {
final List<CardPrinted> result = new ArrayList<CardPrinted>();
for (final String name : names) {
result.add(this.getCard(name, true));
} }
return result; CardPrinted cp = variants().tryGetCard(name);
return cp == null ? instance().getCard(name) : cp;
} }
// returns a list of all cards from their respective latest editions // returns a list of all cards from their respective latest editions
@@ -351,6 +277,8 @@ public final class CardDb {
return this.uniqueCards.values(); return this.uniqueCards.values();
} }
// public Iterable<CardRules> getAllCardRules() { return cards.values(); } // public Iterable<CardRules> getAllCardRules() { return cards.values(); }
// // still not needed // // still not needed
/** /**
@@ -358,12 +286,8 @@ public final class CardDb {
* *
* @return the all cards * @return the all cards
*/ */
public Iterable<CardPrinted> getAllTraditionalCards() { public Collection<CardPrinted> getAllCards() {
return this.allTraditionalCardsFlat; return this.allCardsFlat;
}
public Iterable<CardPrinted> getAllNonTraditionalCards() {
return this.allNonTraditionalCardsFlat;
} }
/** /**
@@ -393,15 +317,10 @@ public final class CardDb {
} else { } else {
// OK, plain name here // OK, plain name here
final Predicate<CardPrinted> predicate = CardPrinted.Predicates.name(nameWithSet.left); final Predicate<CardPrinted> predicate = CardPrinted.Predicates.name(nameWithSet.left);
final Iterable<CardPrinted> namedCards = Iterables.filter(this.allTraditionalCardsFlat, predicate); final Iterable<CardPrinted> namedCards = Iterables.filter(this.allCardsFlat, predicate);
// Find card with maximal set index // Find card with maximal set index
result = Aggregates.itemWithMax(namedCards, CardPrinted.FN_GET_EDITION_INDEX); result = Aggregates.itemWithMax(namedCards, CardPrinted.FN_GET_EDITION_INDEX);
if (null == result) { if (null == result) {
// 2nd chance: look in planes, schemes and so on
final Iterable<CardPrinted> namedNonTraditionals = Iterables.filter(this.allNonTraditionalCardsFlat, predicate);
result = Aggregates.itemWithMax(namedNonTraditionals, CardPrinted.FN_GET_EDITION_INDEX);
if ( null == result ) // sure thing, throw exception
throw new NoSuchElementException(String.format("Card '%s' not found in our database.", name)); throw new NoSuchElementException(String.format("Card '%s' not found in our database.", name));
} }
@@ -413,4 +332,92 @@ public final class CardDb {
return result; return result;
} }
private static class CardSorter{
// Here oracle cards
// private final Map<String, CardRules> cards = new Hashtable<String,
// CardRules>();
// need this to obtain cardReference by name+set+artindex
public final Map<String, Map<String, CardPrinted[]>> allCommonCardsBySet = new TreeMap<String, Map<String, CardPrinted[]>>(String.CASE_INSENSITIVE_ORDER);
public final Map<String, Map<String, CardPrinted[]>> allSpecialCardsBySet = new TreeMap<String, Map<String, CardPrinted[]>>(String.CASE_INSENSITIVE_ORDER);
// Here are refs, get them by name
public final Map<String, CardPrinted> uniqueCommonCards = new TreeMap<String, CardPrinted>(String.CASE_INSENSITIVE_ORDER);
public final Map<String, CardPrinted> uniqueSpecialCards = new TreeMap<String, CardPrinted>(String.CASE_INSENSITIVE_ORDER);
// this is the same list in flat storage
public final List<CardPrinted> allCommonCardsFlat = new ArrayList<CardPrinted>();
public final List<CardPrinted> allSpecialCardsFlat = new ArrayList<CardPrinted>();
/**
* Adds the to lists.
*
* @param card
* the card
* @param cardName
* the card name
* @param s
* the s
* @return the card printed
*/
public CardPrinted addToLists(final CardRules card, final String cardName, final Entry<String, CardInSet> s) {
CardPrinted lastAdded = null;
final String set = s.getKey();
final Map<String, Map<String, CardPrinted[]>> allCardsBySet = card.isTraditional() ? allCommonCardsBySet : allSpecialCardsBySet;
// get this set storage, if not found, create it!
Map<String, CardPrinted[]> setMap = allCardsBySet.get(set);
if (null == setMap) {
setMap = new TreeMap<String, CardPrinted[]>(String.CASE_INSENSITIVE_ORDER);
allCardsBySet.put(set, setMap);
}
final int count = s.getValue().getCopiesCount();
final CardPrinted[] cardCopies = new CardPrinted[count];
setMap.put(cardName, cardCopies);
for (int i = 0; i < count; i++) {
lastAdded = CardPrinted.build(card, set, s.getValue().getRarity(), i);
if (card.isTraditional()) {
this.allCommonCardsFlat.add(lastAdded);
} else {
this.allSpecialCardsFlat.add(lastAdded);
}
cardCopies[i] = lastAdded;
}
return lastAdded;
}
/**
* Adds the new card.
*
* @param card
* the card
*/
private void addNewCard(final CardRules card) {
if (null == card) {
return;
} // consider that a success
// System.out.println(card.getName());
final String cardName = card.getName().toLowerCase();
// 1. register among oracle uniques
// cards.put(cardName, card);
// 2. Save refs into two lists: one flat and other keyed with sets &
// name
CardPrinted lastAdded = null;
for (final Entry<String, CardInSet> s : card.getSetsPrinted()) {
lastAdded = this.addToLists(card, cardName, s);
}
if ( lastAdded.getCard().isTraditional() )
uniqueCommonCards.put(cardName, lastAdded);
else
uniqueSpecialCards.put(cardName, lastAdded);
}
CardSorter(final Iterator<CardRules> parser) {
while (parser.hasNext()) {
this.addNewCard(parser.next());
}
}
}
} }

View File

@@ -115,13 +115,6 @@ public final class CardPrinted implements Comparable<CardPrinted>, InventoryItem
return this.foiled; return this.foiled;
} }
public boolean isTraditional() {
return !(getCard().getType().isVanguard()
|| getCard().getType().isScheme()
|| getCard().getType().isPlane()
|| getCard().getType().isPhenomenon());
}
/** /**
* Gets the card. * Gets the card.
* *

View File

@@ -175,7 +175,7 @@ public abstract class OpenablePack implements InventoryItemFromSet {
Predicate<CardPrinted> cardsRule = Predicates.and( Predicate<CardPrinted> cardsRule = Predicates.and(
CardPrinted.Predicates.printedInSets(setCode), CardPrinted.Predicates.printedInSets(setCode),
Predicates.compose(CardRulesPredicates.Presets.IS_BASIC_LAND, CardPrinted.FN_GET_RULES)); Predicates.compose(CardRulesPredicates.Presets.IS_BASIC_LAND, CardPrinted.FN_GET_RULES));
return Aggregates.random(Iterables.filter(CardDb.instance().getAllTraditionalCards(), cardsRule), count); return Aggregates.random(Iterables.filter(CardDb.instance().getAllCards(), cardsRule), count);
} }
} }

View File

@@ -88,7 +88,7 @@ public final class BoosterUtils {
} }
// This will save CPU time when sets are limited // This will save CPU time when sets are limited
final List<CardPrinted> cardpool = Lists.newArrayList(Iterables.filter(CardDb.instance().getAllTraditionalCards(), filter)); final List<CardPrinted> cardpool = Lists.newArrayList(Iterables.filter(CardDb.instance().getAllCards(), filter));
final Predicate<CardPrinted> pCommon = CardPrinted.Predicates.Presets.IS_COMMON; final Predicate<CardPrinted> pCommon = CardPrinted.Predicates.Presets.IS_COMMON;
cards.addAll(BoosterUtils.generateDefinetlyColouredCards(cardpool, pCommon, numCommon, colorFilters)); cards.addAll(BoosterUtils.generateDefinetlyColouredCards(cardpool, pCommon, numCommon, colorFilters));
@@ -180,7 +180,7 @@ public final class BoosterUtils {
* @return the list * @return the list
*/ */
public static List<CardPrinted> generateDistinctCards(final Predicate<CardPrinted> filter, final int cntNeeded) { public static List<CardPrinted> generateDistinctCards(final Predicate<CardPrinted> filter, final int cntNeeded) {
return BoosterUtils.generateDistinctCards(CardDb.instance().getAllTraditionalCards(), filter, cntNeeded); return BoosterUtils.generateDistinctCards(CardDb.instance().getAllCards(), filter, cntNeeded);
} }
/** /**

View File

@@ -223,7 +223,7 @@ public class QuestRewardCardChooser implements InventoryItem {
} else if (type == poolType.predicateFilter) { } else if (type == poolType.predicateFilter) {
List<CardPrinted> cardChoices = new ArrayList<CardPrinted>(); List<CardPrinted> cardChoices = new ArrayList<CardPrinted>();
for (final CardPrinted card : Iterables.filter(CardDb.instance().getAllTraditionalCards(), predicates)) { for (final CardPrinted card : Iterables.filter(CardDb.instance().getAllCards(), predicates)) {
cardChoices.add(card); cardChoices.add(card);
} }
Collections.sort(cardChoices); Collections.sort(cardChoices);

View File

@@ -171,7 +171,7 @@ public class QuestRewardCardFiltered implements IQuestRewardCard {
*/ */
public final List<CardPrinted> getChoices() { public final List<CardPrinted> getChoices() {
List<CardPrinted> cardChoices = new ArrayList<CardPrinted>(); List<CardPrinted> cardChoices = new ArrayList<CardPrinted>();
for (final CardPrinted card : Iterables.filter(CardDb.instance().getAllTraditionalCards(), predicates)) { for (final CardPrinted card : Iterables.filter(CardDb.instance().getAllCards(), predicates)) {
cardChoices.add(card); cardChoices.add(card);
} }
Collections.sort(cardChoices); Collections.sort(cardChoices);

View File

@@ -90,7 +90,7 @@ public final class QuestUtilCards {
if (usedFormat != null) { if (usedFormat != null) {
List<String> availableEditions = usedFormat.getAllowedSetCodes(); List<String> availableEditions = usedFormat.getAllowedSetCodes();
for (String edition : availableEditions) { for (String edition : availableEditions) {
if (db.isCardSupported("Plains", edition)) { if (null != db.tryGetCard("Plains", edition)) {
landCodes.add(edition); landCodes.add(edition);
} }
} }
@@ -205,7 +205,7 @@ public final class QuestUtilCards {
final Predicate<CardPrinted> myFilter = applyFormatFilter(QuestUtilCards.RARE_PREDICATE); final Predicate<CardPrinted> myFilter = applyFormatFilter(QuestUtilCards.RARE_PREDICATE);
final CardPrinted card = Aggregates.random(Iterables.filter(CardDb.instance().getAllTraditionalCards(), myFilter)); final CardPrinted card = Aggregates.random(Iterables.filter(CardDb.instance().getAllCards(), myFilter));
this.addSingleCard(card); this.addSingleCard(card);
return card; return card;
} }
@@ -220,7 +220,7 @@ public final class QuestUtilCards {
public List<CardPrinted> addRandomRare(final int n) { public List<CardPrinted> addRandomRare(final int n) {
final Predicate<CardPrinted> myFilter = applyFormatFilter(QuestUtilCards.RARE_PREDICATE); final Predicate<CardPrinted> myFilter = applyFormatFilter(QuestUtilCards.RARE_PREDICATE);
final List<CardPrinted> newCards = Aggregates.random(Iterables.filter(CardDb.instance().getAllTraditionalCards(), myFilter), n); final List<CardPrinted> newCards = Aggregates.random(Iterables.filter(CardDb.instance().getAllCards(), myFilter), n);
this.addAllCards(newCards); this.addAllCards(newCards);
return newCards; return newCards;
} }
@@ -509,9 +509,9 @@ public final class QuestUtilCards {
Iterable<CardPrinted> cardList = null; Iterable<CardPrinted> cardList = null;
if (qc.getFormat() == null) { if (qc.getFormat() == null) {
cardList = CardDb.instance().getAllTraditionalCards(); } cardList = CardDb.instance().getAllCards(); }
else { else {
cardList = Iterables.filter(CardDb.instance().getAllTraditionalCards(), cardList = Iterables.filter(CardDb.instance().getAllCards(),
qc.getFormat().getFilterPrinted()); qc.getFormat().getFilterPrinted());
} }
@@ -627,7 +627,7 @@ public final class QuestUtilCards {
public int getCompletionPercent(String edition) { public int getCompletionPercent(String edition) {
// get all cards in the specified edition // get all cards in the specified edition
Predicate<CardPrinted> filter = CardPrinted.Predicates.printedInSets(edition); Predicate<CardPrinted> filter = CardPrinted.Predicates.printedInSets(edition);
Iterable<CardPrinted> editionCards = Iterables.filter(CardDb.instance().getAllTraditionalCards(), filter); Iterable<CardPrinted> editionCards = Iterables.filter(CardDb.instance().getAllCards(), filter);
ItemPool<CardPrinted> ownedCards = qa.getCardPool(); ItemPool<CardPrinted> ownedCards = qa.getCardPool();
// 100% means at least one of every basic land and at least 4 of every other card in the set // 100% means at least one of every basic land and at least 4 of every other card in the set

View File

@@ -108,13 +108,5 @@ public abstract class PredicateString<T> implements Predicate<T> {
} }
}; };
} }
public static PredicateString<String> equalsIgnoreCase(final String what) {
return new PredicateString<String>(StringOp.EQUALS_IC) {
@Override
public boolean apply(String subject) {
return op(subject, what);
}
};
}
} }