mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-16 02:38:02 +00:00
UnOpenedProduct now supports limited pools (when you define that there is a single card per cube)
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ public abstract class OpenablePack implements InventoryItemFromSet {
|
||||
}
|
||||
|
||||
public int getTotalCards() {
|
||||
return contents.getTotal();
|
||||
return contents.getNumberOfCardsExpected();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -52,6 +52,13 @@ public class PrintSheet {
|
||||
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;
|
||||
boolean isSecondRun = start > 0;
|
||||
@@ -107,5 +114,9 @@ public class PrintSheet {
|
||||
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return cardsWithWeights.isEmpty();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user