UnOpenedProduct now supports limited pools (when you define that there is a single card per cube)

This commit is contained in:
Maxmtg
2013-04-27 18:09:22 +00:00
parent 66154323a3
commit 59aea5375a
10 changed files with 100 additions and 81 deletions

View File

@@ -18,9 +18,9 @@
package forge.card;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
@@ -47,7 +47,7 @@ import forge.util.TextUtil;
* @version $Id$
*/
public class BoosterGenerator {
private final static Map<String, PrintSheet> cachedSheets = new HashMap<String, PrintSheet>();
private final static Map<String, PrintSheet> cachedSheets = new TreeMap<String, PrintSheet>(String.CASE_INSENSITIVE_ORDER);
private static final synchronized PrintSheet getPrintSheet(String key) {
if( !cachedSheets.containsKey(key) )
cachedSheets.put(key, makeSheet(key, CardDb.instance().getAllCards()));
@@ -69,26 +69,8 @@ public class BoosterGenerator {
return result;
}
// If they request cards from an arbitrary pool, there's no use to cache printsheets.
public static final List<CardPrinted> getBoosterPack(SealedProductTemplate booster, Iterable<CardPrinted> sourcePool) {
if(sourcePool == CardDb.instance().getAllCards())
throw new IllegalArgumentException("Do not use this overload to obtain boosters based on complete cardDb");
if(null == sourcePool)
return getBoosterPack(booster);
List<CardPrinted> result = new ArrayList<CardPrinted>();
for(Pair<String, Integer> slot : booster.getSlots()) {
String slotType = slot.getLeft(); // add expansion symbol here?
int numCards = slot.getRight().intValue();
PrintSheet ps = makeSheet(slotType, sourcePool);
result.addAll(ps.random(numCards, true));
}
return result;
}
@SuppressWarnings("unchecked")
private static final PrintSheet makeSheet(String sheetKey, Iterable<CardPrinted> src) {
public static final PrintSheet makeSheet(String sheetKey, Iterable<CardPrinted> src) {
PrintSheet ps = new PrintSheet(sheetKey);
String[] sKey = TextUtil.splitWithParenthesis(sheetKey, ' ', '(', ')', 2);

View File

@@ -22,11 +22,8 @@ import java.io.File;
import java.util.List;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import forge.Singletons;
import forge.game.limited.CustomLimited;
import forge.item.CardDb;
import forge.item.CardPrinted;
import forge.item.IPaperCard;
import forge.util.FileUtil;
@@ -168,8 +165,7 @@ public class MetaSet {
case JoinedSet:
Predicate<CardPrinted> predicate = IPaperCard.Predicates.printedInSets(data.split(" "));
Iterable<CardPrinted> pool = Iterables.filter(CardDb.instance().getAllCards(), predicate);
return new UnOpenedProduct(BoosterTemplate.genericBooster, pool);
return new UnOpenedProduct(BoosterTemplate.genericBooster, predicate);
case Choose:
return new UnOpenedMeta(data, true);

View File

@@ -29,25 +29,20 @@ public class SealedProductTemplate {
protected final List<Pair<String, Integer>> slots;
public String getEdition() {
return null;
}
public final List<Pair<String, Integer>> getSlots() {
return slots;
}
public String getEdition() {
return null;
}
public SealedProductTemplate(Iterable<Pair<String, Integer>> itrSlots)
{
slots = Lists.newArrayList(itrSlots);
}
@SuppressWarnings("unchecked")
public SealedProductTemplate(int qty) {
this(Lists.newArrayList(Pair.of("any", qty)));
}
public int getTotal() {
public int getNumberOfCardsExpected() {
int sum = 0;
for(Pair<String, Integer> p : slots) {
sum += p.getRight().intValue();

View File

@@ -1,41 +1,83 @@
package forge.card;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import org.apache.commons.lang3.tuple.Pair;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import forge.item.CardDb;
import forge.item.CardPrinted;
import forge.item.ItemPoolView;
import forge.item.PrintSheet;
public class UnOpenedProduct implements IUnOpenedProduct {
private final ItemPoolView<CardPrinted> cards;
private final Iterable<CardPrinted> cardPoolFlat;
private final SealedProductTemplate tpl;
/**
* TODO: Write javadoc for Constructor.
*/
private final Map<String, PrintSheet> sheets;
private boolean poolLimited = false; // if true after successful generation cards are removed from printsheets.
public final boolean isPoolLimited() {
return poolLimited;
}
public final void setLimitedPool(boolean considerNumbersInPool) {
this.poolLimited = considerNumbersInPool; // TODO: Add 0 to parameter's name.
}
// Means to select from all unique cards (from base game, ie. no schemes or avatars)
public UnOpenedProduct(SealedProductTemplate template) {
tpl = template;
cards = null;
cardPoolFlat = null;
sheets = null;
}
// Invoke this constructor only if you are sure that the pool is not equal to deafult carddb
public UnOpenedProduct(SealedProductTemplate template, ItemPoolView<CardPrinted> pool) {
cards = pool;
cardPoolFlat = null;
tpl = template;
this(template, pool.toFlatList());
}
public UnOpenedProduct(SealedProductTemplate template, Iterable<CardPrinted> pool) {
cardPoolFlat = pool;
public UnOpenedProduct(SealedProductTemplate template, Iterable<CardPrinted> cards) {
tpl = template;
cards = null;
}
sheets = new TreeMap<String, PrintSheet>();
prebuildSheets(cards);
}
public UnOpenedProduct(SealedProductTemplate sealedProductTemplate, Predicate<CardPrinted> filterPrinted) {
this(sealedProductTemplate, Iterables.filter(CardDb.instance().getAllCards(), filterPrinted));
}
private void prebuildSheets(Iterable<CardPrinted> sourceList) {
for(Pair<String, Integer> cc : tpl.getSlots()) {
sheets.put(cc.getKey(), BoosterGenerator.makeSheet(cc.getKey(), sourceList));
}
}
@Override
public List<CardPrinted> get() {
return cards == null && cardPoolFlat == null ? BoosterGenerator.getBoosterPack(tpl)
: BoosterGenerator.getBoosterPack(tpl, cardPoolFlat == null ? cards.toFlatList() : cardPoolFlat);
return sheets == null ? BoosterGenerator.getBoosterPack(tpl) : getBoosterPack();
}
// If they request cards from an arbitrary pool, there's no use to cache printsheets.
private final List<CardPrinted> getBoosterPack() {
List<CardPrinted> result = new ArrayList<CardPrinted>();
for(Pair<String, Integer> slot : tpl.getSlots()) {
PrintSheet ps = sheets.get(slot.getLeft());
if(ps.isEmpty() && poolLimited ) {
throw new IllegalStateException("The cardpool has been depleted and has no more cards for slot " + slot.getKey());
}
List<CardPrinted> foundCards = ps.random(slot.getRight().intValue(), true);
if(poolLimited)
ps.removeAll(foundCards);
result.addAll(foundCards);
}
return result;
}
}

View File

@@ -36,7 +36,6 @@ import com.google.common.base.Supplier;
import forge.Card;
import forge.Constant.Preferences;
import forge.Singletons;
import forge.card.BoosterGenerator;
import forge.card.BoosterTemplate;
import forge.card.CardBlock;
import forge.card.CardEdition;
@@ -89,9 +88,7 @@ public final class BoosterDraft implements IBoosterDraft {
switch (draftType) {
case Full: // Draft from all cards in Forge
Supplier<List<CardPrinted>> s = new Supplier<List<CardPrinted>>() {
@Override public List<CardPrinted> get() { return BoosterGenerator.getBoosterPack(BoosterTemplate.genericBooster); }
};
Supplier<List<CardPrinted>> s = new UnOpenedProduct(BoosterTemplate.genericBooster);
for (int i = 0; i < 3; i++) this.product.add(s);
IBoosterDraft.LAND_SET_CODE[0] = CardDb.instance().getCard("Plains").getEdition();
@@ -167,8 +164,9 @@ public final class BoosterDraft implements IBoosterDraft {
final SealedProductTemplate tpl = draft.getSealedProductTemplate();
UnOpenedProduct toAdd = new UnOpenedProduct(tpl, dPool);
for (int i = 0; i < draft.getNumPacks(); i++) {
this.product.add(new UnOpenedProduct(tpl, dPool));
this.product.add(toAdd);
}
IBoosterDraft.LAND_SET_CODE[0] = draft.getLandSetCode();

View File

@@ -246,19 +246,17 @@ public class SealedDeckFormat {
if (element.endsWith(".sealed")) {
final List<String> dfData = FileUtil.readFile("res/sealed/" + element);
final CustomLimited cs = CustomLimited.parse(dfData, Singletons.getModel().getDecks().getCubes());
if (cs.getSealedProductTemplate().getTotal() > 5) { // Do not allow too small cubes to be played as 'stand-alone'!
if (cs.getSealedProductTemplate().getNumberOfCardsExpected() > 5) { // Do not allow too small cubes to be played as 'stand-alone'!
customs.add(cs);
}
}
}
// present list to user
if (customs.size() < 1) {
JOptionPane.showMessageDialog(null, "No custom sealed files found.", "",
JOptionPane.INFORMATION_MESSAGE);
if (customs.isEmpty()) {
JOptionPane.showMessageDialog(null, "No custom sealed files found.", "", JOptionPane.INFORMATION_MESSAGE);
} else {
final CustomLimited draft = GuiChoose.one("Choose Custom Sealed Pool",
customs);
final CustomLimited draft = GuiChoose.one("Choose Custom Sealed Pool", customs);
// Choose number of boosters
@@ -270,8 +268,9 @@ public class SealedDeckFormat {
Integer nrBoosters = GuiChoose.one("How many booster packs?", integers);
IUnOpenedProduct toAdd = new UnOpenedProduct(draft.getSealedProductTemplate(), draft.getCardPool());
for (int i = 0; i < nrBoosters; i++) {
this.product.add(new UnOpenedProduct(draft.getSealedProductTemplate(), draft.getCardPool()));
this.product.add(toAdd);
}
this.getLandSetCode()[0] = draft.getLandSetCode();

View File

@@ -71,6 +71,6 @@ public class FatPack extends OpenablePack {
@Override
public int getTotalCards() {
return super.getTotalCards() * fpData.getCntBoosters() + fpData.getTotal();
return super.getTotalCards() * fpData.getCntBoosters() + fpData.getNumberOfCardsExpected();
}
}

View File

@@ -68,7 +68,7 @@ public abstract class OpenablePack implements InventoryItemFromSet {
}
public int getTotalCards() {
return contents.getTotal();
return contents.getNumberOfCardsExpected();
}
@Override

View File

@@ -50,7 +50,14 @@ public class PrintSheet {
public void addAll(Iterable<CardPrinted> cards, int weight) {
for(CardPrinted card : cards)
cardsWithWeights.add(card, weight);
}
}
/** Cuts cards out of a sheet - they won't be printed again.
* Please use mutable sheets for cubes only.*/
public void removeAll(Iterable<CardPrinted> cards) {
for(CardPrinted card : cards)
cardsWithWeights.remove(card);
}
private CardPrinted fetchRoulette(int start, int roulette, Collection<CardPrinted> toSkip) {
int sum = start;
@@ -107,5 +114,9 @@ public class PrintSheet {
}
public boolean isEmpty() {
return cardsWithWeights.isEmpty();
}
}

View File

@@ -29,12 +29,13 @@ import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import forge.Constant;
import forge.Singletons;
import forge.card.BoosterGenerator;
import forge.card.CardEdition;
import forge.card.CardRarity;
import forge.card.FormatCollection;
import forge.card.SealedProductTemplate;
import forge.card.UnOpenedProduct;
import forge.deck.Deck;
import forge.deck.DeckSection;
import forge.item.BoosterPack;
@@ -120,11 +121,10 @@ public final class QuestUtilCards {
landCode = "M10";
}
pool.add(db.getCard("Forest", landCode), nBasic);
pool.add(db.getCard("Mountain", landCode), nBasic);
pool.add(db.getCard("Swamp", landCode), nBasic);
pool.add(db.getCard("Island", landCode), nBasic);
pool.add(db.getCard("Plains", landCode), nBasic);
for(String landName : Constant.Color.BASIC_LANDS) {
pool.add(db.getCard(landName, landCode), nBasic);
}
if (!snowLandCodes.isEmpty()) {
String snowLandCode = Aggregates.random(snowLandCodes);
@@ -517,10 +517,7 @@ public final class QuestUtilCards {
* Generate cards in shop.
*/
private void generateCardsInShop() {
Iterable<CardPrinted> cardList = null;
if (qc.getFormat() != null) {
cardList = Iterables.filter(CardDb.instance().getAllCards(), qc.getFormat().getFilterPrinted());
}
int nLevel = this.qc.getAchievements().getLevel();
@@ -537,12 +534,11 @@ public final class QuestUtilCards {
final int totalPacks = Math.min(levelPacks + winPacks, maxPacks);
@SuppressWarnings("unchecked")
SealedProductTemplate template = new SealedProductTemplate(Lists.newArrayList(
Pair.of("Common", common), Pair.of("uncommon", uncommon), Pair.of("RareMythic", rare)
));
SealedProductTemplate tpl = new SealedProductTemplate(Lists.newArrayList( Pair.of("Common", common), Pair.of("Uncommon", uncommon), Pair.of("RareMythic", rare)));
UnOpenedProduct unopened = qc.getFormat() == null ? new UnOpenedProduct( tpl ) : new UnOpenedProduct( tpl, qc.getFormat().getFilterPrinted());
for (int i = 0; i < totalPacks; i++) {
this.qa.getShopList().addAllFlat(BoosterGenerator.getBoosterPack(template, cardList));
this.qa.getShopList().addAllFlat(unopened.get());
}
this.generateBoostersInShop(totalPacks);