mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 11:48:02 +00:00
lazycf, slight updates to classes - more parsing moved to appropiate class
This commit is contained in:
@@ -61,7 +61,7 @@ public final class CardDb {
|
||||
// 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();
|
||||
@@ -74,16 +74,14 @@ public final class CardDb {
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
|
||||
@@ -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,9 +332,21 @@ 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);
|
||||
public static final Predicate<CardRules> isInLatestSetUncommon = rarityInCardsLatestSet(true, CardRarity.Uncommon);
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -20,6 +26,48 @@ public final class MtgDataParser implements Iterator<CardRules> {
|
||||
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() {
|
||||
String nextLine = it.next();
|
||||
@@ -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,11 +110,54 @@ 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);
|
||||
}
|
||||
|
||||
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() { }
|
||||
|
||||
|
||||
|
||||
@@ -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,6 +22,7 @@ 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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user