mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 12:18:00 +00:00
Support generating sealed deck for mobile game
This commit is contained in:
@@ -2,40 +2,24 @@ package forge.screens.home.sanctioned;
|
|||||||
|
|
||||||
import forge.UiCommand;
|
import forge.UiCommand;
|
||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.card.MagicColor;
|
|
||||||
import forge.deck.*;
|
import forge.deck.*;
|
||||||
import forge.game.GameType;
|
import forge.game.GameType;
|
||||||
import forge.gui.GuiChoose;
|
|
||||||
import forge.deck.DeckProxy;
|
import forge.deck.DeckProxy;
|
||||||
import forge.gui.framework.FScreen;
|
import forge.gui.framework.FScreen;
|
||||||
import forge.gui.framework.ICDoc;
|
import forge.gui.framework.ICDoc;
|
||||||
import forge.item.InventoryItem;
|
import forge.item.InventoryItem;
|
||||||
import forge.item.PaperCard;
|
|
||||||
import forge.itemmanager.ItemManagerConfig;
|
import forge.itemmanager.ItemManagerConfig;
|
||||||
import forge.limited.DraftRankCache;
|
|
||||||
import forge.limited.LimitedPoolType;
|
|
||||||
import forge.limited.SealedCardPoolGenerator;
|
import forge.limited.SealedCardPoolGenerator;
|
||||||
import forge.limited.SealedDeckBuilder;
|
|
||||||
import forge.model.FModel;
|
import forge.model.FModel;
|
||||||
import forge.properties.ForgePreferences.FPref;
|
import forge.properties.ForgePreferences.FPref;
|
||||||
import forge.screens.deckeditor.CDeckEditorUI;
|
import forge.screens.deckeditor.CDeckEditorUI;
|
||||||
import forge.screens.deckeditor.controllers.ACEditorBase;
|
import forge.screens.deckeditor.controllers.ACEditorBase;
|
||||||
import forge.screens.deckeditor.controllers.CEditorLimited;
|
import forge.screens.deckeditor.controllers.CEditorLimited;
|
||||||
import forge.toolbox.FOptionPane;
|
import forge.toolbox.FOptionPane;
|
||||||
import forge.util.MyRandom;
|
|
||||||
import forge.util.storage.IStorage;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controls the sealed submenu in the home UI.
|
* Controls the sealed submenu in the home UI.
|
||||||
@@ -48,8 +32,6 @@ public enum CSubmenuSealed implements ICDoc {
|
|||||||
/** */
|
/** */
|
||||||
SINGLETON_INSTANCE;
|
SINGLETON_INSTANCE;
|
||||||
|
|
||||||
private Map<String, Deck> aiDecks;
|
|
||||||
|
|
||||||
private final UiCommand cmdDeckSelect = new UiCommand() {
|
private final UiCommand cmdDeckSelect = new UiCommand() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@@ -93,16 +75,6 @@ public enum CSubmenuSealed implements ICDoc {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void update() {
|
public void update() {
|
||||||
final List<Deck> humanDecks = new ArrayList<Deck>();
|
|
||||||
aiDecks = new HashMap<String, Deck>();
|
|
||||||
|
|
||||||
// Since AI decks are tied directly to the human choice,
|
|
||||||
// they're just mapped in a parallel map and grabbed when the game starts.
|
|
||||||
for (final DeckGroup d : FModel.getDecks().getSealed()) {
|
|
||||||
aiDecks.put(d.getName(), d.getAiDecks().get(0));
|
|
||||||
humanDecks.add(d.getHumanDeck());
|
|
||||||
}
|
|
||||||
|
|
||||||
final VSubmenuSealed view = VSubmenuSealed.SINGLETON_INSTANCE;
|
final VSubmenuSealed view = VSubmenuSealed.SINGLETON_INSTANCE;
|
||||||
view.getLstDecks().setPool(DeckProxy.getAllSealedDecks(FModel.getDecks().getSealed()));
|
view.getLstDecks().setPool(DeckProxy.getAllSealedDecks(FModel.getDecks().getSealed()));
|
||||||
view.getLstDecks().setup(ItemManagerConfig.SEALED_DECKS);
|
view.getLstDecks().setup(ItemManagerConfig.SEALED_DECKS);
|
||||||
@@ -141,81 +113,8 @@ public enum CSubmenuSealed implements ICDoc {
|
|||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private <T extends DeckBase> void setupSealed() {
|
private <T extends DeckBase> void setupSealed() {
|
||||||
final String prompt = "Choose Sealed Deck Format";
|
final DeckGroup sealed = SealedCardPoolGenerator.generateSealedDeck();
|
||||||
final LimitedPoolType poolType = GuiChoose.oneOrNone(prompt, LimitedPoolType.values());
|
if (sealed == null) { return; }
|
||||||
if (poolType == null) { return; }
|
|
||||||
|
|
||||||
SealedCardPoolGenerator sd = new SealedCardPoolGenerator(poolType);
|
|
||||||
if (sd.isEmpty()) { return; }
|
|
||||||
|
|
||||||
final CardPool humanPool = sd.getCardPool(true);
|
|
||||||
if (humanPool == null) { return; }
|
|
||||||
|
|
||||||
// System.out.println(humanPool);
|
|
||||||
|
|
||||||
// This seems to be limited by the MAX_DRAFT_PLAYERS constant
|
|
||||||
// in DeckGroupSerializer.java. You could create more AI decks
|
|
||||||
// but only the first seven would load. --BBU
|
|
||||||
Integer rounds = GuiChoose.getInteger("How many opponents are you willing to face?", 1, 7);
|
|
||||||
if (rounds == null) { return; }
|
|
||||||
|
|
||||||
final String sDeckName = FOptionPane.showInputDialog(
|
|
||||||
"Save this card pool as:",
|
|
||||||
"Save Card Pool",
|
|
||||||
FOptionPane.QUESTION_ICON);
|
|
||||||
|
|
||||||
if (StringUtils.isBlank(sDeckName)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final Deck deck = new Deck(sDeckName);
|
|
||||||
deck.getOrCreate(DeckSection.Sideboard).addAll(humanPool);
|
|
||||||
|
|
||||||
final int landsCount = 10;
|
|
||||||
|
|
||||||
final boolean isZendikarSet = sd.getLandSetCode().equals("ZEN"); // we want to generate one kind of Zendikar lands at a time only
|
|
||||||
final boolean zendikarSetMode = MyRandom.getRandom().nextBoolean();
|
|
||||||
|
|
||||||
for (final String element : MagicColor.Constant.BASIC_LANDS) {
|
|
||||||
int numArt = FModel.getMagicDb().getCommonCards().getArtCount(element, sd.getLandSetCode());
|
|
||||||
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(element, sd.getLandSetCode(), i, numArt > 1 ? landsCount : 30);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
deck.get(DeckSection.Sideboard).add(element, sd.getLandSetCode(), 30);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final IStorage<DeckGroup> sealedDecks = FModel.getDecks().getSealed();
|
|
||||||
|
|
||||||
if (sealedDecks.contains(sDeckName)) {
|
|
||||||
if (!FOptionPane.showConfirmDialog(
|
|
||||||
"'" + sDeckName + "' already exists. Do you want to replace it?",
|
|
||||||
"Sealed Deck Game Exists")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
sealedDecks.delete(sDeckName);
|
|
||||||
}
|
|
||||||
|
|
||||||
final DeckGroup sealed = new DeckGroup(sDeckName);
|
|
||||||
sealed.setHumanDeck(deck);
|
|
||||||
for (int i = 0; i < rounds; i++) {
|
|
||||||
// Generate other decks for next N opponents
|
|
||||||
final CardPool aiPool = sd.getCardPool(false);
|
|
||||||
if (aiPool == null) { return; }
|
|
||||||
|
|
||||||
sealed.addAiDeck(new SealedDeckBuilder(aiPool.toFlatList()).buildDeck());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rank the AI decks
|
|
||||||
sealed.rankAiDecks(new DeckComparer());
|
|
||||||
|
|
||||||
FModel.getDecks().getSealed().add(sealed);
|
|
||||||
|
|
||||||
final ACEditorBase<? extends InventoryItem, T> editor = (ACEditorBase<? extends InventoryItem, T>) new CEditorLimited(
|
final ACEditorBase<? extends InventoryItem, T> editor = (ACEditorBase<? extends InventoryItem, T>) new CEditorLimited(
|
||||||
FModel.getDecks().getSealed(), FScreen.DECK_EDITOR_SEALED);
|
FModel.getDecks().getSealed(), FScreen.DECK_EDITOR_SEALED);
|
||||||
@@ -232,47 +131,4 @@ public enum CSubmenuSealed implements ICDoc {
|
|||||||
public UiCommand getCommandOnSelect() {
|
public UiCommand getCommandOnSelect() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static class DeckComparer implements java.util.Comparator<Deck> {
|
|
||||||
public double getDraftValue(Deck d) {
|
|
||||||
double value = 0;
|
|
||||||
double divider = 0;
|
|
||||||
|
|
||||||
if (d.getMain().isEmpty()) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
double best = 1.0;
|
|
||||||
|
|
||||||
for (Entry<PaperCard, Integer> kv : d.getMain()) {
|
|
||||||
PaperCard evalCard = kv.getKey();
|
|
||||||
int count = kv.getValue();
|
|
||||||
if (DraftRankCache.getRanking(evalCard.getName(), evalCard.getEdition()) != null) {
|
|
||||||
double add = DraftRankCache.getRanking(evalCard.getName(), evalCard.getEdition());
|
|
||||||
// System.out.println(evalCard.getName() + " is worth " + add);
|
|
||||||
value += add * count;
|
|
||||||
divider += count;
|
|
||||||
if (best > add) {
|
|
||||||
best = add;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (divider == 0 || value == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
value /= divider;
|
|
||||||
|
|
||||||
return (20.0 / (best + (2 * value)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compare(Deck o1, Deck o2) {
|
|
||||||
double delta = getDraftValue(o1) - getDraftValue(o2);
|
|
||||||
if ( delta > 0 ) return 1;
|
|
||||||
if ( delta < 0 ) return -1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,6 +115,11 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
|
|||||||
}
|
}
|
||||||
tabPage.initialize();
|
tabPage.initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//if opening brand new sealed deck, show sideboard (card pool) by default
|
||||||
|
if (editorType == EditorType.Sealed && deck.getMain().isEmpty()) {
|
||||||
|
setSelectedPage(sideboardPage);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public EditorType getEditorType() {
|
public EditorType getEditorType() {
|
||||||
|
|||||||
@@ -38,6 +38,12 @@ public class DraftScreen extends LaunchScreen {
|
|||||||
|
|
||||||
lstDecks.setPool(DeckProxy.getDraftDecks(FModel.getDecks().getDraft()));
|
lstDecks.setPool(DeckProxy.getDraftDecks(FModel.getDecks().getDraft()));
|
||||||
lstDecks.setup(ItemManagerConfig.DRAFT_DECKS);
|
lstDecks.setup(ItemManagerConfig.DRAFT_DECKS);
|
||||||
|
lstDecks.setItemActivateHandler(new FEventHandler() {
|
||||||
|
@Override
|
||||||
|
public void handleEvent(FEvent e) {
|
||||||
|
editSelectedDeck();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
btnNewDraft.setFont(FSkinFont.get(16));
|
btnNewDraft.setFont(FSkinFont.get(16));
|
||||||
btnNewDraft.setCommand(new FEventHandler() {
|
btnNewDraft.setCommand(new FEventHandler() {
|
||||||
@@ -71,14 +77,18 @@ public class DraftScreen extends LaunchScreen {
|
|||||||
btnEditDeck.setCommand(new FEventHandler() {
|
btnEditDeck.setCommand(new FEventHandler() {
|
||||||
@Override
|
@Override
|
||||||
public void handleEvent(FEvent e) {
|
public void handleEvent(FEvent e) {
|
||||||
final DeckProxy deck = lstDecks.getSelectedItem();
|
editSelectedDeck();
|
||||||
if (deck == null) { return; }
|
|
||||||
|
|
||||||
Forge.openScreen(new FDeckEditor(EditorType.Draft, deck.getDeck()));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void editSelectedDeck() {
|
||||||
|
final DeckProxy deck = lstDecks.getSelectedItem();
|
||||||
|
if (deck == null) { return; }
|
||||||
|
|
||||||
|
Forge.openScreen(new FDeckEditor(EditorType.Draft, deck.getDeck()));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doLayoutAboveBtnStart(float startY, float width, float height) {
|
protected void doLayoutAboveBtnStart(float startY, float width, float height) {
|
||||||
float x = ItemFilter.PADDING;
|
float x = ItemFilter.PADDING;
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ public class HomeScreen extends FScreen {
|
|||||||
public void handleEvent(FEvent e) {
|
public void handleEvent(FEvent e) {
|
||||||
Forge.openScreen(new SealedScreen());
|
Forge.openScreen(new SealedScreen());
|
||||||
}
|
}
|
||||||
}, false);
|
}, true);
|
||||||
addButton("Quest Mode", new FEventHandler() {
|
addButton("Quest Mode", new FEventHandler() {
|
||||||
@Override
|
@Override
|
||||||
public void handleEvent(FEvent e) {
|
public void handleEvent(FEvent e) {
|
||||||
|
|||||||
@@ -1,17 +1,91 @@
|
|||||||
package forge.screens.sealed;
|
package forge.screens.sealed;
|
||||||
|
|
||||||
|
import forge.FThreads;
|
||||||
|
import forge.Forge;
|
||||||
|
import forge.assets.FSkinFont;
|
||||||
|
import forge.deck.DeckGroup;
|
||||||
|
import forge.deck.DeckProxy;
|
||||||
|
import forge.deck.FDeckChooser;
|
||||||
|
import forge.deck.FDeckEditor;
|
||||||
|
import forge.deck.FDeckEditor.EditorType;
|
||||||
import forge.game.GameType;
|
import forge.game.GameType;
|
||||||
|
import forge.itemmanager.DeckManager;
|
||||||
|
import forge.itemmanager.ItemManagerConfig;
|
||||||
|
import forge.itemmanager.filters.ItemFilter;
|
||||||
|
import forge.limited.SealedCardPoolGenerator;
|
||||||
|
import forge.model.FModel;
|
||||||
import forge.screens.LaunchScreen;
|
import forge.screens.LaunchScreen;
|
||||||
|
import forge.toolbox.FButton;
|
||||||
|
import forge.toolbox.FEvent;
|
||||||
|
import forge.toolbox.FEvent.FEventHandler;
|
||||||
|
import forge.util.ThreadUtil;
|
||||||
|
|
||||||
public class SealedScreen extends LaunchScreen {
|
public class SealedScreen extends LaunchScreen {
|
||||||
|
private final DeckManager lstDecks = add(new DeckManager(GameType.Draft));
|
||||||
|
private final FButton btnNewDeck = add(new FButton("New Deck"));
|
||||||
|
private final FButton btnEditDeck = add(new FButton("Edit Deck"));
|
||||||
|
|
||||||
public SealedScreen() {
|
public SealedScreen() {
|
||||||
super("Sealed Deck");
|
super("Sealed Deck");
|
||||||
|
|
||||||
|
lstDecks.setPool(DeckProxy.getAllSealedDecks(FModel.getDecks().getSealed()));
|
||||||
|
lstDecks.setup(ItemManagerConfig.SEALED_DECKS);
|
||||||
|
lstDecks.setItemActivateHandler(new FEventHandler() {
|
||||||
|
@Override
|
||||||
|
public void handleEvent(FEvent e) {
|
||||||
|
editSelectedDeck();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
btnNewDeck.setFont(FSkinFont.get(16));
|
||||||
|
btnNewDeck.setCommand(new FEventHandler() {
|
||||||
|
@Override
|
||||||
|
public void handleEvent(FEvent e) {
|
||||||
|
ThreadUtil.invokeInGameThread(new Runnable() { //must run in game thread to prevent blocking UI thread
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
final DeckGroup sealed = SealedCardPoolGenerator.generateSealedDeck();
|
||||||
|
if (sealed == null) { return; }
|
||||||
|
|
||||||
|
FThreads.invokeInEdtLater(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
Forge.openScreen(new FDeckEditor(EditorType.Sealed, sealed.getHumanDeck()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
btnEditDeck.setFont(btnNewDeck.getFont());
|
||||||
|
btnEditDeck.setCommand(new FEventHandler() {
|
||||||
|
@Override
|
||||||
|
public void handleEvent(FEvent e) {
|
||||||
|
editSelectedDeck();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void editSelectedDeck() {
|
||||||
|
final DeckProxy deck = lstDecks.getSelectedItem();
|
||||||
|
if (deck == null) { return; }
|
||||||
|
|
||||||
|
Forge.openScreen(new FDeckEditor(EditorType.Sealed, deck.getDeck()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doLayoutAboveBtnStart(float startY, float width, float height) {
|
protected void doLayoutAboveBtnStart(float startY, float width, float height) {
|
||||||
// TODO Auto-generated method stub
|
float x = ItemFilter.PADDING;
|
||||||
|
float y = startY;
|
||||||
|
float w = width - 2 * x;
|
||||||
|
float buttonWidth = (w - FDeckChooser.PADDING) / 2;
|
||||||
|
float buttonHeight = btnNewDeck.getAutoSizeBounds().height * 1.2f;
|
||||||
|
float listHeight = height - buttonHeight - y - FDeckChooser.PADDING;
|
||||||
|
|
||||||
|
lstDecks.setBounds(x, y, w, listHeight);
|
||||||
|
y += listHeight + FDeckChooser.PADDING;
|
||||||
|
btnNewDeck.setBounds(x, y, buttonWidth, buttonHeight);
|
||||||
|
btnEditDeck.setBounds(x + buttonWidth + FDeckChooser.PADDING, y, buttonWidth, buttonHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ public class FOptionPane extends FDialog {
|
|||||||
inputField = cbInput;
|
inputField = cbInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
final FOptionPane optionPane = new FOptionPane(message, title, icon, inputField, new String[] {"OK", "Cancel"}, -1, new Callback<Integer>() {
|
final FOptionPane optionPane = new FOptionPane(message, title, icon, inputField, new String[] {"OK", "Cancel"}, 0, new Callback<Integer>() {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public void run(Integer result) {
|
public void run(Integer result) {
|
||||||
|
|||||||
@@ -17,27 +17,37 @@
|
|||||||
*/
|
*/
|
||||||
package forge.limited;
|
package forge.limited;
|
||||||
|
|
||||||
|
import forge.assets.FSkinProp;
|
||||||
import forge.card.CardEdition;
|
import forge.card.CardEdition;
|
||||||
import forge.card.IUnOpenedProduct;
|
import forge.card.IUnOpenedProduct;
|
||||||
|
import forge.card.MagicColor;
|
||||||
import forge.card.UnOpenedProduct;
|
import forge.card.UnOpenedProduct;
|
||||||
import forge.deck.CardPool;
|
import forge.deck.CardPool;
|
||||||
|
import forge.deck.Deck;
|
||||||
|
import forge.deck.DeckGroup;
|
||||||
|
import forge.deck.DeckSection;
|
||||||
import forge.item.PaperCard;
|
import forge.item.PaperCard;
|
||||||
import forge.item.SealedProduct;
|
import forge.item.SealedProduct;
|
||||||
import forge.model.CardBlock;
|
import forge.model.CardBlock;
|
||||||
import forge.model.FModel;
|
import forge.model.FModel;
|
||||||
import forge.model.UnOpenedMeta;
|
import forge.model.UnOpenedMeta;
|
||||||
import forge.properties.ForgeConstants;
|
import forge.properties.ForgeConstants;
|
||||||
|
import forge.properties.ForgePreferences.FPref;
|
||||||
import forge.util.FileUtil;
|
import forge.util.FileUtil;
|
||||||
|
import forge.util.MyRandom;
|
||||||
import forge.util.TextUtil;
|
import forge.util.TextUtil;
|
||||||
import forge.util.gui.SGuiChoose;
|
import forge.util.gui.SGuiChoose;
|
||||||
import forge.util.gui.SOptionPane;
|
import forge.util.gui.SOptionPane;
|
||||||
|
import forge.util.storage.IStorage;
|
||||||
|
|
||||||
import org.apache.commons.lang3.ArrayUtils;
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
@@ -56,6 +66,84 @@ public class SealedCardPoolGenerator {
|
|||||||
/** The Land set code. */
|
/** The Land set code. */
|
||||||
private String landSetCode = null;
|
private String landSetCode = null;
|
||||||
|
|
||||||
|
public static DeckGroup generateSealedDeck() {
|
||||||
|
final String prompt = "Choose Sealed Deck Format";
|
||||||
|
final LimitedPoolType poolType = SGuiChoose.oneOrNone(prompt, LimitedPoolType.values());
|
||||||
|
if (poolType == null) { return null; }
|
||||||
|
|
||||||
|
SealedCardPoolGenerator sd = new SealedCardPoolGenerator(poolType);
|
||||||
|
if (sd.isEmpty()) { return null; }
|
||||||
|
|
||||||
|
final CardPool humanPool = sd.getCardPool(true);
|
||||||
|
if (humanPool == null) { return null; }
|
||||||
|
|
||||||
|
// System.out.println(humanPool);
|
||||||
|
|
||||||
|
// This seems to be limited by the MAX_DRAFT_PLAYERS constant
|
||||||
|
// in DeckGroupSerializer.java. You could create more AI decks
|
||||||
|
// but only the first seven would load. --BBU
|
||||||
|
Integer rounds = SGuiChoose.getInteger("How many opponents are you willing to face?", 1, 7);
|
||||||
|
if (rounds == null) { return null; }
|
||||||
|
|
||||||
|
final String sDeckName = SOptionPane.showInputDialog(
|
||||||
|
"Save this card pool as:",
|
||||||
|
"Save Card Pool",
|
||||||
|
FSkinProp.ICO_QUESTION);
|
||||||
|
|
||||||
|
if (StringUtils.isBlank(sDeckName)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final IStorage<DeckGroup> sealedDecks = FModel.getDecks().getSealed();
|
||||||
|
if (sealedDecks.contains(sDeckName)) {
|
||||||
|
if (!SOptionPane.showConfirmDialog(
|
||||||
|
"'" + sDeckName + "' already exists. Do you want to replace it?",
|
||||||
|
"Sealed Deck Game Exists")) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
sealedDecks.delete(sDeckName);
|
||||||
|
}
|
||||||
|
|
||||||
|
final Deck deck = new Deck(sDeckName);
|
||||||
|
deck.getOrCreate(DeckSection.Sideboard).addAll(humanPool);
|
||||||
|
|
||||||
|
final int landsCount = 10;
|
||||||
|
|
||||||
|
final boolean isZendikarSet = sd.getLandSetCode().equals("ZEN"); // we want to generate one kind of Zendikar lands at a time only
|
||||||
|
final boolean zendikarSetMode = MyRandom.getRandom().nextBoolean();
|
||||||
|
|
||||||
|
for (final String element : MagicColor.Constant.BASIC_LANDS) {
|
||||||
|
int numArt = FModel.getMagicDb().getCommonCards().getArtCount(element, sd.getLandSetCode());
|
||||||
|
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(element, sd.getLandSetCode(), i, numArt > 1 ? landsCount : 30);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
deck.get(DeckSection.Sideboard).add(element, sd.getLandSetCode(), 30);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final DeckGroup sealed = new DeckGroup(sDeckName);
|
||||||
|
sealed.setHumanDeck(deck);
|
||||||
|
for (int i = 0; i < rounds; i++) {
|
||||||
|
// Generate other decks for next N opponents
|
||||||
|
final CardPool aiPool = sd.getCardPool(false);
|
||||||
|
if (aiPool == null) { return null; }
|
||||||
|
|
||||||
|
sealed.addAiDeck(new SealedDeckBuilder(aiPool.toFlatList()).buildDeck());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rank the AI decks
|
||||||
|
sealed.rankAiDecks(new SealedDeckComparer());
|
||||||
|
|
||||||
|
FModel.getDecks().getSealed().add(sealed);
|
||||||
|
return sealed;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* Constructor for SealedDeck.
|
* Constructor for SealedDeck.
|
||||||
@@ -64,7 +152,7 @@ public class SealedCardPoolGenerator {
|
|||||||
* @param poolType
|
* @param poolType
|
||||||
* a {@link java.lang.String} object.
|
* a {@link java.lang.String} object.
|
||||||
*/
|
*/
|
||||||
public SealedCardPoolGenerator(final LimitedPoolType poolType) {
|
private SealedCardPoolGenerator(final LimitedPoolType poolType) {
|
||||||
switch(poolType) {
|
switch(poolType) {
|
||||||
case Full:
|
case Full:
|
||||||
// Choose number of boosters
|
// Choose number of boosters
|
||||||
@@ -368,4 +456,47 @@ public class SealedCardPoolGenerator {
|
|||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
return product.isEmpty();
|
return product.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class SealedDeckComparer implements java.util.Comparator<Deck> {
|
||||||
|
public double getDraftValue(Deck d) {
|
||||||
|
double value = 0;
|
||||||
|
double divider = 0;
|
||||||
|
|
||||||
|
if (d.getMain().isEmpty()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
double best = 1.0;
|
||||||
|
|
||||||
|
for (Entry<PaperCard, Integer> kv : d.getMain()) {
|
||||||
|
PaperCard evalCard = kv.getKey();
|
||||||
|
int count = kv.getValue();
|
||||||
|
if (DraftRankCache.getRanking(evalCard.getName(), evalCard.getEdition()) != null) {
|
||||||
|
double add = DraftRankCache.getRanking(evalCard.getName(), evalCard.getEdition());
|
||||||
|
// System.out.println(evalCard.getName() + " is worth " + add);
|
||||||
|
value += add * count;
|
||||||
|
divider += count;
|
||||||
|
if (best > add) {
|
||||||
|
best = add;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (divider == 0 || value == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
value /= divider;
|
||||||
|
|
||||||
|
return (20.0 / (best + (2 * value)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compare(Deck o1, Deck o2) {
|
||||||
|
double delta = getDraftValue(o1) - getDraftValue(o2);
|
||||||
|
if ( delta > 0 ) return 1;
|
||||||
|
if ( delta < 0 ) return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user