- Initial checkin for Winston Draft mode. The menu item for Winston Draft is currently commented out, but it should be functional even though the AI is randomnly taking piles based on pile size.

This commit is contained in:
Sol
2014-06-05 02:39:48 +00:00
parent cc79d33206
commit e04b64f7be
21 changed files with 1117 additions and 33 deletions

5
.gitattributes vendored
View File

@@ -826,6 +826,7 @@ forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorQues
forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorQuestDraftingProcess.java -text
forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorQuestLimited.java -text
forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorVariant.java -text
forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorWinstonProcess.java -text
forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CProbabilities.java -text
forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CStatistics.java -text
forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/DeckController.java -text
@@ -886,10 +887,12 @@ forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/AvatarSelector.jav
forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/CSubmenuConstructed.java -text
forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/CSubmenuDraft.java -text
forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/CSubmenuSealed.java -text
forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/CSubmenuWinston.java -text
forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/ConstructedGameMenu.java -text
forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/VSubmenuConstructed.java -text
forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/VSubmenuDraft.java -text
forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/VSubmenuSealed.java -text
forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/VSubmenuWinston.java -text
forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/package-info.java -text
forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuAvatars.java -text
forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuDownloaders.java -text
@@ -16407,6 +16410,8 @@ forge-gui/src/main/java/forge/limited/LimitedPoolType.java -text
forge-gui/src/main/java/forge/limited/ReadDraftRankings.java -text
forge-gui/src/main/java/forge/limited/SealedCardPoolGenerator.java svneol=native#text/plain
forge-gui/src/main/java/forge/limited/SealedDeckBuilder.java svneol=native#text/plain
forge-gui/src/main/java/forge/limited/WinstonDraft.java -text
forge-gui/src/main/java/forge/limited/WinstonDraftAI.java -text
forge-gui/src/main/java/forge/limited/package-info.java svneol=native#text/plain
forge-gui/src/main/java/forge/match/MatchConstants.java -text
forge-gui/src/main/java/forge/match/input/ButtonUtil.java -text

View File

@@ -11,6 +11,7 @@ public enum GameType {
// deck composition rules, isPoolRestricted, can sideboard between matches
Sealed (DeckFormat.Limited, true, true, true, "Sealed"),
Draft (DeckFormat.Limited, true, true, true, "Draft"),
Winston (DeckFormat.Limited, true, true, true, "Winston"),
Gauntlet (DeckFormat.Limited, true, true, true, "Gauntlet"),
Quest (DeckFormat.QuestDeck, true, true, false, "Quest"),
QuestDraft (DeckFormat.Limited, true, true, true, "Quest Draft"),

View File

@@ -12,6 +12,7 @@ import forge.screens.home.quest.*;
import forge.screens.home.sanctioned.VSubmenuConstructed;
import forge.screens.home.sanctioned.VSubmenuDraft;
import forge.screens.home.sanctioned.VSubmenuSealed;
import forge.screens.home.sanctioned.VSubmenuWinston;
import forge.screens.home.settings.VSubmenuAvatars;
import forge.screens.home.settings.VSubmenuDownloaders;
import forge.screens.home.settings.VSubmenuPreferences;
@@ -59,6 +60,7 @@ public enum EDocID { /** */
HOME_CONSTRUCTED (VSubmenuConstructed.SINGLETON_INSTANCE), /** */
HOME_DRAFT (VSubmenuDraft.SINGLETON_INSTANCE), /** */
HOME_SEALED (VSubmenuSealed.SINGLETON_INSTANCE), /** */
HOME_WINSTON (VSubmenuWinston.SINGLETON_INSTANCE), /** */
HOME_RELEASE_NOTES (VSubmenuReleaseNotes.SINGLETON_INSTANCE),
REPORT_MESSAGE (VPrompt.SINGLETON_INSTANCE), /** */

View File

@@ -237,6 +237,10 @@ public final class DeckManager extends ItemManager<DeckProxy> {
screen = FScreen.DECK_EDITOR_DRAFT;
editorCtrl = new CEditorLimited(FModel.getDecks().getDraft(), screen);
break;
case Winston:
screen = FScreen.DECK_EDITOR_DRAFT;
editorCtrl = new CEditorLimited(FModel.getDecks().getWinston(), screen);
break;
default:
return;

View File

@@ -0,0 +1,394 @@
/*
* Forge: Play Magic: the Gathering.
* Copyright (C) 2011 Forge Team
*
* 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 forge.screens.deckeditor.controllers;
import forge.Singletons;
import forge.UiCommand;
import forge.card.MagicColor;
import forge.deck.CardPool;
import forge.deck.Deck;
import forge.deck.DeckGroup;
import forge.deck.DeckSection;
import forge.model.FModel;
import forge.screens.deckeditor.CDeckEditorUI;
import forge.screens.deckeditor.views.VAllDecks;
import forge.screens.deckeditor.views.VCurrentDeck;
import forge.screens.deckeditor.views.VDeckgen;
import forge.gui.framework.DragCell;
import forge.gui.framework.FScreen;
import forge.screens.home.sanctioned.CSubmenuWinston;
import forge.toolbox.FOptionPane;
import forge.itemmanager.CardManager;
import forge.itemmanager.ItemManagerConfig;
import forge.item.PaperCard;
import forge.limited.BoosterDraft;
import forge.limited.IBoosterDraft;
import forge.limited.WinstonDraft;
import forge.properties.ForgePreferences.FPref;
import forge.util.ItemPool;
import forge.util.MyRandom;
import java.util.Map.Entry;
/**
* Updates the deck editor UI as necessary draft selection mode.
*
* <br><br><i>(C at beginning of class name denotes a control class.)</i>
*
* @author Forge
* @version $Id: CEditorDraftingProcess.java 24872 2014-02-17 07:35:47Z drdev $
*/
public class CEditorWinstonProcess extends ACEditorBase<PaperCard, DeckGroup> {
private IBoosterDraft boosterDraft;
private String ccAddLabel = "Add card";
private String ccAdd4Label = "Add card";
private Runnable ccAddCommand = null;
private Runnable ccAdd4Command = null;
private String ccTakeLabel = "Take pile";
private String ccPassLabel = "Pass pile";
private DragCell allDecksParent = null;
private DragCell deckGenParent = null;
private boolean saved = false;
//========== Constructor
/**
* Updates the deck editor UI as necessary draft selection mode.
*/
public CEditorWinstonProcess() {
super(FScreen.DRAFTING_PROCESS);
final CardManager catalogManager = new CardManager(false);
final CardManager deckManager = new CardManager(false);
//hide filters and options panel so more of pack is visible by default
catalogManager.setHideViewOptions(1, true);
deckManager.setCaption("Draft Picks");
catalogManager.setAlwaysNonUnique(true);
deckManager.setAlwaysNonUnique(true);
this.setCatalogManager(catalogManager);
this.setDeckManager(deckManager);
}
/**
* Show gui.
*
* @param inBoosterDraft
* the in_booster draft
*/
public final void showGui(final IBoosterDraft inBoosterDraft) {
this.boosterDraft = inBoosterDraft;
}
/* (non-Javadoc)
* @see forge.gui.deckeditor.ACEditorBase#onAddItems()
*/
@Override
protected void onAddItems(Iterable<Entry<PaperCard, Integer>> items, boolean toAlternate) {
// This doesn't actually do anything, need to use buttons to interact
}
/* (non-Javadoc)
* @see forge.gui.deckeditor.ACEditorBase#onRemoveItems()
*/
@Override
protected void onRemoveItems(Iterable<Entry<PaperCard, Integer>> items, boolean toAlternate) {
}
@Override
protected void buildAddContextMenu(EditorContextMenuBuilder cmb) {
cmb.addMoveItems("Draft", null);
}
@Override
protected void buildRemoveContextMenu(EditorContextMenuBuilder cmb) {
// no valid remove options
}
/**
* <p>
* showChoices.
* </p>
*
* @param list
* a {@link ItemPool<PaperCard>} object.
*/
private void showChoices(final ItemPool<PaperCard> list) {
int packNumber = ((BoosterDraft) boosterDraft).getCurrentBoosterIndex() + 1;
StringBuilder sb = new StringBuilder();
sb.append("Remaining: ");
sb.append(((WinstonDraft)boosterDraft).getDeckSize());
sb.append(" AI Cards: ");
sb.append(((WinstonDraft)boosterDraft).getAIDraftSize());
sb.append(" Pile");
sb.append(" ");
sb.append(packNumber);
sb.append(" - Cards");
this.getCatalogManager().setCaption(sb.toString());
this.getCatalogManager().setPool(list);
this.getDeckManager().refresh();
} // showChoices()
/**
* <p>
* getPlayersDeck.
* </p>
*
* @return a {@link forge.deck.Deck} object.
*/
private Deck getPlayersDeck() {
final Deck deck = new Deck();
// add sideboard to deck
deck.getOrCreate(DeckSection.Sideboard).addAll(this.getDeckManager().getPool());
final String landSet = IBoosterDraft.LAND_SET_CODE[0].getCode();
final boolean isZendikarSet = landSet.equals("ZEN"); // we want to generate one kind of Zendikar lands at a time only
final boolean zendikarSetMode = MyRandom.getRandom().nextBoolean();
final int landsCount = 10;
for(String landName : MagicColor.Constant.BASIC_LANDS) {
int numArt = FModel.getMagicDb().getCommonCards().getArtCount(landName, landSet);
int minArtIndex = isZendikarSet ? (zendikarSetMode ? 1 : 5) : 1;
int maxArtIndex = isZendikarSet ? minArtIndex + 3 : numArt;
if (FModel.getPreferences().getPrefBoolean(FPref.UI_RANDOM_ART_IN_POOLS)) {
for (int i = minArtIndex; i <= maxArtIndex; i++) {
deck.get(DeckSection.Sideboard).add(landName, landSet, i, numArt > 1 ? landsCount : 30);
}
} else {
deck.get(DeckSection.Sideboard).add(landName, landSet, 30);
}
}
return deck;
} // getPlayersDeck()
/**
* <p>
* saveDraft.
* </p>
*/
private void saveDraft() {
String s = FOptionPane.showInputDialog("Save this draft as:", "Save Draft", FOptionPane.QUESTION_ICON);
// Cancel button will be null; OK will return string.
// Must check for null value first, then string length.
// Recurse, if either null or empty string.
if (s == null || s.length() == 0) {
saveDraft();
return;
}
// Check for overwrite case
for (DeckGroup d : FModel.getDecks().getWinston()) {
if (s.equalsIgnoreCase(d.getName())) {
if (!FOptionPane.showConfirmDialog(
"There is already a deck named '" + s + "'. Overwrite?",
"Overwrite Deck?", false)) {
// If no overwrite, recurse.
saveDraft();
return;
}
break;
}
}
saved = true;
// TODO For pile drafts, only one other draft deck is made
// Construct computer's decks and save draft
final Deck[] computer = this.boosterDraft.getDecks();
final DeckGroup finishedDraft = new DeckGroup(s);
finishedDraft.setHumanDeck((Deck) this.getPlayersDeck().copyTo(s));
finishedDraft.addAiDecks(computer);
FModel.getDecks().getWinston().add(finishedDraft);
CSubmenuWinston.SINGLETON_INSTANCE.update();
FScreen.DRAFTING_PROCESS.close();
//open draft pool in Draft Deck Editor right away
Singletons.getControl().setCurrentScreen(FScreen.DECK_EDITOR_DRAFT);
CDeckEditorUI.SINGLETON_INSTANCE.setEditorController(new CEditorLimited(FModel.getDecks().getWinston(), FScreen.DECK_EDITOR_DRAFT));
CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController().getDeckController().load(null, s);
}
//========== Overridden from ACEditorBase
@Override
protected CardLimit getCardLimit() {
return CardLimit.None;
}
/*
* (non-Javadoc)
*
* @see forge.gui.deckeditor.ACEditorBase#getController()
*/
@Override
public DeckController<DeckGroup> getDeckController() {
return null;
}
/*
* (non-Javadoc)
*
* @see forge.gui.deckeditor.ACEditorBase#updateView()
*/
@Override
public void resetTables() {
}
/*
* (non-Javadoc)
*
* @see forge.gui.deckeditor.ACEditorBase#show(forge.Command)
*/
@Override
public void update() {
this.getCatalogManager().setup(ItemManagerConfig.DRAFT_PACK);
this.getDeckManager().setup(ItemManagerConfig.DRAFT_POOL);
ccAddLabel = this.getBtnAdd().getText();
if (this.getDeckManager().getPool() == null) { //avoid showing next choice or resetting pool if just switching back to Draft screen
this.getDeckManager().setPool((Iterable<PaperCard>) null);
this.showChoices(this.boosterDraft.nextChoice());
}
else {
this.showChoices(this.getCatalogManager().getPool());
}
this.getBtnRemove().setVisible(false);
this.getBtnRemove4().setVisible(false);
this.getBtnAdd().setText(ccTakeLabel);
this.getBtnAdd4().setText(ccPassLabel);
// Link the buttons to the appropriate functions
this.ccAddCommand = this.getBtnAdd().getCommand();
this.ccAdd4Command = this.getBtnAdd4().getCommand();
this.getBtnAdd().setCommand(new UiCommand() {
@Override
public void run() {
CEditorWinstonProcess.this.takePile();
}
});
this.getBtnAdd4().setCommand(new UiCommand() {
@Override
public void run() {
CEditorWinstonProcess.this.passPile();
}
});
deckGenParent = removeTab(VDeckgen.SINGLETON_INSTANCE);
allDecksParent = removeTab(VAllDecks.SINGLETON_INSTANCE);
// set catalog table to single-selection only mode
//getCatalogManager().setAllowMultipleSelections(false);
}
/* (non-Javadoc)
* @see forge.gui.deckeditor.controllers.ACEditorBase#canSwitchAway()
*/
@Override
public boolean canSwitchAway(boolean isClosing) {
if (isClosing && !saved) {
String userPrompt =
"This will end the current draft and you will not be able to resume.\n\n" +
"Leave anyway?";
return FOptionPane.showConfirmDialog(userPrompt, "Leave Draft?", "Leave", "Cancel", false);
}
return true;
}
/* (non-Javadoc)
* @see forge.gui.deckeditor.controllers.ACEditorBase#resetUIChanges()
*/
@Override
public void resetUIChanges() {
//Restore button names
this.getBtnAdd().setText(ccAddLabel);
this.getBtnAdd4().setText(ccAdd4Label);
this.getBtnAdd().setCommand(this.ccAddCommand);
this.getBtnAdd4().setCommand(this.ccAdd4Command);
//Re-add buttons
this.getBtnRemove().setVisible(true);
this.getBtnRemove4().setVisible(true);
VCurrentDeck.SINGLETON_INSTANCE.getPnlHeader().setVisible(true);
//Re-add tabs
if (deckGenParent != null) {
deckGenParent.addDoc(VDeckgen.SINGLETON_INSTANCE);
}
if (allDecksParent != null) {
allDecksParent.addDoc(VAllDecks.SINGLETON_INSTANCE);
}
// set catalog table back to free-selection mode
getCatalogManager().setAllowMultipleSelections(true);
}
private void takePile() {
CardPool pool = ((WinstonDraft)boosterDraft).takeActivePile(true);
// Add pool to deck
this.getDeckManager().getPool().addAll(pool);
// get next booster pack
if (this.boosterDraft.hasNextChoice()) {
CardPool newPool = this.boosterDraft.nextChoice();
if (newPool != null) {
this.showChoices(newPool);
return;
}
}
// If we get here, there's no choices left. Finish the draft and then save it
this.boosterDraft.finishedDrafting();
this.saveDraft();
}
private void passPile() {
CardPool pool = ((WinstonDraft)boosterDraft).passActivePile(true);
if (pool != null) {
// Passed the third pile, draw the top card of the deck
this.getDeckManager().getPool().addAll(pool);
}
CardPool newPool = this.boosterDraft.nextChoice();
if (newPool != null) {
this.showChoices(newPool);
}
}
}

View File

@@ -10,6 +10,7 @@ public enum EMenuItem { /** */
CONSTRUCTED, /** */
LIMITED_DRAFT, /** */
LIMITED_SEALED, /** */
LIMITED_WINSTON,
QUEST_CHALLENGES, /** */
QUEST_DUELS, /** */

View File

@@ -31,6 +31,7 @@ import forge.screens.home.quest.*;
import forge.screens.home.sanctioned.VSubmenuConstructed;
import forge.screens.home.sanctioned.VSubmenuDraft;
import forge.screens.home.sanctioned.VSubmenuSealed;
import forge.screens.home.sanctioned.VSubmenuWinston;
import forge.screens.home.settings.VSubmenuAvatars;
import forge.screens.home.settings.VSubmenuDownloaders;
import forge.screens.home.settings.VSubmenuPreferences;
@@ -115,6 +116,7 @@ public enum VHomeUI implements IVTopLevelUI {
allSubmenus.add(VSubmenuConstructed.SINGLETON_INSTANCE);
allSubmenus.add(VSubmenuDraft.SINGLETON_INSTANCE);
allSubmenus.add(VSubmenuSealed.SINGLETON_INSTANCE);
//allSubmenus.add(VSubmenuWinston.SINGLETON_INSTANCE);
allSubmenus.add(VSubmenuDuels.SINGLETON_INSTANCE);
allSubmenus.add(VSubmenuChallenges.SINGLETON_INSTANCE);

View File

@@ -75,7 +75,7 @@ public enum CSubmenuDraft implements ICDoc {
*/
@Override
public void update() {
final VSubmenuDraft view = VSubmenuDraft.SINGLETON_INSTANCE;
final VSubmenuDraft view = VSubmenuDraft.SINGLETON_INSTANCE;
final JButton btnStart = view.getBtnStart();
view.getLstDecks().setPool(DeckProxy.getDraftDecks(FModel.getDecks().getDraft()));

View File

@@ -0,0 +1,162 @@
package forge.screens.home.sanctioned;
import forge.GuiBase;
import forge.UiCommand;
import forge.Singletons;
import forge.deck.Deck;
import forge.deck.DeckGroup;
import forge.game.GameType;
import forge.game.player.RegisteredPlayer;
import forge.gui.GuiChoose;
import forge.gui.SOverlayUtils;
import forge.interfaces.IGuiBase;
import forge.model.FModel;
import forge.screens.deckeditor.CDeckEditorUI;
import forge.deck.DeckProxy;
import forge.screens.deckeditor.controllers.CEditorWinstonProcess;
import forge.gui.framework.FScreen;
import forge.gui.framework.ICDoc;
import forge.toolbox.FOptionPane;
import forge.itemmanager.ItemManagerConfig;
import forge.limited.LimitedPoolType;
import forge.limited.WinstonDraft;
import forge.properties.ForgePreferences.FPref;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
/**
* Controls the draft submenu in the home UI.
*
* <br><br><i>(C at beginning of class name denotes a control class.)</i>
*
*/
@SuppressWarnings("serial")
public enum CSubmenuWinston implements ICDoc {
/** */
SINGLETON_INSTANCE;
private final UiCommand cmdDeckSelect = new UiCommand() {
@Override
public void run() {
VSubmenuWinston.SINGLETON_INSTANCE.getBtnStart().setEnabled(true);
}
};
/* (non-Javadoc)
* @see forge.control.home.IControlSubmenu#update()
*/
@Override
public void initialize() {
final VSubmenuWinston view = VSubmenuWinston.SINGLETON_INSTANCE;
view.getLstDecks().setSelectCommand(cmdDeckSelect);
view.getBtnBuildDeck().setCommand(new UiCommand() {
@Override
public void run() {
setupDraft();
}
});
view.getBtnStart().addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
startGame(GameType.Winston);
}
});
}
/* (non-Javadoc)
* @see forge.control.home.IControlSubmenu#update()
*/
@Override
public void update() {
final VSubmenuWinston view = VSubmenuWinston.SINGLETON_INSTANCE;
final JButton btnStart = view.getBtnStart();
view.getLstDecks().setPool(DeckProxy.getWinstonDecks(FModel.getDecks().getWinston()));
view.getLstDecks().setup(ItemManagerConfig.WINSTON_DECKS);
if (!view.getLstDecks().getPool().isEmpty()) {
btnStart.setEnabled(true);
}
SwingUtilities.invokeLater(new Runnable() {
@Override public void run() {
if (btnStart.isEnabled()) {
view.getBtnStart().requestFocusInWindow();
} else {
view.getBtnBuildDeck().requestFocusInWindow();
}
}
});
}
private void startGame(final GameType gameType) {
final DeckProxy humanDeck = VSubmenuWinston.SINGLETON_INSTANCE.getLstDecks().getSelectedItem();
final int aiIndex = 0;
if (humanDeck == null) {
FOptionPane.showErrorDialog("No deck selected for human.\n(You may need to build a new deck)", "No Deck");
return;
}
if (FModel.getPreferences().getPrefBoolean(FPref.ENFORCE_DECK_LEGALITY)) {
String errorMessage = gameType.getDecksFormat().getDeckConformanceProblem(humanDeck.getDeck());
if (null != errorMessage) {
FOptionPane.showErrorDialog("Your deck " + errorMessage + " Please edit or choose a different deck.", "Invalid Deck");
return;
}
}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
SOverlayUtils.startGameOverlay();
SOverlayUtils.showOverlay();
}
});
DeckGroup opponentDecks = FModel.getDecks().getWinston().get(humanDeck.getName());
Deck aiDeck = opponentDecks.getAiDecks().get(aiIndex);
if (aiDeck == null) {
throw new IllegalStateException("Draft: Computer deck is null!");
}
IGuiBase fc = GuiBase.getInterface();
List<RegisteredPlayer> starter = new ArrayList<RegisteredPlayer>();
starter.add(new RegisteredPlayer(humanDeck.getDeck()).setPlayer(fc.getGuiPlayer()));
starter.add(new RegisteredPlayer(aiDeck).setPlayer(fc.createAiPlayer()));
Singletons.getControl().startMatch(GameType.Winston, starter);
}
/** */
private void setupDraft() {
// Determine what kind of booster draft to run
final LimitedPoolType poolType = GuiChoose.oneOrNone("Choose Draft Format", LimitedPoolType.values());
if (poolType == null) { return; }
WinstonDraft draft = WinstonDraft.createDraft(poolType);
if (draft == null) { return; }
final CEditorWinstonProcess draftController = new CEditorWinstonProcess();
draftController.showGui(draft);
Singletons.getControl().setCurrentScreen(FScreen.DRAFTING_PROCESS);
CDeckEditorUI.SINGLETON_INSTANCE.setEditorController(draftController);
}
/* (non-Javadoc)
* @see forge.gui.framework.ICDoc#getCommandOnSelect()
*/
@Override
public UiCommand getCommandOnSelect() {
return null;
}
}

View File

@@ -0,0 +1,177 @@
package forge.screens.home.sanctioned;
import forge.game.GameType;
import forge.gui.framework.DragCell;
import forge.gui.framework.DragTab;
import forge.gui.framework.EDocID;
import forge.itemmanager.DeckManager;
import forge.itemmanager.ItemManagerContainer;
import forge.screens.home.*;
import forge.screens.home.VHomeUI.PnlDisplay;
import forge.toolbox.*;
import net.miginfocom.swing.MigLayout;
import javax.swing.*;
import java.awt.*;
/**
* Assembles Swing components of draft submenu singleton.
*
* <br><br><i>(V at beginning of class name denotes a view class.)</i>
*/
public enum VSubmenuWinston implements IVSubmenu<CSubmenuWinston> {
/** */
SINGLETON_INSTANCE;
// Fields used with interface IVDoc
private DragCell parentCell;
private final DragTab tab = new DragTab("Winston Draft");
/** */
private final LblHeader lblTitle = new LblHeader("Sanctioned Format: Winston Draft");
private final JPanel pnlStart = new JPanel();
private final StartButton btnStart = new StartButton();
private final DeckManager lstDecks = new DeckManager(GameType.Winston);
private final JList<String> lstAI = new FList<String>();
private final JLabel lblInfo = new FLabel.Builder()
.fontAlign(SwingConstants.LEFT).fontSize(16).fontStyle(Font.BOLD)
.text("Build or select a deck").build();
private final FLabel lblDir1 = new FLabel.Builder()
.text("In Winston Draft mode, two players draft 6 packs of cards by piles.")
.fontSize(12).build();
private final FLabel lblDir2 = new FLabel.Builder()
.text("Build a deck from the cards you choose. The AI will do the same.")
.fontSize(12).build();
private final FLabel lblDir3 = new FLabel.Builder()
.text("Then, play against the AI opponent you drafted against.")
.fontSize(12).build();
private final FLabel btnBuildDeck = new FLabel.ButtonBuilder().text("New Winston Draft Game").fontSize(16).build();
/**
* Constructor.
*/
private VSubmenuWinston() {
lstAI.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
btnStart.setEnabled(false);
lblTitle.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2));
lstDecks.setCaption("Winston Draft Decks");
pnlStart.setLayout(new MigLayout("insets 0, gap 0, wrap 2"));
pnlStart.setOpaque(false);
pnlStart.add(btnStart);
}
/* (non-Javadoc)
* @see forge.view.home.IViewSubmenu#getGroup()
*/
@Override
public EMenuGroup getGroupEnum() {
return EMenuGroup.SANCTIONED;
}
/* (non-Javadoc)
* @see forge.gui.home.IVSubmenu#getMenuTitle()
*/
@Override
public String getMenuTitle() {
return "Winston Draft";
}
/* (non-Javadoc)
* @see forge.gui.home.IVSubmenu#getItemEnum()
*/
@Override
public EDocID getItemEnum() {
return EDocID.HOME_WINSTON;
}
/** @return {@link forge.gui.toolbox.FLabel} */
public FLabel getBtnBuildDeck() {
return this.btnBuildDeck;
}
/** @return {@link javax.swing.JButton} */
public JButton getBtnStart() {
return this.btnStart;
}
/** @return {@link forge.gui.toolbox.itemmanager.DeckManager} */
public DeckManager getLstDecks() {
return lstDecks;
}
//========== Overridden from IVDoc
/* (non-Javadoc)
* @see forge.view.home.IViewSubmenu#populate()
*/
@Override
public void populate() {
PnlDisplay pnlDisplay = VHomeUI.SINGLETON_INSTANCE.getPnlDisplay();
pnlDisplay.removeAll();
pnlDisplay.setLayout(new MigLayout("insets 0, gap 0, wrap, ax right"));
pnlDisplay.add(lblTitle, "w 80%!, h 40px!, gap 0 0 15px 15px, ax right");
pnlDisplay.add(lblInfo, "w 80%!, h 30px!, gap 0 10% 20px 5px");
pnlDisplay.add(lblDir1, "gap 0 0 0 5px");
pnlDisplay.add(lblDir2, "gap 0 0 0 5px");
pnlDisplay.add(lblDir3, "gap 0 0 0 20px");
pnlDisplay.add(btnBuildDeck, "w 250px!, h 30px!, ax center, gap 0 10% 0 20px");
pnlDisplay.add(new ItemManagerContainer(lstDecks), "w 80%!, gap 0 10% 0 0, pushy, growy");
pnlDisplay.add(pnlStart, "gap 0 10% 50px 50px, ax center");
pnlDisplay.repaint();
pnlDisplay.revalidate();
}
/* (non-Javadoc)
* @see forge.gui.framework.IVDoc#getDocumentID()
*/
@Override
public EDocID getDocumentID() {
return EDocID.HOME_WINSTON;
}
/* (non-Javadoc)
* @see forge.gui.framework.IVDoc#getTabLabel()
*/
@Override
public DragTab getTabLabel() {
return tab;
}
/* (non-Javadoc)
* @see forge.gui.framework.IVDoc#setParentCell(forge.gui.framework.DragCell)
*/
@Override
public void setParentCell(final DragCell cell0) {
this.parentCell = cell0;
}
/* (non-Javadoc)
* @see forge.gui.framework.IVDoc#getParentCell()
*/
@Override
public DragCell getParentCell() {
return parentCell;
}
/* (non-Javadoc)
* @see forge.gui.framework.IVDoc#getLayoutControl()
*/
@Override
public CSubmenuWinston getLayoutControl() {
return CSubmenuWinston.SINGLETON_INSTANCE;
}
}

View File

@@ -105,4 +105,9 @@ public class BoosterDraftTest implements IBoosterDraft {
public void finishedDrafting() {
}
@Override
public boolean isPileDraft() {
return false;
}
}

View File

@@ -416,6 +416,15 @@ public class DeckProxy implements InventoryItem {
return decks;
}
@SuppressWarnings("unchecked")
public static Iterable<DeckProxy> getWinstonDecks(IStorage<DeckGroup> draft) {
ArrayList<DeckProxy> decks = new ArrayList<DeckProxy>();
for (DeckGroup d : draft) {
decks.add(new DeckProxy(d, "Winston", ((Function<IHasName, Deck>)(Object)DeckGroup.FN_HUMAN_DECK), GameType.Winston, draft));
}
return decks;
}
public static final Predicate<DeckProxy> IS_WHITE = new Predicate<DeckProxy>() {
@Override
public boolean apply(final DeckProxy deck) {

View File

@@ -58,6 +58,8 @@ public enum ItemManagerConfig {
null, null, 3, 0),
SEALED_DECKS(SColumnUtil.getDecksDefaultColumns(true, false), false, false, false,
null, null, 3, 0),
WINSTON_DECKS(SColumnUtil.getDecksDefaultColumns(true, false), false, false, false,
null, null, 3, 0),
QUEST_DECKS(SColumnUtil.getDecksDefaultColumns(true, false), false, false, false,
null, null, 3, 0),
PRECON_DECKS(SColumnUtil.getDecksDefaultColumns(false, false), false, false, false,

View File

@@ -50,31 +50,35 @@ import java.util.Map.Entry;
* Booster Draft Format.
*
*/
public final class BoosterDraft implements IBoosterDraft {
public class BoosterDraft implements IBoosterDraft {
private final BoosterDraftAI draftAI = new BoosterDraftAI();
private static final int N_PLAYERS = 8;
public static final String FILE_EXT = ".draft";
private int nextBoosterGroup = 0;
protected int nextBoosterGroup = 0;
private int currentBoosterSize = 0;
private int currentBoosterPick = 0;
private List<List<PaperCard>> pack; // size 8
/** The draft picks. */
private final Map<String, Float> draftPicks = new TreeMap<String, Float>();
private final LimitedPoolType draftFormat;
protected LimitedPoolType draftFormat;
private final List<Supplier<List<PaperCard>>> product = new ArrayList<Supplier<List<PaperCard>>>();
protected final List<Supplier<List<PaperCard>>> product = new ArrayList<Supplier<List<PaperCard>>>();
public static BoosterDraft createDraft(final LimitedPoolType draftType) {
BoosterDraft draft = new BoosterDraft(draftType);
if (!draft.generateProduct()) { return null; }
return draft;
}
switch (draftType) {
protected boolean generateProduct() {
switch (this.draftFormat) {
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);
this.product.add(s);
}
IBoosterDraft.LAND_SET_CODE[0] = CardEdition.Predicates.getRandomSetWithAllBasicLands(FModel.getMagicDb().getEditions());
break;
@@ -82,7 +86,7 @@ public final class BoosterDraft implements IBoosterDraft {
case Block: // Draft from cards by block or set
case FantasyBlock:
List<CardBlock> blocks = new ArrayList<CardBlock>();
IStorage<CardBlock> storage = draftType == LimitedPoolType.Block
IStorage<CardBlock> storage = this.draftFormat == LimitedPoolType.Block
? FModel.getBlocks() : FModel.getFantasyBlocks();
for (CardBlock b : storage) {
@@ -92,12 +96,12 @@ public final class BoosterDraft implements IBoosterDraft {
}
final CardBlock block = SGuiChoose.oneOrNone("Choose Block", blocks);
if (block == null) { return null; }
if (block == null) { return false; }
final CardEdition[] cardSets = block.getSets();
if (cardSets.length == 0) {
SOptionPane.showErrorDialog(block.toString() + " does not contain any set combinations.");
return null;
return false;
}
final Stack<String> sets = new Stack<String>();
@@ -115,18 +119,18 @@ public final class BoosterDraft implements IBoosterDraft {
if (sets.size() > 1) {
final Object p = SGuiChoose.oneOrNone("Choose Set Combination", getSetCombos(sets));
if (p == null) { return null; }
if (p == null) { return false; }
final String[] pp = p.toString().split("/");
for (int i = 0; i < nPacks; i++) {
draft.product.add(block.getBooster(pp[i]));
this.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);
this.product.add(product1);
}
}
@@ -134,29 +138,28 @@ public final class BoosterDraft implements IBoosterDraft {
break;
case Custom:
final List<CustomLimited> myDrafts = draft.loadCustomDrafts();
final List<CustomLimited> myDrafts = this.loadCustomDrafts();
if (myDrafts.isEmpty()) {
SOptionPane.showMessageDialog("No custom draft files found.");
}
else {
final CustomLimited customDraft = SGuiChoose.oneOrNone("Choose Custom Draft", myDrafts);
if (customDraft == null) { return null; }
if (customDraft == null) { return false; }
draft.setupCustomDraft(customDraft);
this.setupCustomDraft(customDraft);
}
break;
default:
throw new NoSuchElementException("Draft for mode " + draftType + " has not been set up!");
throw new NoSuchElementException("Draft for mode " + this.draftFormat + " has not been set up!");
}
draft.pack = draft.get8BoosterPack();
return draft;
this.pack = this.get8BoosterPack();
return true;
}
public static BoosterDraft createDraft(final LimitedPoolType draftType, final CardBlock block, final String[] boosters) {
public static BoosterDraft createDraft(final LimitedPoolType draftType, final CardBlock block, final String[] boosters) {
BoosterDraft draft = new BoosterDraft(draftType);
final int nPacks = boosters.length;
@@ -169,18 +172,20 @@ public final class BoosterDraft implements IBoosterDraft {
draft.pack = draft.get8BoosterPack();
return draft;
}
protected BoosterDraft() {
this.draftFormat = LimitedPoolType.Full;
}
/**
* <p>
* Constructor for BoosterDraft_1.
* </p>
*
*
* @param draftType
* a {@link java.lang.String} object.
*/
private BoosterDraft(final LimitedPoolType draftType) {
protected BoosterDraft(final LimitedPoolType draftType) {
this.draftAI.setBd(this);
this.draftFormat = draftType;
}
@@ -233,7 +238,7 @@ public final class BoosterDraft implements IBoosterDraft {
* nextChoice.
* </p>
*
* @return a {@link forge.CardList} object.
* @return a {@link forge.deck.CardPool} object.
*/
@Override
public CardPool nextChoice() {
@@ -252,7 +257,7 @@ public final class BoosterDraft implements IBoosterDraft {
* get8BoosterPack.
* </p>
*
* @return an array of {@link forge.CardList} objects.
* @return an array of {@link forge.deck.CardPool} objects.
*/
public List<List<PaperCard>> get8BoosterPack() {
if (this.nextBoosterGroup >= this.product.size()) {
@@ -284,7 +289,7 @@ public final class BoosterDraft implements IBoosterDraft {
return this.draftAI.getDecks();
}
private void computerChoose() {
protected void computerChoose() {
final int iHumansBooster = this.getCurrentBoosterIndex();
int iPlayer = 0;
for (int i = 1; i < this.pack.size(); i++) {
@@ -377,6 +382,11 @@ public final class BoosterDraft implements IBoosterDraft {
HttpUtil.upload(ForgeConstants.URL_DRAFT_UPLOAD + "?fmt=" + draftFormat, outDraftData);
}
@Override
public boolean isPileDraft() {
return false;
}
private static List<String> getSetCombos(final List<String> setz) {
String[] sets = setz.toArray(ArrayUtils.EMPTY_STRING_ARRAY);
List<String> setCombos = new ArrayList<String>();

View File

@@ -45,11 +45,11 @@ public class BoosterDraftAI {
/**
* Constant <code>nDecks=7.</code>
*/
private static final int N_DECKS = 7;
protected static final int N_DECKS = 7;
// holds all the cards for each of the computer's decks
private final List<List<PaperCard>> deck = new ArrayList<List<PaperCard>>();
private final ArrayList<DeckColors> playerColors = new ArrayList<DeckColors>();
protected final List<List<PaperCard>> deck = new ArrayList<List<PaperCard>>();
protected final ArrayList<DeckColors> playerColors = new ArrayList<DeckColors>();
// roughly equivalent to 25 ranks in a core set, or 15 ranks in a small set
private static final double TAKE_BEST_THRESHOLD = 0.1;
@@ -63,7 +63,7 @@ public class BoosterDraftAI {
* List of CardPrinted
* @param player
* a int.
* @return a {@link forge.CardList} object.
* @return a {@link forge.item.PaperCard} object.
*/
public PaperCard choose(final List<PaperCard> chooseFrom, final int player) {
if (ForgePreferences.DEV_MODE) {

View File

@@ -22,6 +22,8 @@ import forge.card.MagicColor;
import forge.card.mana.ManaCost;
import forge.item.IPaperCard;
import java.util.List;
/**
* Created by IntelliJ IDEA. User: dhudson Date: 6/24/11 Time: 8:42 PM To change
* this template use File | Settings | File Templates.
@@ -64,6 +66,14 @@ class DeckColors {
}
}
public void setColorsByList(List<Byte> colors) {
colorMask = 0;
for (Byte col : colors) {
colorMask |= col;
}
chosen = null;
}
public boolean canChoseMoreColors() {
return getChosenColors().countColors() < MAX_COLORS;

View File

@@ -76,4 +76,6 @@ public interface IBoosterDraft {
*/
void finishedDrafting();
boolean isPileDraft();
}

View File

@@ -0,0 +1,178 @@
package forge.limited;
import com.google.common.base.Predicates;
import com.google.common.base.Supplier;
import com.google.common.collect.Iterables;
import forge.deck.CardPool;
import forge.deck.Deck;
import forge.item.IPaperCard;
import forge.item.PaperCard;
import forge.quest.data.GameFormatQuest;
import forge.util.MyRandom;
import java.util.*;
public class WinstonDraft extends BoosterDraft {
private WinstonDraftAI draftAI = null;
private static int NUM_PILES = 3;
private static int NUM_PLAYERS = 2;
private Stack<PaperCard> deck; // main deck where all cards
private List<List<PaperCard>> piles; // 3 piles to draft from
public static WinstonDraft createDraft(final LimitedPoolType draftType) {
WinstonDraft draft = new WinstonDraft(draftType);
if (!draft.generateProduct()) {
return null;
}
draft.initializeWinstonDraft();
return draft;
}
private WinstonDraft(LimitedPoolType draftType) {
draftFormat = draftType;
draftAI = new WinstonDraftAI();
}
private void initializeWinstonDraft() {
this.deck = new Stack<PaperCard>();
for (int i = 0; i < this.product.size(); i++) {
Supplier<List<PaperCard>> supply = this.product.get(i);
for(int j = 0; j < NUM_PLAYERS; j++) {
// Remove Basic Lands from draft for simplicity
for (PaperCard paperCard : Iterables.filter(supply.get(), Predicates.not(PaperCard.Predicates.Presets.IS_BASIC_LAND))) {
this.deck.add(paperCard);
}
}
}
Collections.shuffle(this.deck, MyRandom.getRandom());
// Create three Winston piles, adding the top card from the Winston deck to start each pile
this.piles = new ArrayList<>();
for(int i = 0; i < NUM_PILES; i++) {
List<PaperCard> pile = new ArrayList<PaperCard>();
pile.add(this.deck.pop());
this.piles.add(pile);
}
this.nextBoosterGroup = 0;
draftAI.setDraft(this);
if (MyRandom.percentTrue(50)) {
// 50% chance of the AI picking the first card in a Winston Draft
//this.computerChoose();
}
}
@Override
public CardPool nextChoice() {
// This is called for two reasons: Skipping a pile, and getting the next one in line
// Or taking a pile and getting reset back to the first non-empty pile
int nextPile = -1;
for(int i = nextBoosterGroup; i < this.piles.size(); i++) {
if (this.piles.get(i).size() > 0) {
nextPile = i;
break;
}
}
if (nextPile < 0 || nextPile > this.piles.size())
return null;
nextBoosterGroup = nextPile;
return getPoolByPile(nextBoosterGroup);
}
public CardPool getActivePool() {
return getPoolByPile(this.nextBoosterGroup);
}
private CardPool getPoolByPile(int i) {
CardPool result = new CardPool();
result.addAllFlat(this.piles.get(i));
return result;
}
public void computerChoose() {
nextBoosterGroup = 0;
draftAI.choose();
}
public void refillPile(List<PaperCard> pile) {
if (this.deck.size() > 0)
pile.add(this.deck.pop());
}
public int getNextChoice(int startPile) {
for(int i = startPile; i < NUM_PILES; i++) {
if (this.piles.get(i).size() > 0)
return i;
}
// All piles are empty, so draft is about to end.
return -1;
}
public boolean hasNextChoice() {
return getNextChoice(0) >= 0;
}
public boolean isLastPileAndEmptyDeck(int pile) {
return this.deck.size() == 0 && getNextChoice(pile+1) >= 0;
}
public int getCurrentBoosterIndex() {
return nextBoosterGroup;
}
public CardPool takeActivePile(boolean humanAction) {
CardPool pool = getPoolByPile(this.nextBoosterGroup);
this.piles.get(this.nextBoosterGroup).clear();
this.refillPile(this.piles.get(this.nextBoosterGroup));
this.nextBoosterGroup = 0;
if (humanAction)
computerChoose();
return pool;
}
public CardPool passActivePile(boolean humanAction) {
this.refillPile(this.piles.get(this.nextBoosterGroup));
this.nextBoosterGroup++;
if (this.nextBoosterGroup >= this.piles.size()) {
CardPool pool = new CardPool();
if (this.deck.size() > 0)
pool.add(this.deck.pop());
this.nextBoosterGroup = 0;
if (humanAction)
computerChoose();
return pool;
}
return null;
}
public int getNumPiles() {
return NUM_PILES;
}
@Override
public Deck[] getDecks() {
this.determineAIDeckColors();
return this.draftAI.getDecks();
}
public void determineAIDeckColors() {
this.draftAI.determineDeckColor();
}
@Override
public boolean isPileDraft() {
return true;
}
public int getDeckSize() { return this.deck.size(); }
public int getAIDraftSize() { return this.draftAI.getAIDraftSize(); }
}

View File

@@ -0,0 +1,114 @@
package forge.limited;
import forge.card.ColorSet;
import forge.card.MagicColor;
import forge.deck.CardPool;
import forge.game.card.CardColor;
import forge.item.PaperCard;
import forge.util.MyRandom;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class WinstonDraftAI extends BoosterDraftAI{
private WinstonDraft draft = null;
private static final int N_DECKS = 1;
private ArrayList<Byte> colorPreference = new ArrayList<>();
public WinstonDraft getDraft() {
return draft;
}
public void setDraft(WinstonDraft draft) {
this.draft = draft;
}
public WinstonDraftAI() {
this.deck.clear();
this.playerColors.clear();
for (int i = 0; i < N_DECKS; i++) {
this.deck.add(new ArrayList<PaperCard>());
this.playerColors.add(new DeckColors());
}
}
public void determineDeckColor() {
// Turn colorPreference into playerColors
int count[] = tallyDeckColors();
// Just take the three best colors, but maybe sometimes only take best two
this.playerColors.get(0).setColorsByList(colorPreference.subList(0, 3));
}
public void choose() {
boolean takenPile = true;
CardPool acquire = null;
while(takenPile) {
CardPool pool = draft.getActivePool();
// Determine if the current pool is worth taking
// For now, each card in a pile is worth 10 points. Compare versus a d100 roll
String desc = "Pile " + (draft.getCurrentBoosterIndex()+1);
int value = pool.countAll() * 10;
// If this is the last pile, and the deck is empty, definitely take the pile!
boolean takePile = MyRandom.percentTrue(value) || draft.isLastPileAndEmptyDeck(draft.getCurrentBoosterIndex());
if (takePile) {
acquire = draft.takeActivePile(false);
} else {
acquire = draft.passActivePile(false);
desc = "Top of Deck";
}
if (acquire != null) {
System.out.println("AI taking " + desc + "(" + acquire.countAll() + " cards).");
takenPile = false;
}
}
if (acquire != null) {
this.deck.get(0).addAll(acquire.toFlatList());
//tallyDeckColors();
}
}
private int[] tallyDeckColors() {
int[] colorCount = new int[5];
for(PaperCard pc : this.deck.get(0)) {
ColorSet colors = pc.getRules().getColor();
if (colors.hasWhite())
colorCount[0]++;
if (colors.hasBlue())
colorCount[1]++;
if (colors.hasBlack())
colorCount[2]++;
if (colors.hasRed())
colorCount[3]++;
if (colors.hasGreen())
colorCount[4]++;
}
// Just keep order or should I keep order/value pairs?
colorPreference.clear();
for(int i = 0; i < colorCount.length; i++) {
// Sort colors in order.
Byte col = MagicColor.WUBRG[i];
int spot = 0;
for (int j = 0; j < i; j++) {
if (colorCount[i] > colorCount[j]) {
// If new color has more than the current slot, we need to add into that slot
// And push all remaining colors further down
break;
}
spot++;
}
colorPreference.add(spot, col);
}
// Is this the right order?
return colorCount;
}
public int getAIDraftSize() {
return this.deck.get(0).size();
}
}

View File

@@ -37,6 +37,7 @@ public class CardCollections {
private final IStorage<Deck> constructed;
private final IStorage<DeckGroup> draft;
private final IStorage<DeckGroup> sealed;
private final IStorage<DeckGroup> winston;
private final IStorage<Deck> cube;
private final IStorage<Deck> scheme;
private final IStorage<Deck> plane;
@@ -53,11 +54,11 @@ public class CardCollections {
this.constructed = new StorageImmediatelySerialized<Deck>("Constructed decks", new DeckStorage(new File(ForgeConstants.DECK_CONSTRUCTED_DIR), true), true);
this.draft = new StorageImmediatelySerialized<DeckGroup>("Draft deck sets", new DeckGroupSerializer(new File(ForgeConstants.DECK_DRAFT_DIR)));
this.sealed = new StorageImmediatelySerialized<DeckGroup>("Sealed deck sets", new DeckGroupSerializer(new File(ForgeConstants.DECK_SEALED_DIR)));
this.winston = new StorageImmediatelySerialized<DeckGroup>("Winston draft deck sets", new DeckGroupSerializer(new File(ForgeConstants.DECK_WINSTON_DIR)));
this.cube = new StorageImmediatelySerialized<Deck>("Cubes", new DeckStorage(new File(ForgeConstants.DECK_CUBE_DIR)));
this.scheme = new StorageImmediatelySerialized<Deck>("Archenemy decks", new DeckStorage(new File(ForgeConstants.DECK_SCHEME_DIR)));
this.plane = new StorageImmediatelySerialized<Deck>("Planechase decks", new DeckStorage(new File(ForgeConstants.DECK_PLANE_DIR)));
this.commander = new StorageImmediatelySerialized<Deck>("Commander decks", new DeckStorage(new File(ForgeConstants.DECK_COMMANDER_DIR)));
sw.stop();
System.out.printf("Read decks (%d ms): %d constructed, %d sealed, %d draft, %d cubes, %d scheme, %d planar, %d commander.%n", sw.getTime(), constructed.size(), sealed.size(), draft.size(), cube.size(), scheme.size(), plane.size(),commander.size());
// int sum = constructed.size() + sealed.size() + draft.size() + cube.size() + scheme.size() + plane.size();
@@ -85,6 +86,10 @@ public class CardCollections {
return this.draft;
}
public final IStorage<DeckGroup> getWinston() {
return this.winston;
}
/**
* Gets the cubes.
*

View File

@@ -102,6 +102,7 @@ public final class ForgeConstants {
public static final String DECK_BASE_DIR = USER_DIR + "decks/";
public static final String DECK_CONSTRUCTED_DIR = DECK_BASE_DIR + "constructed/";
public static final String DECK_DRAFT_DIR = DECK_BASE_DIR + "draft/";
public static final String DECK_WINSTON_DIR = DECK_BASE_DIR + "winston/";
public static final String DECK_SEALED_DIR = DECK_BASE_DIR + "sealed/";
public static final String DECK_SCHEME_DIR = DECK_BASE_DIR + "scheme/";
public static final String DECK_PLANE_DIR = DECK_BASE_DIR + "planar/";