Support canceling when selecting block or custom draft format when setting up a new draft or sealed deck

Prevent crash if you select a block that has no sets
This commit is contained in:
drdev
2014-02-07 05:20:08 +00:00
parent 1422748447
commit b34ca7b951
6 changed files with 139 additions and 99 deletions

View File

@@ -150,11 +150,14 @@ public enum CSubmenuDraft implements ICDoc {
final LimitedPoolType poolType = GuiChoose.oneOrNone("Choose Draft Format", LimitedPoolType.values());
if (poolType == null) { return; }
final CEditorDraftingProcess draft = new CEditorDraftingProcess();
draft.showGui(new BoosterDraft(poolType));
BoosterDraft draft = BoosterDraft.createDraft(poolType);
if (draft == null) { return; }
final CEditorDraftingProcess draftController = new CEditorDraftingProcess();
draftController.showGui(draft);
Singletons.getControl().setCurrentScreen(FScreen.DRAFTING_PROCESS);
CDeckEditorUI.SINGLETON_INSTANCE.setEditorController(draft);
CDeckEditorUI.SINGLETON_INSTANCE.setEditorController(draftController);
}
/* (non-Javadoc)

View File

@@ -16,6 +16,7 @@ import org.apache.commons.lang3.StringUtils;
import forge.Command;
import forge.Singletons;
import forge.card.MagicColor;
import forge.deck.CardPool;
import forge.deck.Deck;
import forge.deck.DeckBase;
import forge.deck.DeckGroup;
@@ -36,7 +37,6 @@ import forge.limited.ReadDraftRankings;
import forge.limited.SealedCardPoolGenerator;
import forge.limited.SealedDeckBuilder;
import forge.properties.ForgePreferences.FPref;
import forge.util.ItemPool;
import forge.util.MyRandom;
import forge.util.storage.IStorage;
@@ -151,7 +151,8 @@ public enum CSubmenuSealed implements ICDoc {
SealedCardPoolGenerator sd = new SealedCardPoolGenerator(poolType);
if (sd.isEmpty()) { return; }
final ItemPool<PaperCard> humanPool = sd.getCardpool(true);
final CardPool humanPool = sd.getCardPool(true);
if (humanPool == null) { return; }
// System.out.println(humanPool);
@@ -208,7 +209,10 @@ public enum CSubmenuSealed implements ICDoc {
sealed.setHumanDeck(deck);
for (int i = 0; i < rounds; i++) {
// Generate other decks for next N opponents
sealed.addAiDeck(new SealedDeckBuilder(sd.getCardpool(false).toFlatList()).buildDeck());
final CardPool aiPool = sd.getCardPool(false);
if (aiPool == null) { return; }
sealed.addAiDeck(new SealedDeckBuilder(aiPool.toFlatList()).buildDeck());
}
// Rank the AI decks

View File

@@ -71,6 +71,95 @@ public final class BoosterDraft implements IBoosterDraft {
private final List<Supplier<List<PaperCard>>> product = new ArrayList<Supplier<List<PaperCard>>>();
public static BoosterDraft createDraft(final LimitedPoolType draftType) {
BoosterDraft draft = new BoosterDraft(draftType);
switch (draftType) {
case Full: // Draft from all cards in Forge
Supplier<List<PaperCard>> s = new UnOpenedProduct(SealedProduct.Template.genericBooster);
for (int i = 0; i < 3; i++) {
draft.product.add(s);
}
IBoosterDraft.LAND_SET_CODE[0] = CardEdition.Predicates.getRandomSetWithAllBasicLands(Singletons.getMagicDb().getEditions());
break;
case Block: // Draft from cards by block or set
case FantasyBlock:
List<CardBlock> blocks = new ArrayList<CardBlock>();
IStorage<CardBlock> storage = draftType == LimitedPoolType.Block
? Singletons.getModel().getBlocks() : Singletons.getModel().getFantasyBlocks();
for (CardBlock b : storage) {
if (b.getCntBoostersDraft() > 0) {
blocks.add(b);
}
}
final CardBlock block = GuiChoose.oneOrNone("Choose Block", blocks);
if (block == null) { return null; }
final CardEdition[] cardSets = block.getSets();
if (cardSets.length == 0) {
FOptionPane.showErrorDialog(block.toString() + " does not contain any set combinations.");
return null;
}
final Stack<String> sets = new Stack<String>();
for (int k = cardSets.length - 1; k >= 0; k--) {
sets.add(cardSets[k].getCode());
}
for (String setCode : block.getMetaSetNames()) {
if (block.getMetaSet(setCode).isDraftable()) {
sets.push(setCode); // to the beginning
}
}
final int nPacks = block.getCntBoostersDraft();
if (sets.size() > 1) {
final Object p = GuiChoose.oneOrNone("Choose Set Combination", getSetCombos(sets));
if (p == null) { return null; }
final String[] pp = p.toString().split("/");
for (int i = 0; i < nPacks; i++) {
draft.product.add(block.getBooster(pp[i]));
}
}
else {
IUnOpenedProduct product1 = block.getBooster(sets.get(0));
for (int i = 0; i < nPacks; i++) {
draft.product.add(product1);
}
}
IBoosterDraft.LAND_SET_CODE[0] = block.getLandSet();
break;
case Custom:
final List<CustomLimited> myDrafts = draft.loadCustomDrafts("res/draft/", ".draft");
if (myDrafts.isEmpty()) {
FOptionPane.showMessageDialog("No custom draft files found.");
}
else {
final CustomLimited customDraft = GuiChoose.oneOrNone("Choose Custom Draft", myDrafts);
if (customDraft == null) { return null; }
draft.setupCustomDraft(customDraft);
}
break;
default:
throw new NoSuchElementException("Draft for mode " + draftType + " has not been set up!");
}
draft.pack = draft.get8BoosterPack();
return draft;
}
/**
* <p>
* Constructor for BoosterDraft_1.
@@ -79,77 +168,9 @@ public final class BoosterDraft implements IBoosterDraft {
* @param draftType
* a {@link java.lang.String} object.
*/
public BoosterDraft(final LimitedPoolType draftType) {
private BoosterDraft(final LimitedPoolType draftType) {
this.draftAI.setBd(this);
this.draftFormat = draftType;
switch (draftType) {
case Full: // Draft from all cards in Forge
Supplier<List<PaperCard>> s = new UnOpenedProduct(SealedProduct.Template.genericBooster);
for (int i = 0; i < 3; i++) this.product.add(s);
IBoosterDraft.LAND_SET_CODE[0] = CardEdition.Predicates.getRandomSetWithAllBasicLands(Singletons.getMagicDb().getEditions());
break;
case Block: case FantasyBlock: // Draft from cards by block or set
List<CardBlock> blocks = new ArrayList<CardBlock>();
IStorage<CardBlock> storage = draftType == LimitedPoolType.Block
? Singletons.getModel().getBlocks() : Singletons.getModel().getFantasyBlocks();
for (CardBlock b : storage) {
if( b.getCntBoostersDraft() > 0)
blocks.add(b);
}
final CardBlock block = GuiChoose.one("Choose Block", blocks);
final CardEdition[] cardSets = block.getSets();
final Stack<String> sets = new Stack<String>();
for (int k = cardSets.length - 1; k >= 0; --k) {
sets.add(cardSets[k].getCode());
}
for(String setCode : block.getMetaSetNames() ) {
if ( block.getMetaSet(setCode).isDraftable() )
sets.push(setCode); // to the beginning
}
final int nPacks = block.getCntBoostersDraft();
if (sets.size() > 1) {
final Object p = GuiChoose.one("Choose Set Combination", getSetCombos(sets));
final String[] pp = p.toString().split("/");
for (int i = 0; i < nPacks; i++) {
this.product.add(block.getBooster(pp[i]));
}
} else {
IUnOpenedProduct product1 = block.getBooster(sets.get(0));
for (int i = 0; i < nPacks; i++) {
this.product.add(product1);
}
}
IBoosterDraft.LAND_SET_CODE[0] = block.getLandSet();
break;
case Custom:
final List<CustomLimited> myDrafts = this.loadCustomDrafts("res/draft/", ".draft");
if (myDrafts.isEmpty()) {
FOptionPane.showMessageDialog("No custom draft files found.");
}
else {
final CustomLimited draft = GuiChoose.one("Choose Custom Draft", myDrafts);
this.setupCustomDraft(draft);
}
break;
default:
throw new NoSuchElementException("Draft for mode " + draftType + " has not been set up!");
}
this.pack = this.get8BoosterPack();
}
private void setupCustomDraft(final CustomLimited draft) {
@@ -252,11 +273,9 @@ public final class BoosterDraft implements IBoosterDraft {
}
private void computerChoose() {
final int iHumansBooster = this.getCurrentBoosterIndex();
int iPlayer = 0;
for (int i = 1; i < this.pack.size(); i++) {
final List<Card> forAi = new ArrayList<Card>();
final List<PaperCard> booster = this.pack.get((iHumansBooster + i) % this.pack.size());
for (final IPaperCard cr : booster) {
@@ -311,13 +330,15 @@ public final class BoosterDraft implements IBoosterDraft {
if (cc.equals(c)) {
pickValue = thisBooster.size()
* (1f - (((float) this.currentBoosterPick / this.currentBoosterSize) * 2f));
} else {
}
else {
pickValue = 0;
}
if (!this.draftPicks.containsKey(cnBk)) {
this.draftPicks.put(cnBk, pickValue);
} else {
}
else {
final float curValue = this.draftPicks.get(cnBk);
final float newValue = (curValue + pickValue) / 2;
this.draftPicks.put(cnBk, newValue);
@@ -335,7 +356,7 @@ public final class BoosterDraft implements IBoosterDraft {
if (!Preferences.UPLOAD_DRAFT || 1 >= draftPicks.size()) {
return;
}
ArrayList<String> outDraftData = new ArrayList<String>();
for (Entry<String, Float> key : draftPicks.entrySet()) {
outDraftData.add(key.getValue() + "|" + key.getKey());
@@ -344,7 +365,7 @@ public final class BoosterDraft implements IBoosterDraft {
HttpUtil.upload(NewConstants.URL_DRAFT_UPLOAD + "?fmt=" + draftFormat, outDraftData);
}
private List<String> getSetCombos(final List<String> setz) {
private static List<String> getSetCombos(final List<String> setz) {
String[] sets = setz.toArray(ArrayUtils.EMPTY_STRING_ARRAY);
List<String> setCombos = new ArrayList<String>();
if (sets.length >= 2) {

View File

@@ -36,7 +36,6 @@ import forge.item.SealedProduct;
import forge.model.CardBlock;
import forge.model.UnOpenedMeta;
import forge.util.FileUtil;
import forge.util.ItemPool;
import forge.util.TextUtil;
/**
@@ -155,7 +154,8 @@ public class SealedCardPoolGenerator {
return;
}
final CustomLimited draft = GuiChoose.one("Choose Custom Sealed Pool", customs);
final CustomLimited draft = GuiChoose.oneOrNone("Choose Custom Sealed Pool", customs);
if (draft == null) { return; }
UnOpenedProduct toAdd = new UnOpenedProduct(draft.getSealedProductTemplate(), draft.getCardPool());
toAdd.setLimitedPool(draft.isSingleton());
@@ -185,7 +185,7 @@ public class SealedCardPoolGenerator {
*
* @return an ArrayList of the set choices.
*/
private ArrayList<String> getSetCombos(final List<String> setz, final int nPacks) {
private static ArrayList<String> getSetCombos(final List<String> setz, final int nPacks) {
String[] sets = setz.toArray(ArrayUtils.EMPTY_STRING_ARRAY);
ArrayList<String> setCombos = new ArrayList<String>();
@@ -335,12 +335,16 @@ public class SealedCardPoolGenerator {
* boolean, get pool for human (possible choices)
* @return a {@link forge.CardList} object.
*/
public ItemPool<PaperCard> getCardpool(final boolean isHuman) {
public CardPool getCardPool(final boolean isHuman) {
final CardPool pool = new CardPool();
for (IUnOpenedProduct prod : product) {
if (prod instanceof UnOpenedMeta) {
pool.addAllFlat(((UnOpenedMeta) prod).open(isHuman));
List<PaperCard> cards = ((UnOpenedMeta) prod).open(isHuman, true);
if (cards == null) {
return null; //return null if user canceled
}
pool.addAllFlat(cards);
}
else {
pool.addAllFlat(prod.get());

View File

@@ -40,7 +40,7 @@ public class UnOpenedMeta implements IUnOpenedProduct {
ChooseOne,
SelectAll,
}
private final ArrayList<MetaSet> metaSets;
private final JoinOperation operation;
private final Random generator = MyRandom.getRandom();
@@ -56,19 +56,18 @@ public class UnOpenedMeta implements IUnOpenedProduct {
metaSets = new ArrayList<MetaSet>();
operation = op;
for(String m : TextUtil.splitWithParenthesis(creationString, ';')) {
for (String m : TextUtil.splitWithParenthesis(creationString, ';')) {
metaSets.add(new MetaSet(m, true));
}
}
/**
* Open the booster pack, return contents.
* @return List, list of cards.
*/
@Override
public List<PaperCard> get() {
return this.open(true);
return this.open(true, false);
}
/**
@@ -79,24 +78,32 @@ public class UnOpenedMeta implements IUnOpenedProduct {
* known partialities for the AI.
* @return List, list of cards.
*/
public List<PaperCard> open(final boolean isHuman) {
public List<PaperCard> open(final boolean isHuman, final boolean allowCancel) {
if (metaSets.isEmpty()) {
throw new RuntimeException("Empty UnOpenedMetaset, cannot generate booster.");
}
switch(operation) {
switch (operation) {
case ChooseOne:
if (isHuman) {
final MetaSet ms = GuiChoose.one("Choose booster:", metaSets);
final MetaSet ms;
if (allowCancel) {
ms = GuiChoose.oneOrNone("Choose Booster", metaSets);
if (ms == null) {
return null;
}
}
else {
ms = GuiChoose.one("Choose Booster", metaSets);
}
return ms.getBooster().get();
}
case RandomOne: // AI should fall though here from the case above
int selected = generator.nextInt(metaSets.size());
final IUnOpenedProduct newBooster = metaSets.get(selected).getBooster();
return newBooster.get();
case SelectAll:
List<PaperCard> allCards = new ArrayList<PaperCard>();
for (MetaSet ms : metaSets) {
@@ -106,7 +113,7 @@ public class UnOpenedMeta implements IUnOpenedProduct {
}
throw new IllegalStateException("Got wrong operation type in unopenedMeta - execution should never reach this point");
}
public static UnOpenedMeta choose(String desc) {
return new UnOpenedMeta(desc, JoinOperation.ChooseOne);
}
@@ -116,5 +123,4 @@ public class UnOpenedMeta implements IUnOpenedProduct {
public static UnOpenedMeta selectAll(String desc) {
return new UnOpenedMeta(desc, JoinOperation.SelectAll);
}
}

View File

@@ -20,7 +20,9 @@ public class BoosterDraft1Test {
*/
@Test(groups = { "UnitTest", "fast" }, timeOut = 1000, enabled = false)
public void boosterDraft1Test1() throws Exception {
final BoosterDraft draft = new BoosterDraft(LimitedPoolType.Full);
final BoosterDraft draft = BoosterDraft.createDraft(LimitedPoolType.Full);
if (draft == null) { return; }
while (draft.hasNextChoice()) {
final CardPool list = draft.nextChoice();
System.out.println(list.countAll());