diff --git a/forge-gui-desktop/src/main/java/forge/deckchooser/FDeckChooser.java b/forge-gui-desktop/src/main/java/forge/deckchooser/FDeckChooser.java index eaf276bda6d..bba6b83c7e7 100644 --- a/forge-gui-desktop/src/main/java/forge/deckchooser/FDeckChooser.java +++ b/forge-gui-desktop/src/main/java/forge/deckchooser/FDeckChooser.java @@ -164,7 +164,7 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener { private void updateMatrix(GameFormat format) { lstDecks.setAllowMultipleSelections(false); - lstDecks.setPool(CardThemedDeckGenerator.getMatrixDecks(format, isAi)); + lstDecks.setPool(ArchetypeDeckGenerator.getMatrixDecks(format, isAi)); lstDecks.setup(ItemManagerConfig.STRING_ONLY); btnRandom.setText("Random"); diff --git a/forge-gui-mobile/src/forge/deck/FDeckChooser.java b/forge-gui-mobile/src/forge/deck/FDeckChooser.java index 1415085bec7..3b1f48a7369 100644 --- a/forge-gui-mobile/src/forge/deck/FDeckChooser.java +++ b/forge-gui-mobile/src/forge/deck/FDeckChooser.java @@ -654,7 +654,7 @@ public class FDeckChooser extends FScreen { maxSelections = 1; pool= new ArrayList<>(); if(FModel.isdeckGenMatrixLoaded()) { - pool = CardThemedDeckGenerator.getMatrixDecks(FModel.getFormats().getStandard(), isAi); + pool = ArchetypeDeckGenerator.getMatrixDecks(FModel.getFormats().getStandard(), isAi); } config = ItemManagerConfig.STRING_ONLY; break; @@ -662,7 +662,7 @@ public class FDeckChooser extends FScreen { maxSelections = 1; pool= new ArrayList<>(); if(FModel.isdeckGenMatrixLoaded()) { - pool = CardThemedDeckGenerator.getMatrixDecks(FModel.getFormats().getModern(), isAi); + pool = ArchetypeDeckGenerator.getMatrixDecks(FModel.getFormats().getModern(), isAi); } config = ItemManagerConfig.STRING_ONLY; break; diff --git a/forge-gui/res/deckgendecks/Commander.dat b/forge-gui/res/deckgendecks/Commander.dat index a90645d8be5..3177f69e4a3 100644 Binary files a/forge-gui/res/deckgendecks/Commander.dat and b/forge-gui/res/deckgendecks/Commander.dat differ diff --git a/forge-gui/res/deckgendecks/Modern.lda.dat b/forge-gui/res/deckgendecks/Modern.lda.dat index a6f2552a176..3c5e4410aaa 100644 Binary files a/forge-gui/res/deckgendecks/Modern.lda.dat and b/forge-gui/res/deckgendecks/Modern.lda.dat differ diff --git a/forge-gui/res/deckgendecks/Modern.raw.dat b/forge-gui/res/deckgendecks/Modern.raw.dat new file mode 100644 index 00000000000..73b41d43c5a Binary files /dev/null and b/forge-gui/res/deckgendecks/Modern.raw.dat differ diff --git a/forge-gui/res/deckgendecks/Standard.lda.dat b/forge-gui/res/deckgendecks/Standard.lda.dat index 8c62653f5aa..a9abab30922 100644 Binary files a/forge-gui/res/deckgendecks/Standard.lda.dat and b/forge-gui/res/deckgendecks/Standard.lda.dat differ diff --git a/forge-gui/res/deckgendecks/Standard.raw.dat b/forge-gui/res/deckgendecks/Standard.raw.dat new file mode 100644 index 00000000000..3be13759ef7 Binary files /dev/null and b/forge-gui/res/deckgendecks/Standard.raw.dat differ diff --git a/forge-gui/src/main/java/forge/deck/ArchetypeDeckGenerator.java b/forge-gui/src/main/java/forge/deck/ArchetypeDeckGenerator.java new file mode 100644 index 00000000000..74aefb8da64 --- /dev/null +++ b/forge-gui/src/main/java/forge/deck/ArchetypeDeckGenerator.java @@ -0,0 +1,92 @@ +package forge.deck; + +import forge.card.CardEdition; +import forge.deck.io.Archetype; +import forge.game.GameFormat; +import forge.item.PaperCard; +import forge.model.FModel; +import org.apache.commons.lang3.tuple.Pair; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by maustin on 09/05/2017. + */ +public class ArchetypeDeckGenerator extends DeckProxy implements Comparable { + public static List getMatrixDecks(GameFormat format, boolean isForAi){ + final List decks = new ArrayList(); + for(Archetype archetype: CardArchetypeLDAGenerator.ldaArchetypes.get(format.getName())) { + decks.add(new ArchetypeDeckGenerator(archetype, format, isForAi)); + } + + return decks; + } + private final Archetype archetype; + private final int index; + private final GameFormat format; + private final boolean isForAi; + private PaperCard card; + + + private ArchetypeDeckGenerator(Archetype archetype0, GameFormat format0, boolean isForAi0) { + super(); + archetype = archetype0; + index = 0; + format=format0; + isForAi=isForAi0; + for(Pair cardPair : archetype.getCardProbabilities()){ + PaperCard candidate = FModel.getMagicDb().getCommonCards().getUniqueByName(cardPair.getLeft()); + if(!candidate.getRules().getType().isLand()){ + card = candidate; + break; + } + } + } + + public CardEdition getEdition() { + return CardEdition.UNKNOWN; + } + + + @Override + public String getName() { + return archetype.getName(); + } + + @Override + public String toString() { + return archetype.getName(); + } + + public Archetype getArchetype() { + return archetype; + } + + @Override + public int compareTo(final ArchetypeDeckGenerator d) { + return d.getArchetype().getDeckCount().compareTo(archetype.getDeckCount()); + } + + @Override + public Deck getDeck() { + + return DeckgenUtil.buildLDACArchetypeDeck(archetype,format,isForAi); + } + + @Override + public boolean isGeneratedDeck() { + return true; + } + + public String getImageKey(boolean altState) { +/* Predicate cardFilter = Predicates.and(format.getFilterPrinted(),PaperCard.Predicates.name(name)); + List cards=FModel.getMagicDb().getCommonCards().getAllCards(cardFilter); + return cards.get(cards.size()-1).getImageKey(altState);*/ + return card.getImageKey(altState); + } + + public PaperCard getPaperCard(){ + return card; + } +} diff --git a/forge-gui/src/main/java/forge/deck/CardArchetypeLDAGenerator.java b/forge-gui/src/main/java/forge/deck/CardArchetypeLDAGenerator.java index b71b9dee6ad..93c8ff3099a 100644 --- a/forge-gui/src/main/java/forge/deck/CardArchetypeLDAGenerator.java +++ b/forge-gui/src/main/java/forge/deck/CardArchetypeLDAGenerator.java @@ -1,6 +1,7 @@ package forge.deck; import forge.StaticData; +import forge.deck.io.Archetype; import forge.deck.io.CardThemedLDAIO; import forge.game.GameFormat; import forge.model.FModel; @@ -15,6 +16,7 @@ import java.util.*; public final class CardArchetypeLDAGenerator { public static Map>>>> ldaPools = new HashMap(); + public static Map> ldaArchetypes = new HashMap<>(); public static boolean initialize(){ @@ -33,10 +35,10 @@ public final class CardArchetypeLDAGenerator { /** Try to load matrix .dat files, otherwise check for deck folders and build .dat, otherwise return false **/ public static boolean initializeFormat(String format){ + List lda = CardThemedLDAIO.loadRawLDA(format); Map>>> formatMap = CardThemedLDAIO.loadLDA(format); if(formatMap==null) { try { - List>> lda = CardThemedLDAIO.loadRawLDA(format); formatMap = loadFormat(lda); CardThemedLDAIO.saveLDA(format, formatMap); }catch (Exception e){ @@ -45,17 +47,18 @@ public final class CardArchetypeLDAGenerator { } } ldaPools.put(format, formatMap); + ldaArchetypes.put(format, lda); return true; } - public static Map>>> loadFormat(List>> lda) throws Exception{ + public static Map>>> loadFormat(List lda) throws Exception{ List>> topics = new ArrayList<>(); Set cards = new HashSet(); for (int t = 0; t < lda.size(); ++t) { List> topic = new ArrayList<>(); Set topicCards = new HashSet<>(); - List> highRankVocabs = lda.get(t); + List> highRankVocabs = lda.get(t).getCardProbabilities(); if (highRankVocabs.get(0).getRight()<=0.01d){ continue; } diff --git a/forge-gui/src/main/java/forge/deck/DeckType.java b/forge-gui/src/main/java/forge/deck/DeckType.java index 072fbbb88d6..7c9f67d1be0 100644 --- a/forge-gui/src/main/java/forge/deck/DeckType.java +++ b/forge-gui/src/main/java/forge/deck/DeckType.java @@ -17,8 +17,8 @@ public enum DeckType { PRECONSTRUCTED_DECK("Preconstructed Decks"), QUEST_OPPONENT_DECK ("Quest Opponent Decks"), COLOR_DECK ("Random Color Decks"), - STANDARD_CARDGEN_DECK ("Random Standard Card-themed Decks"), - MODERN_CARDGEN_DECK ("Random Modern Card-themed Decks"), + STANDARD_CARDGEN_DECK ("Random Standard Archetype Decks"), + MODERN_CARDGEN_DECK ("Random Modern Archetype Decks"), STANDARD_COLOR_DECK ("Random Standard Color Decks"), MODERN_COLOR_DECK ("Random Modern Color Decks"), THEME_DECK ("Random Theme Decks"), @@ -36,9 +36,9 @@ public enum DeckType { DeckType.PRECONSTRUCTED_DECK, DeckType.QUEST_OPPONENT_DECK, DeckType.COLOR_DECK, - DeckType.STANDARD_COLOR_DECK, DeckType.STANDARD_CARDGEN_DECK, DeckType.MODERN_CARDGEN_DECK, + DeckType.STANDARD_COLOR_DECK, DeckType.MODERN_COLOR_DECK, DeckType.THEME_DECK, DeckType.RANDOM_DECK, diff --git a/forge-gui/src/main/java/forge/deck/DeckgenUtil.java b/forge-gui/src/main/java/forge/deck/DeckgenUtil.java index d3b2ce719f4..67c68bcbc61 100644 --- a/forge-gui/src/main/java/forge/deck/DeckgenUtil.java +++ b/forge-gui/src/main/java/forge/deck/DeckgenUtil.java @@ -13,10 +13,12 @@ import forge.card.ColorSet; import forge.card.mana.ManaCost; import forge.card.mana.ManaCostShard; import forge.deck.generation.*; +import forge.deck.io.Archetype; import forge.game.GameFormat; import forge.game.GameType; import forge.item.PaperCard; import forge.itemmanager.IItemManager; +import forge.limited.ArchetypeDeckBuilder; import forge.limited.CardThemedCommanderDeckBuilder; import forge.limited.CardThemedConquestDeckBuilder; import forge.limited.CardThemedDeckBuilder; @@ -251,6 +253,84 @@ public class DeckgenUtil { return deck; } + + + /** + * Build a deck based on the chosen card. + * + * @param archetype + * @param format + * @param isForAI + * @return + */ + public static Deck buildLDACArchetypeDeck(Archetype archetype, GameFormat format, boolean isForAI){ + List> preSelectedCardNames = archetype.getCardProbabilities(); + PaperCard card = StaticData.instance().getCommonCards().getUniqueByName(preSelectedCardNames.get(0).getLeft()); + List selectedCards = new ArrayList<>(); + for(Pair pair:preSelectedCardNames){ + String name = pair.getLeft(); + PaperCard cardToAdd = StaticData.instance().getCommonCards().getUniqueByName(name); + //for(int i=0; i<1;++i) { + if(!cardToAdd.getName().equals(card.getName())) { + selectedCards.add(cardToAdd); + } + //} + } + + List toRemove = new ArrayList<>(); + + //randomly remove cards + int removeCount=0; + int i=0; + for(PaperCard c:selectedCards){ + if(MyRandom.getRandom().nextInt(100)>70+(15-(i/selectedCards.size())*selectedCards.size()) && removeCount<4 //randomly remove some cards - more likely as distance increases + &&!c.getName().contains("Urza")){ //avoid breaking Tron decks + toRemove.add(c); + removeCount++; + } + if(c.getName().equals(card.getName())){//may have been added in secondary list + toRemove.add(c); + } + ++i; + } + selectedCards.removeAll(toRemove); + //Add keycard + List playsetList = new ArrayList<>(); + int keyCardCount=4; + if(card.getRules().getMainPart().getManaCost().getCMC()>7){ + keyCardCount=1+MyRandom.getRandom().nextInt(4); + }else if(card.getRules().getMainPart().getManaCost().getCMC()>5){ + keyCardCount=2+MyRandom.getRandom().nextInt(3); + } + for(int j=0;j27){ + System.out.println("Too many lands "+deck.getMain().countAll(Predicates.compose(CardRulesPredicates.Presets.IS_LAND, PaperCard.FN_GET_RULES))); + deck=buildCardGenDeck(format,isForAI); + } + while(deck.get(DeckSection.Sideboard).countAll()>15){ + deck.get(DeckSection.Sideboard).remove(deck.get(DeckSection.Sideboard).get(0)); + } + return deck; + } + /** * @param selection {@link java.lang.String} array * @return {@link forge.deck.Deck} diff --git a/forge-gui/src/main/java/forge/deck/io/Archetype.java b/forge-gui/src/main/java/forge/deck/io/Archetype.java new file mode 100644 index 00000000000..454c216ea03 --- /dev/null +++ b/forge-gui/src/main/java/forge/deck/io/Archetype.java @@ -0,0 +1,43 @@ +package forge.deck.io; + +import org.apache.commons.lang3.tuple.Pair; + +import java.io.Serializable; +import java.util.List; + +public class Archetype implements Serializable { + + private List> cardProbabilities; + private String name; + private Integer deckCount; + + public Archetype(List> cardProbabilities, String name, Integer deckCount){ + this.cardProbabilities = cardProbabilities; + this.name = name; + this.deckCount = deckCount; + } + + public List> getCardProbabilities() { + return cardProbabilities; + } + + public void setCardProbabilities(List> cardProbabilities) { + this.cardProbabilities = cardProbabilities; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getDeckCount() { + return deckCount; + } + + public void setDeckCount(Integer deckCount) { + this.deckCount = deckCount; + } +} diff --git a/forge-gui/src/main/java/forge/deck/io/CardThemedLDAIO.java b/forge-gui/src/main/java/forge/deck/io/CardThemedLDAIO.java index ad711e78a26..b05ae41f57a 100644 --- a/forge-gui/src/main/java/forge/deck/io/CardThemedLDAIO.java +++ b/forge-gui/src/main/java/forge/deck/io/CardThemedLDAIO.java @@ -19,7 +19,7 @@ public class CardThemedLDAIO { public static final String SUFFIX_DATA = ".lda.dat"; public static final String RAW_SUFFIX_DATA = ".raw.dat"; - public static void saveRawLDA(String format, List>> lda){ + public static void saveRawLDA(String format, List lda){ File file = getRAWLDAFile(format); ObjectOutputStream s = null; try { @@ -40,11 +40,11 @@ public class CardThemedLDAIO { } } - public static List>> loadRawLDA(String format){ + public static List loadRawLDA(String format){ try { FileInputStream fin = new FileInputStream(getRAWLDAFile(format)); ObjectInputStream s = new ObjectInputStream(fin); - List>> matrix = (List>>) s.readObject(); + List matrix = (List) s.readObject(); s.close(); return matrix; }catch (Exception e){ diff --git a/forge-gui/src/main/java/forge/limited/ArchetypeDeckBuilder.java b/forge-gui/src/main/java/forge/limited/ArchetypeDeckBuilder.java new file mode 100644 index 00000000000..4802d1d3f1c --- /dev/null +++ b/forge-gui/src/main/java/forge/limited/ArchetypeDeckBuilder.java @@ -0,0 +1,28 @@ +package forge.limited; + +import forge.deck.DeckFormat; +import forge.deck.io.Archetype; +import forge.game.GameFormat; +import forge.item.PaperCard; + +import java.util.List; + +public class ArchetypeDeckBuilder extends CardThemedDeckBuilder{ + + private Archetype archetype; + + public ArchetypeDeckBuilder(Archetype archetype0, PaperCard keyCard0, final List dList, GameFormat format, boolean isForAI){ + super(keyCard0,null, dList, format, isForAI, DeckFormat.Constructed); + archetype = archetype0; + } + + /** + * Generate a descriptive name. + * + * @return name + */ + protected String generateName() { + return archetype.getName() + " generated deck"; + } + +}