BoosterGenerator refactored - does not hold numbers of cards of each rarity to generate per run.

This commit is contained in:
Maxmtg
2012-02-25 09:43:49 +00:00
parent a44e30dbbd
commit c8fbeb0d97
16 changed files with 111 additions and 159 deletions

2
.gitattributes vendored
View File

@@ -11068,6 +11068,7 @@ src/main/java/forge/card/EditionInfo.java svneol=native#text/plain
src/main/java/forge/card/FormatCollection.java -text
src/main/java/forge/card/MtgDataParser.java -text
src/main/java/forge/card/TriggerReplacementBase.java -text
src/main/java/forge/card/UnOpenedProduct.java -text
src/main/java/forge/card/abilityfactory/AbilityFactory.java svneol=native#text/plain
src/main/java/forge/card/abilityfactory/AbilityFactoryAlterLife.java svneol=native#text/plain
src/main/java/forge/card/abilityfactory/AbilityFactoryAnimate.java svneol=native#text/plain
@@ -11521,7 +11522,6 @@ src/main/java/net/slightlymagic/braids/util/progress_monitor/BaseProgressMonitor
src/main/java/net/slightlymagic/braids/util/progress_monitor/BraidsProgressMonitor.java svneol=native#text/plain
src/main/java/net/slightlymagic/braids/util/progress_monitor/StderrProgressMonitor.java svneol=native#text/plain
src/main/java/net/slightlymagic/braids/util/progress_monitor/package-info.java svneol=native#text/plain
src/main/java/net/slightlymagic/maxmtg/Closure1.java -text
src/main/java/net/slightlymagic/maxmtg/Predicate.java -text
src/main/java/net/slightlymagic/maxmtg/PredicateString.java -text
src/main/java/net/slightlymagic/maxmtg/package-info.java svneol=native#text/plain

View File

@@ -26,6 +26,7 @@ import java.util.Map;
import java.util.Random;
import java.util.Set;
import net.slightlymagic.maxmtg.Predicate;
import org.apache.commons.lang3.StringUtils;

View File

@@ -25,7 +25,6 @@ import java.util.Map;
import java.util.Map.Entry;
import net.slightlymagic.braids.util.lambda.Lambda1;
import net.slightlymagic.maxmtg.Closure1;
import net.slightlymagic.maxmtg.Predicate;
import forge.item.CardDb;
import forge.item.CardPrinted;
@@ -41,7 +40,6 @@ import forge.util.MyRandom;
* @version $Id$
*/
public class BoosterGenerator {
private static final int BOOSTERS_TO_FIND_MYTHIC = 8;
// Function to open a booster as it is.
@@ -49,51 +47,37 @@ public class BoosterGenerator {
public static final Lambda1<List<CardPrinted>, BoosterGenerator> IDENTITY_PICK = new Lambda1<List<CardPrinted>, BoosterGenerator>() {
@Override
public List<CardPrinted> apply(final BoosterGenerator arg1) {
return arg1.getBoosterPack();
return arg1.getBoosterPack(10, 3, 1, 0, 0, 0, 0, 0, 1);
}
};
// Closure which will hold both the booster and the way we want to pick from
// it - holds default options
/**
* Gets the simple picker.
*
* @param source
* the source
* @return the simple picker
*/
public static Closure1<List<CardPrinted>, BoosterGenerator> getSimplePicker(final BoosterGenerator source) {
return new Closure1<List<CardPrinted>, BoosterGenerator>(BoosterGenerator.IDENTITY_PICK, source);
}
// These lists are to hold cards grouped by rarity in advance.
private final List<CardPrinted> allButLands = new ArrayList<CardPrinted>();
private final Map<CardRarity, List<CardPrinted>> cardsByRarity = new EnumMap<CardRarity, List<CardPrinted>>(CardRarity.class);
private final Map<CardRarity, List<CardPrinted>> twoFacedByRarity = new EnumMap<CardRarity, List<CardPrinted>>(CardRarity.class);
private final Map<CardRarity, List<CardPrinted>> singleFacedByRarity = new EnumMap<CardRarity, List<CardPrinted>>(CardRarity.class);
// private List<CardPrinted> commonCreatures;
// private List<CardPrinted> commonNonCreatures;
private static final List<CardPrinted> EMPTY_LIST = Collections.unmodifiableList(new ArrayList<CardPrinted>(0));
// Modern boosters contain 10 commons, 3 uncommmons, 1 rare/mythic
// They also contain 1 land and 1 token/rules, but we don't pick them now.
private int numCommons = 10;
private int numUncommons = 3;
private int numRareSlots = 1;
private int numDoubleFaced = 0;
private int numSpecials = 0;
private BoosterGenerator() {
for (CardRarity v : CardRarity.values()) {
cardsByRarity.put(v, new ArrayList<CardPrinted>());
twoFacedByRarity.put(v, new ArrayList<CardPrinted>());
singleFacedByRarity.put(v, new ArrayList<CardPrinted>());
}
}
private void MergeAllFacedCards() {
for (CardRarity v : CardRarity.values()) {
List<CardPrinted> cp = new ArrayList<CardPrinted>(singleFacedByRarity.get(v));
cp.addAll(twoFacedByRarity.get(v));
cardsByRarity.put(v, cp);
}
}
/**
* <p>
@@ -108,6 +92,7 @@ public class BoosterGenerator {
for (final CardPrinted c : cards) {
this.addToRarity(c);
}
MergeAllFacedCards();
}
/**
@@ -121,6 +106,7 @@ public class BoosterGenerator {
for (final Entry<CardPrinted, Integer> e : dPool) {
this.addToRarity(e.getKey());
}
MergeAllFacedCards();
}
/**
@@ -131,22 +117,14 @@ public class BoosterGenerator {
* @param cardSet
* the card set
*/
public BoosterGenerator(BoosterData booster) {
public BoosterGenerator(Predicate<CardPrinted> filter) {
this();
this.numCommons = booster.getCommon();
this.numUncommons = booster.getUncommon();
this.numRareSlots = booster.getRare();
this.numSpecials = booster.getSpecial();
this.numDoubleFaced = booster.getDoubleFaced();
final Predicate<CardPrinted> filter = booster.getEditionFilter();
final List<CardPrinted> cardsInThisSet = filter.select(CardDb.instance().getAllCards());
for (final CardPrinted c : cardsInThisSet) {
for (final CardPrinted c : filter.select(CardDb.instance().getAllCards())) {
this.addToRarity(c);
// System.out.println(c);
}
MergeAllFacedCards();
// System.out.println("done");
}
@@ -213,16 +191,6 @@ public class BoosterGenerator {
return result;
}
/**
* Gets the booster pack.
*
* @return the booster pack
*/
public final List<CardPrinted> getBoosterPack() {
return this.getBoosterPack(this.numCommons, this.numUncommons, this.numRareSlots, 0, 0, this.numSpecials,
this.numDoubleFaced, 0, 0);
}
/**
* Gets the singleton booster pack.
*
@@ -231,11 +199,17 @@ public class BoosterGenerator {
* @return the singleton booster pack
*/
public final List<CardPrinted> getSingletonBoosterPack(final int nAnyCard) {
final List<CardPrinted> temp = new ArrayList<CardPrinted>();
return this.pickRandomCards(this.allButLands, nAnyCard, true);
}
temp.addAll(this.pickRandomCards(this.allButLands, nAnyCard, true));
return temp;
/**
* Gets the booster pack.
*
* @return the booster pack
*/
public final List<CardPrinted> getBoosterPack(BoosterData booster) {
return this.getBoosterPack(booster.getCommon(), booster.getUncommon(), booster.getRare(), 0, 0, booster.getSpecial(),
booster.getDoubleFaced(), 0, 0);
}
/**
@@ -283,17 +257,18 @@ public class BoosterGenerator {
final int nLands) {
final List<CardPrinted> temp = new ArrayList<CardPrinted>();
final Map<CardRarity, List<CardPrinted>> commonCardsMap = nDoubls != 0 ? singleFacedByRarity : cardsByRarity;
temp.addAll(this.pickRandomCards(cardsByRarity.get(CardRarity.Common), nCom));
temp.addAll(this.pickRandomCards(cardsByRarity.get(CardRarity.Uncommon), nUnc));
temp.addAll(this.pickRandomCards(commonCardsMap.get(CardRarity.Common), nCom));
temp.addAll(this.pickRandomCards(commonCardsMap.get(CardRarity.Uncommon), nUnc));
if (nRareSlots > 0) {
temp.addAll(this.pickRandomRaresOrMythics(cardsByRarity.get(CardRarity.Rare),
temp.addAll(this.pickRandomRaresOrMythics(commonCardsMap.get(CardRarity.Rare),
cardsByRarity.get(CardRarity.MythicRare), nRareSlots));
}
if ((nRares > 0) || (nMythics > 0)) {
temp.addAll(this.pickRandomCards(cardsByRarity.get(CardRarity.Rare), nRares));
temp.addAll(this.pickRandomCards(cardsByRarity.get(CardRarity.MythicRare), nMythics));
temp.addAll(this.pickRandomCards(commonCardsMap.get(CardRarity.Rare), nRares));
temp.addAll(this.pickRandomCards(commonCardsMap.get(CardRarity.MythicRare), nMythics));
}
if (nDoubls > 0) {
final int dblFacedRarity = MyRandom.getRandom().nextInt(nCom + nUnc + nRareSlots);
@@ -309,11 +284,9 @@ public class BoosterGenerator {
temp.addAll(this.pickRandomCards(twoFacedByRarity.get(rarityInSlot), nDoubls));
}
temp.addAll(this.pickRandomCards(cardsByRarity.get(CardRarity.Special), nSpecs));
temp.addAll(this.pickRandomCards(commonCardsMap.get(CardRarity.Special), nSpecs));
temp.addAll(this.pickRandomCards(this.allButLands, nAnyCard));
temp.addAll(this.pickRandomCards(cardsByRarity.get(CardRarity.BasicLand), nLands));
temp.addAll(this.pickRandomCards(commonCardsMap.get(CardRarity.BasicLand), nLands));
return temp;
}
@@ -323,12 +296,8 @@ public class BoosterGenerator {
return;
}
CardRarity rarity = c.getRarity();
if (c.getCard().isDoubleFaced() && (this.numDoubleFaced > 0)) {
twoFacedByRarity.get(rarity).add(c);
} else {
cardsByRarity.get(rarity).add(c);
}
Map<CardRarity, List<CardPrinted>> targetList = c.getCard().isDoubleFaced() ? twoFacedByRarity : singleFacedByRarity;
targetList.get(c.getRarity()).add(c);
if (!c.getCard().getType().isBasicLand()) {
this.allButLands.add(c);

View File

@@ -23,13 +23,15 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import net.slightlymagic.maxmtg.Predicate;
import net.slightlymagic.maxmtg.PredicateString;
import net.slightlymagic.maxmtg.Predicate.ComparableOp;
import net.slightlymagic.maxmtg.Predicate.PredicatesOp;
import net.slightlymagic.maxmtg.PredicateString;
import org.apache.commons.lang3.StringUtils;
/**
* <p>
* CardOracle class.

View File

@@ -0,0 +1,38 @@
package forge.card;
import java.util.List;
import net.slightlymagic.braids.util.lambda.Lambda1;
import forge.item.CardPrinted;
/**
* TODO: Write javadoc for this type.
*
*/
public class UnOpenedProduct {
private final Lambda1<List<CardPrinted>, BoosterGenerator> openBooster;
private final BoosterGenerator generator;
private final BoosterData booster;
public UnOpenedProduct(Lambda1<List<CardPrinted>, BoosterGenerator> identityPick, BoosterGenerator bpFull) {
openBooster = identityPick;
generator = bpFull;
booster = null;
}
/**
* TODO: Write javadoc for Constructor.
* @param boosterData
*/
public UnOpenedProduct(BoosterData boosterData) {
booster = boosterData;
openBooster = null;
generator = new BoosterGenerator(boosterData.getEditionFilter());
}
public List<CardPrinted> open() {
return openBooster != null ? openBooster.apply(generator) : generator.getBoosterPack(booster);
}
}

View File

@@ -30,15 +30,15 @@ import javax.swing.JOptionPane;
import net.slightlymagic.braids.util.UtilFunctions;
import net.slightlymagic.braids.util.lambda.Lambda1;
import net.slightlymagic.maxmtg.Closure1;
import forge.Card;
import forge.CardList;
import forge.Constant;
import forge.Singletons;
import forge.card.BoosterData;
import forge.card.BoosterGenerator;
import forge.card.CardBlock;
import forge.card.CardEdition;
import forge.card.UnOpenedProduct;
import forge.deck.Deck;
import forge.gui.GuiUtils;
import forge.item.CardDb;
@@ -68,7 +68,7 @@ public final class BoosterDraft implements IBoosterDraft {
private final Map<String, Float> draftPicks = new TreeMap<String, Float>();
private final CardPoolLimitation draftFormat;
private final ArrayList<Closure1<List<CardPrinted>, BoosterGenerator>> packs = new ArrayList<Closure1<List<CardPrinted>, BoosterGenerator>>();
private final ArrayList<UnOpenedProduct> product = new ArrayList<UnOpenedProduct>();
/**
* <p>
@@ -85,9 +85,8 @@ public final class BoosterDraft implements IBoosterDraft {
switch (draftType) {
case Full: // Draft from all cards in Forge
final BoosterGenerator bpFull = new BoosterGenerator(CardDb.instance().getAllUniqueCards());
final Closure1<List<CardPrinted>, BoosterGenerator> picker = BoosterGenerator.getSimplePicker(bpFull);
for (int i = 0; i < 3; i++) {
this.packs.add(picker);
this.product.add(new UnOpenedProduct(BoosterGenerator.IDENTITY_PICK, bpFull));
}
IBoosterDraft.LAND_SET_CODE[0] = CardDb.instance().getCard("Plains").getEdition();
@@ -124,15 +123,13 @@ public final class BoosterDraft implements IBoosterDraft {
final Object p = GuiUtils.getChoice("Choose Set Combination", setCombos.toArray());
final String[] pp = p.toString().split("/");
for (int i = 0; i < nPacks; i++) {
final BoosterGenerator bpMulti = new BoosterGenerator(Singletons.getModel().getBoosters().get(pp[i]));
this.packs.add(BoosterGenerator.getSimplePicker(bpMulti));
this.product.add(new UnOpenedProduct(Singletons.getModel().getBoosters().get(pp[i])));
}
} else {
final BoosterGenerator bpOne = new BoosterGenerator(Singletons.getModel().getBoosters().get(sets[0]));
final Closure1<List<CardPrinted>, BoosterGenerator> pick1 = BoosterGenerator.getSimplePicker(bpOne);
final UnOpenedProduct product1 = new UnOpenedProduct(Singletons.getModel().getBoosters().get(sets[0]));
for (int i = 0; i < nPacks; i++) {
this.packs.add(pick1);
this.product.add(product1);
}
}
@@ -179,10 +176,8 @@ public final class BoosterDraft implements IBoosterDraft {
}
};
final Closure1<List<CardPrinted>, BoosterGenerator> picker = new Closure1<List<CardPrinted>, BoosterGenerator>(
fnPick, bpCustom);
for (int i = 0; i < draft.getNumPacks(); i++) {
this.packs.add(picker);
this.product.add(new UnOpenedProduct(fnPick, bpCustom));
}
IBoosterDraft.LAND_SET_CODE[0] = draft.getLandSetCode();
@@ -239,13 +234,13 @@ public final class BoosterDraft implements IBoosterDraft {
* @return an array of {@link forge.CardList} objects.
*/
public List<List<CardPrinted>> get8BoosterPack() {
if (this.nextBoosterGroup >= this.packs.size()) {
if (this.nextBoosterGroup >= this.product.size()) {
return null;
}
final List<List<CardPrinted>> list = new ArrayList<List<CardPrinted>>();
for (int i = 0; i < 8; i++) {
list.add(this.packs.get(this.nextBoosterGroup).apply());
list.add(this.product.get(this.nextBoosterGroup).open());
}
this.nextBoosterGroup++;
@@ -307,7 +302,7 @@ public final class BoosterDraft implements IBoosterDraft {
*/
@Override
public boolean hasNextChoice() {
final boolean isLastGroup = this.nextBoosterGroup >= this.packs.size();
final boolean isLastGroup = this.nextBoosterGroup >= this.product.size();
final boolean isBoosterDepleted = this.currentBoosterPick >= this.currentBoosterSize;
final boolean noMoreCards = isLastGroup && isBoosterDepleted;
return !noMoreCards;

View File

@@ -25,7 +25,6 @@ import javax.swing.JOptionPane;
import net.slightlymagic.braids.util.UtilFunctions;
import net.slightlymagic.braids.util.lambda.Lambda1;
import net.slightlymagic.maxmtg.Closure1;
import forge.AllZone;
import forge.Card;
import forge.CardList;
@@ -33,9 +32,11 @@ import forge.CardListFilter;
import forge.CardListUtil;
import forge.Constant;
import forge.Singletons;
import forge.card.BoosterData;
import forge.card.BoosterGenerator;
import forge.card.CardBlock;
import forge.card.CardEdition;
import forge.card.UnOpenedProduct;
import forge.card.spellability.AbilityMana;
import forge.deck.Deck;
import forge.gui.GuiUtils;
@@ -55,7 +56,7 @@ import forge.util.MyRandom;
* @since 1.0.15
*/
public class SealedDeck {
private final List<Closure1<List<CardPrinted>, BoosterGenerator>> packs = new ArrayList<Closure1<List<CardPrinted>, BoosterGenerator>>();
private final ArrayList<UnOpenedProduct> product = new ArrayList<UnOpenedProduct>();
/** The Land set code. */
private String[] landSetCode = { "" };
@@ -72,9 +73,8 @@ public class SealedDeck {
if (sealedType.equals("Full")) {
final BoosterGenerator bpFull = new BoosterGenerator(CardDb.instance().getAllUniqueCards());
final Closure1<List<CardPrinted>, BoosterGenerator> picker = BoosterGenerator.getSimplePicker(bpFull);
for (int i = 0; i < 6; i++) {
this.packs.add(picker);
this.product.add(new UnOpenedProduct(BoosterGenerator.IDENTITY_PICK, bpFull));
}
this.getLandSetCode()[0] = CardDb.instance().getCard("Plains").getEdition();
@@ -107,14 +107,12 @@ public class SealedDeck {
final String[] pp = p.toString().split("/");
for (int i = 0; i < nPacks; i++) {
final BoosterGenerator bpMulti = new BoosterGenerator(Singletons.getModel().getBoosters().get(pp[i]));
this.packs.add(BoosterGenerator.getSimplePicker(bpMulti));
this.product.add(new UnOpenedProduct(Singletons.getModel().getBoosters().get(pp[i])));
}
} else {
final BoosterGenerator bpOne = new BoosterGenerator(Singletons.getModel().getBoosters().get(sets[0]));
final Closure1<List<CardPrinted>, BoosterGenerator> picker = BoosterGenerator.getSimplePicker(bpOne);
final UnOpenedProduct product1 = new UnOpenedProduct(Singletons.getModel().getBoosters().get(sets[0]));
for (int i = 0; i < nPacks; i++) {
this.packs.add(picker);
this.product.add(product1);
}
}
@@ -168,11 +166,8 @@ public class SealedDeck {
}
};
final Closure1<List<CardPrinted>, BoosterGenerator> picker = new Closure1<List<CardPrinted>, BoosterGenerator>(
fnPick, bpCustom);
for (int i = 0; i < draft.getNumPacks(); i++) {
this.packs.add(picker);
this.product.add(new UnOpenedProduct(fnPick, bpCustom));
}
this.getLandSetCode()[0] = draft.getLandSetCode();
@@ -190,8 +185,8 @@ public class SealedDeck {
public ItemPool<CardPrinted> getCardpool() {
final ItemPool<CardPrinted> pool = new ItemPool<CardPrinted>(CardPrinted.class);
for (int i = 0; i < this.packs.size(); i++) {
pool.addAllFlat(this.packs.get(i).apply());
for (int i = 0; i < this.product.size(); i++) {
pool.addAllFlat(this.product.get(i).open());
}
return pool;

View File

@@ -27,6 +27,7 @@ import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import net.slightlymagic.maxmtg.Predicate;
import forge.Command;
import forge.gui.deckeditor.elements.CardPanelBase;
import forge.gui.deckeditor.elements.DeckAnalysis;

View File

@@ -37,6 +37,7 @@ import javax.swing.JTable;
import javax.swing.WindowConstants;
import net.slightlymagic.maxmtg.Predicate;
import forge.Command;
import forge.Constant;
import forge.Singletons;

View File

@@ -24,6 +24,7 @@ import java.util.List;
import javax.swing.JCheckBox;
import net.slightlymagic.maxmtg.Predicate;
import forge.card.CardRules;
import forge.item.CardPrinted;

View File

@@ -31,6 +31,7 @@ import javax.swing.event.TableModelListener;
import javax.swing.table.TableCellRenderer;
import net.slightlymagic.maxmtg.Predicate;
import forge.Constant;
import forge.card.CardRules;
import forge.item.InventoryItem;

View File

@@ -134,8 +134,8 @@ public class BoosterPack implements InventoryItemFromSet {
}
private void generate() {
final BoosterGenerator gen = new BoosterGenerator(this.contents);
this.cards = gen.getBoosterPack();
final BoosterGenerator gen = new BoosterGenerator(this.contents.getEditionFilter());
this.cards = gen.getBoosterPack(this.contents);
final int cntLands = this.contents.getLand();
if (cntLands > 0) {

View File

@@ -22,6 +22,7 @@ import java.util.Collections;
import java.util.List;
import net.slightlymagic.maxmtg.Predicate;
import forge.card.CardRules;
import forge.item.CardDb;
import forge.item.CardPrinted;

View File

@@ -22,6 +22,7 @@ import java.util.HashMap;
import java.util.List;
import net.slightlymagic.maxmtg.Predicate;
import forge.Singletons;
import forge.deck.Deck;
import forge.item.CardPrinted;

View File

@@ -1,56 +0,0 @@
/*
* Forge: Play Magic: the Gathering.
* Copyright (C) 2011 MaxMtg
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package net.slightlymagic.maxmtg;
import net.slightlymagic.braids.util.lambda.Lambda1;
/**
* This class represents an action (lambda) and some arguments to make a call at
* a later time.
*
* @param <R>
* the generic type
* @param <A1>
* the generic type
*/
public class Closure1<R, A1> {
private final Lambda1<R, A1> method;
private final A1 argument;
/**
* Instantiates a new closure1.
*
* @param lambda
* the lambda
* @param object
* the object
*/
public Closure1(final Lambda1<R, A1> lambda, final A1 object) {
this.method = lambda;
this.argument = object;
}
/**
* Apply.
*
* @return the r
*/
public R apply() {
return this.method.apply(this.argument);
}
}

View File

@@ -2,6 +2,7 @@ package forge;
import org.testng.annotations.Test;
import forge.card.BoosterData;
import forge.card.BoosterGenerator;
import forge.deck.Deck;
import forge.game.limited.IBoosterDraft;
@@ -46,8 +47,9 @@ public class BoosterDraftTest implements IBoosterDraft {
@Override
public ItemPoolView<CardPrinted> nextChoice() {
this.n--;
final BoosterGenerator pack = new BoosterGenerator(Singletons.getModel().getBoosters().get("M11"));
return ItemPool.createFrom(pack.getBoosterPack(), CardPrinted.class);
BoosterData booster = Singletons.getModel().getBoosters().get("M11");
final BoosterGenerator pack = new BoosterGenerator(booster.getEditionFilter());
return ItemPool.createFrom(pack.getBoosterPack(booster), CardPrinted.class);
}
/** {@inheritDoc} */