lazycf, slight updates to classes - more parsing moved to appropiate class

This commit is contained in:
Maxmtg
2011-08-28 15:20:43 +00:00
parent 117d10fa74
commit af5948e344
6 changed files with 152 additions and 59 deletions

View File

@@ -47,7 +47,7 @@ public final class CardDb {
this(new MtgDataParser()); // I wish cardname.txt parser was be here.
}
private CardDb(final Iterator<CardRules> parser) {
private CardDb(final Iterator<CardRules> parser) {
while (parser.hasNext()) {
addNewCard(parser.next());
}
@@ -57,33 +57,31 @@ public final class CardDb {
if (null == card) { return; }
//System.out.println(card.getName());
String cardName = card.getName();
// 1. register among oracle uniques
cards.put(cardName, card);
// 2. fill refs into two lists: one with
// 2. Save refs into two lists: one flat and other keyed with sets & name
CardPrinted lastAdded = null;
for (Entry<String, CardInSet> s : card.getSetsPrinted()) {
String set = s.getKey();
// get this set storage, if not found, create it!
// get this set storage, if not found, create it!
Map<String, CardPrinted[]> setMap = allCardsBySet.get(set);
if (null == setMap) {
setMap = new Hashtable<String, CardPrinted[]>();
allCardsBySet.put(set, setMap);
}
int count = s.getValue().getCopiesCount();
CardPrinted[] cards = new CardPrinted[count];
setMap.put(cardName, cards);
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+1);
lastAdded = CardPrinted.build(card, set, s.getValue().getRarity(), i);
allCardsFlat.add(lastAdded);
cards[i] = lastAdded;
cardCopies[i] = lastAdded;
}
}
uniqueCards.put(cardName, lastAdded);
}
@@ -113,8 +111,8 @@ public final class CardDb {
throw new NoSuchElementException(err);
}
// 3. Get the proper copy
if (artIndex > 0 && artIndex <= cards.length) { return cards[artIndex-1]; }
String err = String.format("Asked for '%s' from '%s' #%d: db didn't find that copy. Note: artIndex is 1-based", name, set, artIndex);
if (artIndex > 0 && artIndex <= cards.length) { return cards[artIndex]; }
String err = String.format("Asked for '%s' from '%s' #%d: db didn't find that copy.", name, set, artIndex);
throw new NoSuchElementException(err);
}

View File

@@ -8,38 +8,14 @@ package forge.card;
*/
public class CardInSet {
private CardRarity rarity;
private int numCopies;
private final CardRarity rarity;
private final int numCopies;
public CardInSet(final CardRarity rarity, final int cntCopies) {
this.rarity = rarity;
this.numCopies = cntCopies;
}
public static CardInSet parse(final String unparsed) {
int spaceAt = unparsed.indexOf(' ');
char rarity = unparsed.charAt(spaceAt + 1);
CardRarity rating;
switch (rarity) {
case 'L': rating = CardRarity.BasicLand; break;
case 'C': rating = CardRarity.Common; break;
case 'U': rating = CardRarity.Uncommon; break;
case 'R': rating = CardRarity.Rare; break;
case 'M': rating = CardRarity.MythicRare; break;
case 'S': rating = CardRarity.Special; break;
default: rating = CardRarity.MythicRare; break;
}
int number = 1;
int bracketAt = unparsed.indexOf('(');
if (-1 != bracketAt) {
String sN = unparsed.substring(bracketAt + 2, bracketAt + 3);
number = Integer.parseInt(sN);
}
return new CardInSet(rating, number);
}
public final int getCopiesCount() { return numCopies; }
public final CardRarity getRarity() { return rarity; }
}

View File

@@ -1,6 +1,9 @@
package forge.card;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
@@ -31,7 +34,7 @@ public final class CardRules {
private String loyalty = null;
private HashMap<String, CardInSet> setsPrinted = null;
private Map<String, CardInSet> setsPrinted = null;
// Ctor and builders are needed here
public String getName() { return name; }
@@ -54,7 +57,7 @@ public final class CardRules {
}
public CardRules(final String cardName, final CardType cardType, final String manacost,
final String ptLine, final String[] cardRules, final String[] setsData)
final String ptLine, final String[] cardRules, final Map<String, CardInSet> setsData)
{
this.name = cardName;
this.type = cardType;
@@ -73,12 +76,7 @@ public final class CardRules {
} else if (cardType.isPlaneswalker()) {
this.loyalty = ptLine;
}
this.setsPrinted = new HashMap<String, CardInSet>();
for (int iSet = 0; iSet < setsData.length; iSet++) {
String setCode = setsData[iSet].substring(0, setsData[iSet].indexOf(' '));
setsPrinted.put(setCode, CardInSet.parse(setsData[iSet]));
}
setsPrinted = setsData;
}
public boolean rulesContain(final String text) {
@@ -334,8 +332,20 @@ public final class CardRules {
public static final Predicate<CardRules> isBlack = isColor(CardColor.BLACK);
public static final Predicate<CardRules> isRed = isColor(CardColor.RED);
public static final Predicate<CardRules> isGreen = isColor(CardColor.GREEN);
public static final Predicate<CardRules> isColorless = hasCntColors((byte) 0);
public static final Predicate<CardRules> isMulticolor = hasAtLeastCntColors((byte) 2);
public static final List<Predicate<CardRules>> colors = new ArrayList<Predicate<CardRules>>();
static {
colors.add(isWhite);
colors.add(isBlue);
colors.add(isBlack);
colors.add(isRed);
colors.add(isGreen);
colors.add(isColorless);
}
// Think twice before using these, since rarity is a prop of printed card.
public static final Predicate<CardRules> isInLatestSetCommon = rarityInCardsLatestSet(true, CardRarity.Common);

View File

@@ -83,6 +83,9 @@ public final class CardType implements Comparable<CardType> {
public boolean isSorcery() { return coreType.contains(CardCoreType.Sorcery); }
public boolean isEnchantment() { return coreType.contains(CardCoreType.Enchantment); }
public boolean isBasic() { return superType.contains(CardSuperType.Basic); }
public boolean isLegendary() { return superType.contains(CardSuperType.Legendary); }
public String getTypesBeforeDash() {
ArrayList<String> types = new ArrayList<String>();
for (CardSuperType st : superType) { types.add(st.name()); }
@@ -109,5 +112,6 @@ public final class CardType implements Comparable<CardType> {
public int compareTo(final CardType o) {
return toString().compareTo(o.toString());
}
}

View File

@@ -1,10 +1,16 @@
package forge.card;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.tools.ant.taskdefs.compilers.Sj;
import forge.FileUtil;
import forge.properties.ForgeProps;
@@ -19,6 +25,48 @@ public final class MtgDataParser implements Iterator<CardRules> {
it = mtgDataLines.iterator();
skipSetList();
}
private static List<String> setsToSkipPrefixes = new ArrayList<String>();
private static List<String> unSets = new ArrayList<String>(); // take only lands from there
static {
setsToSkipPrefixes.add("VG"); // Vanguard
setsToSkipPrefixes.add("ME"); // Mtgo master's editions
setsToSkipPrefixes.add("FV"); // From the vaults
// Duel decks... or... should I keep them?
setsToSkipPrefixes.add("DVD");
setsToSkipPrefixes.add("EVT");
setsToSkipPrefixes.add("EVG");
setsToSkipPrefixes.add("GVL");
setsToSkipPrefixes.add("JVC");
setsToSkipPrefixes.add("DDG");
setsToSkipPrefixes.add("PVC");
// Archenemy - we cannot play it now anyway
setsToSkipPrefixes.add("ARC");
// Planechase - this too
setsToSkipPrefixes.add("HOP");
// Reprints
setsToSkipPrefixes.add("BRB");
setsToSkipPrefixes.add("BTD");
setsToSkipPrefixes.add("DKM");
//setsToSkipPrefixes.add("ATH"); // No need to skip it really.
// On gatherer's opinion this cards was releases twice in original set
// Promo sets - all cards have been issued in other sets
setsToSkipPrefixes.add("SDC");
setsToSkipPrefixes.add("ASTRAL");
// Premium decks
setsToSkipPrefixes.add("H09");
setsToSkipPrefixes.add("H10");
// Un-sets are weird, but lands from there are valuable
unSets.add("UNH");
unSets.add("UGL");
}
private boolean weHaveNext;
private void skipSetList() {
@@ -38,6 +86,7 @@ public final class MtgDataParser implements Iterator<CardRules> {
public CardRules next() {
if (!it.hasNext()) { weHaveNext = false; return null; }
String name = it.next();
if (!it.hasNext()) { weHaveNext = false; return null; }
String manaCost = it.next();
CardType type = null;
@@ -61,12 +110,55 @@ public final class MtgDataParser implements Iterator<CardRules> {
strs.add(nextLine);
nextLine = it.next();
}
String[] sets = strs.remove(strs.size() - 1).split(", ");
// feel free to return null after this line
String setsLine = strs.remove(strs.size() - 1);
boolean isBasicLand = type.isLand() && type.isBasic();
Map<String, CardInSet> sets = getValidEditions(setsLine, isBasicLand);
if (sets.isEmpty()) { return null; } // that was a bad card - it won't be added by invoker
return new CardRules(name, type, manaCost, ptOrLoyalty, strs.toArray(emptyArray), sets);
}
@Override public void remove() { }
private Map<String, CardInSet> getValidEditions(final String sets, final boolean isBasicLand) {
String[] setsData = sets.split(", ");
Map<String, CardInSet> result = new HashMap<String, CardInSet>();
for (int iSet = 0; iSet < setsData.length; iSet++) {
int spacePos = setsData[iSet].indexOf(' ');
String setCode = setsData[iSet].substring(0, spacePos);
boolean shouldSkip = false;
for (String s : setsToSkipPrefixes) { if (setCode.startsWith(s)) { shouldSkip = true; break; } }
for (String s : unSets) { if (setCode.startsWith(s) && !isBasicLand) { shouldSkip = true; break; } }
if (shouldSkip) { continue; }
result.put(setCode, parseCardInSet(setsData[iSet], spacePos));
}
return result;
}
public static CardInSet parseCardInSet(final String unparsed, final int spaceAt) {
char rarity = unparsed.charAt(spaceAt + 1);
CardRarity rating;
switch (rarity) {
case 'L': rating = CardRarity.BasicLand; break;
case 'C': rating = CardRarity.Common; break;
case 'U': rating = CardRarity.Uncommon; break;
case 'R': rating = CardRarity.Rare; break;
case 'M': rating = CardRarity.MythicRare; break;
case 'S': rating = CardRarity.Special; break;
default: rating = CardRarity.MythicRare; break;
}
int number = 1;
int bracketAt = unparsed.indexOf('(', spaceAt);
if (-1 != bracketAt) {
String sN = unparsed.substring(bracketAt + 2, unparsed.indexOf(')', bracketAt));
number = Integer.parseInt(sN);
}
return new CardInSet(rating, number);
}
@Override public void remove() { }
}

View File

@@ -1,7 +1,9 @@
package forge.card.cardFactory;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import net.slightlymagic.braids.util.NotImplementedError;
@@ -20,7 +22,8 @@ import forge.Player;
public class LazyCardFactory extends AbstractCardFactory {
private final CardReader cardReader;
private final List<String> cardsFailedToLoad = new ArrayList<String>();
/**
* Construct an instance, pointing it to a specific cardsfolder.
*
@@ -65,18 +68,28 @@ public class LazyCardFactory extends AbstractCardFactory {
protected Card getCard2(final String cardName, final Player owner) {
final Map<String, Card> cardNamesToCards = getMap();
Card result = null;
boolean cardExists = false;
boolean wasLoaded = cardNamesToCards.containsKey(cardName);
if (!wasLoaded) {
if (cardsFailedToLoad.contains(cardName)) {
return null; // no more System.err, exceptions of other drama - just return null.
}
if (!cardNamesToCards.containsKey(cardName)) {
final String canonicalASCIIName = CardUtil.canonicalizeCardName(cardName);
getCardReader().findCard(canonicalASCIIName);
if (cardNamesToCards.containsKey(cardName)) {
cardExists = true;
Card cardRequested = getCardReader().findCard(canonicalASCIIName);
if (null != cardRequested) {
cardNamesToCards.put(cardName, cardRequested);
wasLoaded = true;
} else {
cardsFailedToLoad.add(cardName);
System.err.println(String.format("LazyCF: Tried to read from disk card '%s' but not found it!", cardName));
return null;
}
}
if (cardExists) {
// Factory should return us a copy, ready for changes.
if (wasLoaded) {
result = super.getCard2(cardName, owner);
}