mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 04:08:01 +00:00
Merge branch 'ldaarchetypedeckgenerationchanges' into 'master'
Archetype based deck generation See merge request core-developers/forge!625
This commit is contained in:
@@ -164,7 +164,7 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
|
|||||||
private void updateMatrix(GameFormat format) {
|
private void updateMatrix(GameFormat format) {
|
||||||
lstDecks.setAllowMultipleSelections(false);
|
lstDecks.setAllowMultipleSelections(false);
|
||||||
|
|
||||||
lstDecks.setPool(CardThemedDeckGenerator.getMatrixDecks(format, isAi));
|
lstDecks.setPool(ArchetypeDeckGenerator.getMatrixDecks(format, isAi));
|
||||||
lstDecks.setup(ItemManagerConfig.STRING_ONLY);
|
lstDecks.setup(ItemManagerConfig.STRING_ONLY);
|
||||||
|
|
||||||
btnRandom.setText("Random");
|
btnRandom.setText("Random");
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import com.badlogic.gdx.math.Rectangle;
|
|||||||
import forge.Forge;
|
import forge.Forge;
|
||||||
import forge.Graphics;
|
import forge.Graphics;
|
||||||
import forge.assets.FSkinImage;
|
import forge.assets.FSkinImage;
|
||||||
|
import forge.deck.ArchetypeDeckGenerator;
|
||||||
import forge.deck.CardThemedDeckGenerator;
|
import forge.deck.CardThemedDeckGenerator;
|
||||||
import forge.deck.CommanderDeckGenerator;
|
import forge.deck.CommanderDeckGenerator;
|
||||||
import forge.deck.DeckProxy;
|
import forge.deck.DeckProxy;
|
||||||
@@ -131,6 +132,8 @@ public class CardZoom extends FOverlay {
|
|||||||
return CardView.getCardForUi(((CardThemedDeckGenerator)item).getPaperCard());
|
return CardView.getCardForUi(((CardThemedDeckGenerator)item).getPaperCard());
|
||||||
}else if (item instanceof CommanderDeckGenerator){
|
}else if (item instanceof CommanderDeckGenerator){
|
||||||
return CardView.getCardForUi(((CommanderDeckGenerator)item).getPaperCard());
|
return CardView.getCardForUi(((CommanderDeckGenerator)item).getPaperCard());
|
||||||
|
}else if (item instanceof ArchetypeDeckGenerator){
|
||||||
|
return CardView.getCardForUi(((ArchetypeDeckGenerator)item).getPaperCard());
|
||||||
}else{
|
}else{
|
||||||
DeckProxy deck = ((DeckProxy)item);
|
DeckProxy deck = ((DeckProxy)item);
|
||||||
return new CardView(-1, null, deck.getName(), null, deck.getImageKey(false));
|
return new CardView(-1, null, deck.getName(), null, deck.getImageKey(false));
|
||||||
|
|||||||
@@ -654,7 +654,7 @@ public class FDeckChooser extends FScreen {
|
|||||||
maxSelections = 1;
|
maxSelections = 1;
|
||||||
pool= new ArrayList<>();
|
pool= new ArrayList<>();
|
||||||
if(FModel.isdeckGenMatrixLoaded()) {
|
if(FModel.isdeckGenMatrixLoaded()) {
|
||||||
pool = CardThemedDeckGenerator.getMatrixDecks(FModel.getFormats().getStandard(), isAi);
|
pool = ArchetypeDeckGenerator.getMatrixDecks(FModel.getFormats().getStandard(), isAi);
|
||||||
}
|
}
|
||||||
config = ItemManagerConfig.STRING_ONLY;
|
config = ItemManagerConfig.STRING_ONLY;
|
||||||
break;
|
break;
|
||||||
@@ -662,7 +662,7 @@ public class FDeckChooser extends FScreen {
|
|||||||
maxSelections = 1;
|
maxSelections = 1;
|
||||||
pool= new ArrayList<>();
|
pool= new ArrayList<>();
|
||||||
if(FModel.isdeckGenMatrixLoaded()) {
|
if(FModel.isdeckGenMatrixLoaded()) {
|
||||||
pool = CardThemedDeckGenerator.getMatrixDecks(FModel.getFormats().getModern(), isAi);
|
pool = ArchetypeDeckGenerator.getMatrixDecks(FModel.getFormats().getModern(), isAi);
|
||||||
}
|
}
|
||||||
config = ItemManagerConfig.STRING_ONLY;
|
config = ItemManagerConfig.STRING_ONLY;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -11,10 +11,7 @@ import forge.assets.ImageCache;
|
|||||||
import forge.card.CardRenderer;
|
import forge.card.CardRenderer;
|
||||||
import forge.card.CardRenderer.CardStackPosition;
|
import forge.card.CardRenderer.CardStackPosition;
|
||||||
import forge.card.CardZoom;
|
import forge.card.CardZoom;
|
||||||
import forge.deck.CardThemedDeckGenerator;
|
import forge.deck.*;
|
||||||
import forge.deck.CommanderDeckGenerator;
|
|
||||||
import forge.deck.DeckProxy;
|
|
||||||
import forge.deck.FDeckViewer;
|
|
||||||
import forge.item.InventoryItem;
|
import forge.item.InventoryItem;
|
||||||
import forge.item.PaperCard;
|
import forge.item.PaperCard;
|
||||||
import forge.itemmanager.ColumnDef;
|
import forge.itemmanager.ColumnDef;
|
||||||
@@ -864,7 +861,8 @@ public class ImageView<T extends InventoryItem> extends ItemView<T> {
|
|||||||
public boolean longPress(float x, float y) {
|
public boolean longPress(float x, float y) {
|
||||||
ItemInfo item = getItemAtPoint(x + getLeft(), y + getTop());
|
ItemInfo item = getItemAtPoint(x + getLeft(), y + getTop());
|
||||||
if (item != null) {
|
if (item != null) {
|
||||||
if(item.getKey() instanceof CardThemedDeckGenerator || item.getKey() instanceof CommanderDeckGenerator){
|
if(item.getKey() instanceof CardThemedDeckGenerator || item.getKey() instanceof CommanderDeckGenerator
|
||||||
|
|| item.getKey() instanceof ArchetypeDeckGenerator){
|
||||||
FDeckViewer.show(((DeckProxy)item.getKey()).getDeck());
|
FDeckViewer.show(((DeckProxy)item.getKey()).getDeck());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
BIN
forge-gui/res/deckgendecks/Modern.raw.dat
Normal file
BIN
forge-gui/res/deckgendecks/Modern.raw.dat
Normal file
Binary file not shown.
Binary file not shown.
BIN
forge-gui/res/deckgendecks/Standard.raw.dat
Normal file
BIN
forge-gui/res/deckgendecks/Standard.raw.dat
Normal file
Binary file not shown.
@@ -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<ArchetypeDeckGenerator> {
|
||||||
|
public static List<DeckProxy> getMatrixDecks(GameFormat format, boolean isForAi){
|
||||||
|
final List<DeckProxy> decks = new ArrayList<DeckProxy>();
|
||||||
|
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<String, Double> 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<PaperCard> cardFilter = Predicates.and(format.getFilterPrinted(),PaperCard.Predicates.name(name));
|
||||||
|
List<PaperCard> cards=FModel.getMagicDb().getCommonCards().getAllCards(cardFilter);
|
||||||
|
return cards.get(cards.size()-1).getImageKey(altState);*/
|
||||||
|
return card.getImageKey(altState);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PaperCard getPaperCard(){
|
||||||
|
return card;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package forge.deck;
|
package forge.deck;
|
||||||
|
|
||||||
import forge.StaticData;
|
import forge.StaticData;
|
||||||
|
import forge.deck.io.Archetype;
|
||||||
import forge.deck.io.CardThemedLDAIO;
|
import forge.deck.io.CardThemedLDAIO;
|
||||||
import forge.game.GameFormat;
|
import forge.game.GameFormat;
|
||||||
import forge.model.FModel;
|
import forge.model.FModel;
|
||||||
@@ -15,6 +16,7 @@ import java.util.*;
|
|||||||
public final class CardArchetypeLDAGenerator {
|
public final class CardArchetypeLDAGenerator {
|
||||||
|
|
||||||
public static Map<String, Map<String,List<List<Pair<String, Double>>>>> ldaPools = new HashMap();
|
public static Map<String, Map<String,List<List<Pair<String, Double>>>>> ldaPools = new HashMap();
|
||||||
|
public static Map<String, List<Archetype>> ldaArchetypes = new HashMap<>();
|
||||||
|
|
||||||
|
|
||||||
public static boolean initialize(){
|
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 **/
|
/** Try to load matrix .dat files, otherwise check for deck folders and build .dat, otherwise return false **/
|
||||||
public static boolean initializeFormat(String format){
|
public static boolean initializeFormat(String format){
|
||||||
|
List<Archetype> lda = CardThemedLDAIO.loadRawLDA(format);
|
||||||
Map<String,List<List<Pair<String, Double>>>> formatMap = CardThemedLDAIO.loadLDA(format);
|
Map<String,List<List<Pair<String, Double>>>> formatMap = CardThemedLDAIO.loadLDA(format);
|
||||||
if(formatMap==null) {
|
if(formatMap==null) {
|
||||||
try {
|
try {
|
||||||
List<List<Pair<String, Double>>> lda = CardThemedLDAIO.loadRawLDA(format);
|
|
||||||
formatMap = loadFormat(lda);
|
formatMap = loadFormat(lda);
|
||||||
CardThemedLDAIO.saveLDA(format, formatMap);
|
CardThemedLDAIO.saveLDA(format, formatMap);
|
||||||
}catch (Exception e){
|
}catch (Exception e){
|
||||||
@@ -45,17 +47,18 @@ public final class CardArchetypeLDAGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ldaPools.put(format, formatMap);
|
ldaPools.put(format, formatMap);
|
||||||
|
ldaArchetypes.put(format, lda);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Map<String,List<List<Pair<String, Double>>>> loadFormat(List<List<Pair<String, Double>>> lda) throws Exception{
|
public static Map<String,List<List<Pair<String, Double>>>> loadFormat(List<Archetype> lda) throws Exception{
|
||||||
|
|
||||||
List<List<Pair<String, Double>>> topics = new ArrayList<>();
|
List<List<Pair<String, Double>>> topics = new ArrayList<>();
|
||||||
Set<String> cards = new HashSet<String>();
|
Set<String> cards = new HashSet<String>();
|
||||||
for (int t = 0; t < lda.size(); ++t) {
|
for (int t = 0; t < lda.size(); ++t) {
|
||||||
List<Pair<String, Double>> topic = new ArrayList<>();
|
List<Pair<String, Double>> topic = new ArrayList<>();
|
||||||
Set<String> topicCards = new HashSet<>();
|
Set<String> topicCards = new HashSet<>();
|
||||||
List<Pair<String, Double>> highRankVocabs = lda.get(t);
|
List<Pair<String, Double>> highRankVocabs = lda.get(t).getCardProbabilities();
|
||||||
if (highRankVocabs.get(0).getRight()<=0.01d){
|
if (highRankVocabs.get(0).getRight()<=0.01d){
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ public enum DeckType {
|
|||||||
PRECONSTRUCTED_DECK("Preconstructed Decks"),
|
PRECONSTRUCTED_DECK("Preconstructed Decks"),
|
||||||
QUEST_OPPONENT_DECK ("Quest Opponent Decks"),
|
QUEST_OPPONENT_DECK ("Quest Opponent Decks"),
|
||||||
COLOR_DECK ("Random Color Decks"),
|
COLOR_DECK ("Random Color Decks"),
|
||||||
STANDARD_CARDGEN_DECK ("Random Standard Card-themed Decks"),
|
STANDARD_CARDGEN_DECK ("Random Standard Archetype Decks"),
|
||||||
MODERN_CARDGEN_DECK ("Random Modern Card-themed Decks"),
|
MODERN_CARDGEN_DECK ("Random Modern Archetype Decks"),
|
||||||
STANDARD_COLOR_DECK ("Random Standard Color Decks"),
|
STANDARD_COLOR_DECK ("Random Standard Color Decks"),
|
||||||
MODERN_COLOR_DECK ("Random Modern Color Decks"),
|
MODERN_COLOR_DECK ("Random Modern Color Decks"),
|
||||||
THEME_DECK ("Random Theme Decks"),
|
THEME_DECK ("Random Theme Decks"),
|
||||||
@@ -36,9 +36,9 @@ public enum DeckType {
|
|||||||
DeckType.PRECONSTRUCTED_DECK,
|
DeckType.PRECONSTRUCTED_DECK,
|
||||||
DeckType.QUEST_OPPONENT_DECK,
|
DeckType.QUEST_OPPONENT_DECK,
|
||||||
DeckType.COLOR_DECK,
|
DeckType.COLOR_DECK,
|
||||||
DeckType.STANDARD_COLOR_DECK,
|
|
||||||
DeckType.STANDARD_CARDGEN_DECK,
|
DeckType.STANDARD_CARDGEN_DECK,
|
||||||
DeckType.MODERN_CARDGEN_DECK,
|
DeckType.MODERN_CARDGEN_DECK,
|
||||||
|
DeckType.STANDARD_COLOR_DECK,
|
||||||
DeckType.MODERN_COLOR_DECK,
|
DeckType.MODERN_COLOR_DECK,
|
||||||
DeckType.THEME_DECK,
|
DeckType.THEME_DECK,
|
||||||
DeckType.RANDOM_DECK,
|
DeckType.RANDOM_DECK,
|
||||||
|
|||||||
@@ -13,10 +13,12 @@ import forge.card.ColorSet;
|
|||||||
import forge.card.mana.ManaCost;
|
import forge.card.mana.ManaCost;
|
||||||
import forge.card.mana.ManaCostShard;
|
import forge.card.mana.ManaCostShard;
|
||||||
import forge.deck.generation.*;
|
import forge.deck.generation.*;
|
||||||
|
import forge.deck.io.Archetype;
|
||||||
import forge.game.GameFormat;
|
import forge.game.GameFormat;
|
||||||
import forge.game.GameType;
|
import forge.game.GameType;
|
||||||
import forge.item.PaperCard;
|
import forge.item.PaperCard;
|
||||||
import forge.itemmanager.IItemManager;
|
import forge.itemmanager.IItemManager;
|
||||||
|
import forge.limited.ArchetypeDeckBuilder;
|
||||||
import forge.limited.CardThemedCommanderDeckBuilder;
|
import forge.limited.CardThemedCommanderDeckBuilder;
|
||||||
import forge.limited.CardThemedConquestDeckBuilder;
|
import forge.limited.CardThemedConquestDeckBuilder;
|
||||||
import forge.limited.CardThemedDeckBuilder;
|
import forge.limited.CardThemedDeckBuilder;
|
||||||
@@ -70,48 +72,6 @@ public class DeckgenUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Take two lists of cards with counts of each and combine the second into the first by adding a mean normalized fraction
|
|
||||||
* of the count in the second list to the first list.
|
|
||||||
* @param cards1
|
|
||||||
* @param cards2
|
|
||||||
*/
|
|
||||||
public static void combineDistances(List<Map.Entry<PaperCard,Integer>> cards1,List<Map.Entry<PaperCard,Integer>> cards2){
|
|
||||||
Float secondListWeighting=0.4f;
|
|
||||||
Integer maxDistance=0;
|
|
||||||
for (Map.Entry<PaperCard,Integer> pair1:cards1){
|
|
||||||
maxDistance=maxDistance+pair1.getValue();
|
|
||||||
}
|
|
||||||
maxDistance=maxDistance/cards1.size();
|
|
||||||
Integer maxDistance2=0;
|
|
||||||
for (Map.Entry<PaperCard,Integer> pair2:cards2){
|
|
||||||
maxDistance2=maxDistance2+pair2.getValue();
|
|
||||||
}
|
|
||||||
maxDistance2=maxDistance2/cards2.size();
|
|
||||||
for (Map.Entry<PaperCard,Integer> pair2:cards2){
|
|
||||||
boolean isCardPresent=false;
|
|
||||||
for (Map.Entry<PaperCard,Integer> pair1:cards1){
|
|
||||||
if (pair1.getKey().equals(pair2.getKey())){
|
|
||||||
pair1.setValue(pair1.getValue()+new Float((pair2.getValue()*secondListWeighting*maxDistance/maxDistance2)).intValue());
|
|
||||||
isCardPresent=true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!isCardPresent){
|
|
||||||
Map.Entry<PaperCard,Integer> newEntry=new AbstractMap.SimpleEntry<PaperCard, Integer>(pair2.getKey(),new Float((pair2.getValue()*0.4*maxDistance/maxDistance2)).intValue());
|
|
||||||
cards1.add(newEntry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class CardDistanceComparator implements Comparator<Map.Entry<PaperCard,Integer>>
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public int compare(Map.Entry<PaperCard,Integer> index1, Map.Entry<PaperCard,Integer> index2)
|
|
||||||
{
|
|
||||||
return index1.getValue().compareTo(index2.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Deck buildPlanarConquestDeck(PaperCard card, GameFormat format, DeckFormat deckFormat){
|
public static Deck buildPlanarConquestDeck(PaperCard card, GameFormat format, DeckFormat deckFormat){
|
||||||
return buildPlanarConquestDeck(card, null, format, deckFormat, false);
|
return buildPlanarConquestDeck(card, null, format, deckFormat, false);
|
||||||
@@ -239,11 +199,96 @@ public class DeckgenUtil {
|
|||||||
if(deck.getMain().countAll()!=60){
|
if(deck.getMain().countAll()!=60){
|
||||||
System.out.println(deck.getMain().countAll());
|
System.out.println(deck.getMain().countAll());
|
||||||
System.out.println("Wrong card count "+deck.getMain().countAll());
|
System.out.println("Wrong card count "+deck.getMain().countAll());
|
||||||
deck=buildCardGenDeck(format,isForAI);
|
deck=buildLDACArchetypeDeck(format,isForAI);
|
||||||
}
|
}
|
||||||
if(deck.getMain().countAll(Predicates.compose(CardRulesPredicates.Presets.IS_LAND, PaperCard.FN_GET_RULES))>27){
|
if(deck.getMain().countAll(Predicates.compose(CardRulesPredicates.Presets.IS_LAND, PaperCard.FN_GET_RULES))>27){
|
||||||
System.out.println("Too many lands "+deck.getMain().countAll(Predicates.compose(CardRulesPredicates.Presets.IS_LAND, PaperCard.FN_GET_RULES)));
|
System.out.println("Too many lands "+deck.getMain().countAll(Predicates.compose(CardRulesPredicates.Presets.IS_LAND, PaperCard.FN_GET_RULES)));
|
||||||
deck=buildCardGenDeck(format,isForAI);
|
deck=buildLDACArchetypeDeck(format,isForAI);
|
||||||
|
}
|
||||||
|
while(deck.get(DeckSection.Sideboard).countAll()>15){
|
||||||
|
deck.get(DeckSection.Sideboard).remove(deck.get(DeckSection.Sideboard).get(0));
|
||||||
|
}
|
||||||
|
return deck;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static Deck buildLDACArchetypeDeck(GameFormat format, boolean isForAI){
|
||||||
|
List<Archetype> keys = new ArrayList<>(CardArchetypeLDAGenerator.ldaArchetypes.get(format.getName()));
|
||||||
|
Archetype randomKey = keys.get( MyRandom.getRandom().nextInt(keys.size()) );
|
||||||
|
return buildLDACArchetypeDeck(randomKey,format,isForAI);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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<Pair<String, Double>> preSelectedCardNames = archetype.getCardProbabilities();
|
||||||
|
PaperCard card = StaticData.instance().getCommonCards().getUniqueByName(preSelectedCardNames.get(0).getLeft());
|
||||||
|
List<PaperCard> selectedCards = new ArrayList<>();
|
||||||
|
for(Pair<String, Double> 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<PaperCard> 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<PaperCard> 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;j<keyCardCount;++j) {
|
||||||
|
playsetList.add(card);
|
||||||
|
}
|
||||||
|
for (PaperCard c:selectedCards){
|
||||||
|
for(int j=0;j<4;++j) {
|
||||||
|
if(MyRandom.getRandom().nextInt(100)<90) {
|
||||||
|
playsetList.add(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//build deck from combined list
|
||||||
|
ArchetypeDeckBuilder dBuilder = new ArchetypeDeckBuilder(archetype, card, playsetList,format,isForAI);
|
||||||
|
Deck deck = dBuilder.buildDeck();
|
||||||
|
if(deck.getMain().countAll()!=60){
|
||||||
|
System.out.println(deck.getMain().countAll());
|
||||||
|
System.out.println("Wrong card count "+deck.getMain().countAll());
|
||||||
|
deck=buildLDACArchetypeDeck(format,isForAI);
|
||||||
|
}
|
||||||
|
if(deck.getMain().countAll(Predicates.compose(CardRulesPredicates.Presets.IS_LAND, PaperCard.FN_GET_RULES))>27){
|
||||||
|
System.out.println("Too many lands "+deck.getMain().countAll(Predicates.compose(CardRulesPredicates.Presets.IS_LAND, PaperCard.FN_GET_RULES)));
|
||||||
|
deck=buildLDACArchetypeDeck(format,isForAI);
|
||||||
}
|
}
|
||||||
while(deck.get(DeckSection.Sideboard).countAll()>15){
|
while(deck.get(DeckSection.Sideboard).countAll()>15){
|
||||||
deck.get(DeckSection.Sideboard).remove(deck.get(DeckSection.Sideboard).get(0));
|
deck.get(DeckSection.Sideboard).remove(deck.get(DeckSection.Sideboard).get(0));
|
||||||
|
|||||||
@@ -101,9 +101,9 @@ public class RandomDeckGenerator extends DeckProxy implements Comparable<RandomD
|
|||||||
}
|
}
|
||||||
return DeckgenUtil.buildColorDeck(colors, null, isAi);
|
return DeckgenUtil.buildColorDeck(colors, null, isAi);
|
||||||
case STANDARD_CARDGEN_DECK:
|
case STANDARD_CARDGEN_DECK:
|
||||||
return DeckgenUtil.buildCardGenDeck(FModel.getFormats().getStandard(),isAi);
|
return DeckgenUtil.buildLDACArchetypeDeck(FModel.getFormats().getStandard(),isAi);
|
||||||
case MODERN_CARDGEN_DECK:
|
case MODERN_CARDGEN_DECK:
|
||||||
return DeckgenUtil.buildCardGenDeck(FModel.getFormats().getModern(),isAi);
|
return DeckgenUtil.buildLDACArchetypeDeck(FModel.getFormats().getModern(),isAi);
|
||||||
case STANDARD_COLOR_DECK:
|
case STANDARD_COLOR_DECK:
|
||||||
colors = new ArrayList<String>();
|
colors = new ArrayList<String>();
|
||||||
count = Aggregates.randomInt(1, 3);
|
count = Aggregates.randomInt(1, 3);
|
||||||
|
|||||||
43
forge-gui/src/main/java/forge/deck/io/Archetype.java
Normal file
43
forge-gui/src/main/java/forge/deck/io/Archetype.java
Normal file
@@ -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<Pair<String, Double>> cardProbabilities;
|
||||||
|
private String name;
|
||||||
|
private Integer deckCount;
|
||||||
|
|
||||||
|
public Archetype(List<Pair<String, Double>> cardProbabilities, String name, Integer deckCount){
|
||||||
|
this.cardProbabilities = cardProbabilities;
|
||||||
|
this.name = name;
|
||||||
|
this.deckCount = deckCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Pair<String, Double>> getCardProbabilities() {
|
||||||
|
return cardProbabilities;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCardProbabilities(List<Pair<String, Double>> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,7 +19,7 @@ public class CardThemedLDAIO {
|
|||||||
public static final String SUFFIX_DATA = ".lda.dat";
|
public static final String SUFFIX_DATA = ".lda.dat";
|
||||||
public static final String RAW_SUFFIX_DATA = ".raw.dat";
|
public static final String RAW_SUFFIX_DATA = ".raw.dat";
|
||||||
|
|
||||||
public static void saveRawLDA(String format, List<List<Pair<String, Double>>> lda){
|
public static void saveRawLDA(String format, List<Archetype> lda){
|
||||||
File file = getRAWLDAFile(format);
|
File file = getRAWLDAFile(format);
|
||||||
ObjectOutputStream s = null;
|
ObjectOutputStream s = null;
|
||||||
try {
|
try {
|
||||||
@@ -40,11 +40,11 @@ public class CardThemedLDAIO {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<List<Pair<String, Double>>> loadRawLDA(String format){
|
public static List<Archetype> loadRawLDA(String format){
|
||||||
try {
|
try {
|
||||||
FileInputStream fin = new FileInputStream(getRAWLDAFile(format));
|
FileInputStream fin = new FileInputStream(getRAWLDAFile(format));
|
||||||
ObjectInputStream s = new ObjectInputStream(fin);
|
ObjectInputStream s = new ObjectInputStream(fin);
|
||||||
List<List<Pair<String, Double>>> matrix = (List<List<Pair<String, Double>>>) s.readObject();
|
List<Archetype> matrix = (List<Archetype>) s.readObject();
|
||||||
s.close();
|
s.close();
|
||||||
return matrix;
|
return matrix;
|
||||||
}catch (Exception e){
|
}catch (Exception e){
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ public class GauntletUtil {
|
|||||||
deck = DeckgenUtil.getRandomColorDeck(FModel.getFormats().getStandard().getFilterPrinted(),true);
|
deck = DeckgenUtil.getRandomColorDeck(FModel.getFormats().getStandard().getFilterPrinted(),true);
|
||||||
break;
|
break;
|
||||||
case STANDARD_CARDGEN_DECK:
|
case STANDARD_CARDGEN_DECK:
|
||||||
deck = DeckgenUtil.buildCardGenDeck(FModel.getFormats().getStandard(),true);
|
deck = DeckgenUtil.buildLDACArchetypeDeck(FModel.getFormats().getStandard(),true);
|
||||||
break;
|
break;
|
||||||
case MODERN_CARDGEN_DECK:
|
case MODERN_CARDGEN_DECK:
|
||||||
deck = DeckgenUtil.buildCardGenDeck(FModel.getFormats().getModern(),true);
|
deck = DeckgenUtil.buildLDACArchetypeDeck(FModel.getFormats().getModern(),true);
|
||||||
break;
|
break;
|
||||||
case MODERN_COLOR_DECK:
|
case MODERN_COLOR_DECK:
|
||||||
deck = DeckgenUtil.getRandomColorDeck(FModel.getFormats().getModern().getFilterPrinted(),true);
|
deck = DeckgenUtil.getRandomColorDeck(FModel.getFormats().getModern().getFilterPrinted(),true);
|
||||||
|
|||||||
@@ -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<PaperCard> 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";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user