Improvements and extensions to Card based random deck generator. Now randomly picks a second keycard to build the deck around too. Also I have now included all non-AI playable decks in the model (the AI still excludes the non-AI playables from the decks it builds). There are now 10x more decks in the model including the latest decks from pro tour AKH. The format of the .dat files has now changed - so these new dat files need to be redeployed if you are manually installing on Android.

This commit is contained in:
austinio7116
2017-05-17 08:23:47 +00:00
parent 1bc868c0c9
commit dde9f064ab
13 changed files with 183 additions and 57 deletions

View File

@@ -153,7 +153,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)); lstDecks.setPool(CardThemedDeckGenerator.getMatrixDecks(format, isAi));
lstDecks.setup(ItemManagerConfig.STRING_ONLY); lstDecks.setup(ItemManagerConfig.STRING_ONLY);
btnRandom.setText("Random"); btnRandom.setText("Random");

View File

@@ -118,8 +118,8 @@ public class FDeckViewer extends FDialog {
} }
}); });
final int width = 800; final int width = 1920;
final int height = 600; final int height = 1080;
this.setPreferredSize(new Dimension(width, height)); this.setPreferredSize(new Dimension(width, height));
this.setSize(width, height); this.setSize(width, height);

View File

@@ -601,12 +601,12 @@ public class FDeckChooser extends FScreen {
break; break;
case STANDARD_CARDGEN_DECK: case STANDARD_CARDGEN_DECK:
maxSelections = 1; maxSelections = 1;
pool = CardThemedDeckGenerator.getMatrixDecks(FModel.getFormats().getStandard()); pool = CardThemedDeckGenerator.getMatrixDecks(FModel.getFormats().getStandard(), isAi);
config = ItemManagerConfig.STRING_ONLY; config = ItemManagerConfig.STRING_ONLY;
break; break;
case MODERN_CARDGEN_DECK: case MODERN_CARDGEN_DECK:
maxSelections = 1; maxSelections = 1;
pool = CardThemedDeckGenerator.getMatrixDecks(FModel.getFormats().getModern()); pool = CardThemedDeckGenerator.getMatrixDecks(FModel.getFormats().getModern(), isAi);
config = ItemManagerConfig.STRING_ONLY; config = ItemManagerConfig.STRING_ONLY;
break; break;
case MODERN_COLOR_DECK: case MODERN_COLOR_DECK:

View File

@@ -22,12 +22,12 @@ import java.util.*;
*/ */
public final class CardRelationMatrixGenerator { public final class CardRelationMatrixGenerator {
public static HashMap<GameFormat,HashMap<String,List<PaperCard>>> cardPools = new HashMap<>(); public static HashMap<GameFormat,HashMap<String,List<Map.Entry<PaperCard,Integer>>>> cardPools = new HashMap<>();
public static void initialize(){ public static void initialize(){
HashMap<String,List<PaperCard>> standardMap = CardThemedMatrixIO.loadMatrix(FModel.getFormats().getStandard()); HashMap<String,List<Map.Entry<PaperCard,Integer>>> standardMap = CardThemedMatrixIO.loadMatrix(FModel.getFormats().getStandard());
HashMap<String,List<PaperCard>> modernMap = CardThemedMatrixIO.loadMatrix(FModel.getFormats().getModern()); HashMap<String,List<Map.Entry<PaperCard,Integer>>> modernMap = CardThemedMatrixIO.loadMatrix(FModel.getFormats().getModern());
if(standardMap==null || modernMap==null){ if(standardMap==null || modernMap==null){
reInitialize(); reInitialize();
return; return;
@@ -40,12 +40,12 @@ public final class CardRelationMatrixGenerator {
cardPools.put(FModel.getFormats().getStandard(),initializeFormat(FModel.getFormats().getStandard())); cardPools.put(FModel.getFormats().getStandard(),initializeFormat(FModel.getFormats().getStandard()));
cardPools.put(FModel.getFormats().getModern(),initializeFormat(FModel.getFormats().getModern())); cardPools.put(FModel.getFormats().getModern(),initializeFormat(FModel.getFormats().getModern()));
for(GameFormat format:cardPools.keySet()){ for(GameFormat format:cardPools.keySet()){
HashMap<String,List<PaperCard>> map = cardPools.get(format); HashMap<String,List<Map.Entry<PaperCard,Integer>>> map = cardPools.get(format);
CardThemedMatrixIO.saveMatrix(format,map); CardThemedMatrixIO.saveMatrix(format,map);
} }
} }
public static HashMap<String,List<PaperCard>> initializeFormat(GameFormat format){ public static HashMap<String,List<Map.Entry<PaperCard,Integer>>> initializeFormat(GameFormat format){
IStorage<Deck> decks = new StorageImmediatelySerialized<Deck>("Generator", new DeckStorage(new File(ForgeConstants.DECK_GEN_DIR+ForgeConstants.PATH_SEPARATOR+format.getName()), IStorage<Deck> decks = new StorageImmediatelySerialized<Deck>("Generator", new DeckStorage(new File(ForgeConstants.DECK_GEN_DIR+ForgeConstants.PATH_SEPARATOR+format.getName()),
ForgeConstants.DECK_GEN_DIR, false), ForgeConstants.DECK_GEN_DIR, false),
@@ -83,7 +83,7 @@ public final class CardRelationMatrixGenerator {
} }
} }
} }
HashMap<String,List<PaperCard>> cardPools = new HashMap<>(); HashMap<String,List<Map.Entry<PaperCard,Integer>>> cardPools = new HashMap<>();
for (PaperCard card:cardList){ for (PaperCard card:cardList){
int col=cardIntegerMap.get(card.getName()); int col=cardIntegerMap.get(card.getName());
int[] distances = matrix[col]; int[] distances = matrix[col];
@@ -92,21 +92,21 @@ public final class CardRelationMatrixGenerator {
ArrayIndexComparator comparator = new ArrayIndexComparator(ArrayUtils.toObject(distances)); ArrayIndexComparator comparator = new ArrayIndexComparator(ArrayUtils.toObject(distances));
Integer[] indices = comparator.createIndexArray(); Integer[] indices = comparator.createIndexArray();
Arrays.sort(indices, comparator); Arrays.sort(indices, comparator);
List<PaperCard> deckPool=new ArrayList<>(); List<Map.Entry<PaperCard,Integer>> deckPool=new ArrayList<>();
int k=0; int k=0;
boolean isZeroDistance=false; boolean excludeThisCard=false;//if there are too few cards with at least one connection
for (int j=0;j<20;++k){ for (int j=0;j<20;++k){
if(distances[indices[cardList.size()-1-k]]==0){ if(distances[indices[cardList.size()-1-k]]==0){
isZeroDistance=true; excludeThisCard = true;
break; break;
} }
PaperCard cardToAdd=integerCardMap.get(indices[cardList.size()-1-k]); PaperCard cardToAdd=integerCardMap.get(indices[cardList.size()-1-k]);
if(!cardToAdd.getRules().getMainPart().getType().isLand()){//need 15 non-land cards if(!cardToAdd.getRules().getMainPart().getType().isLand()){//need x non-land cards
++j; ++j;
} }
deckPool.add(cardToAdd); deckPool.add(new AbstractMap.SimpleEntry<PaperCard, Integer>(cardToAdd,distances[indices[cardList.size()-1-k]]));
}; };
if(isZeroDistance){ if(excludeThisCard){
continue; continue;
} }
cardPools.put(card.getName(),deckPool); cardPools.put(card.getName(),deckPool);

View File

@@ -10,23 +10,25 @@ import java.util.List;
* Created by maustin on 09/05/2017. * Created by maustin on 09/05/2017.
*/ */
public class CardThemedDeckGenerator extends DeckProxy implements Comparable<CardThemedDeckGenerator> { public class CardThemedDeckGenerator extends DeckProxy implements Comparable<CardThemedDeckGenerator> {
public static List<DeckProxy> getMatrixDecks(GameFormat format){ public static List<DeckProxy> getMatrixDecks(GameFormat format, boolean isForAi){
final List<DeckProxy> decks = new ArrayList<DeckProxy>(); final List<DeckProxy> decks = new ArrayList<DeckProxy>();
for(String card: CardRelationMatrixGenerator.cardPools.get(format).keySet()) { for(String card: CardRelationMatrixGenerator.cardPools.get(format).keySet()) {
decks.add(new CardThemedDeckGenerator(card, format)); decks.add(new CardThemedDeckGenerator(card, format, isForAi));
} }
return decks; return decks;
} }
private final String name; private final String name;
private final int index; private final int index;
private final GameFormat format; private final GameFormat format;
private final boolean isForAi;
private CardThemedDeckGenerator(String cardName, GameFormat format0) { private CardThemedDeckGenerator(String cardName, GameFormat format0, boolean isForAi0) {
super(); super();
name = cardName; name = cardName;
index = 0; index = 0;
format=format0; format=format0;
isForAi=isForAi0;
} }
public CardEdition getEdition() { public CardEdition getEdition() {
@@ -52,7 +54,7 @@ public class CardThemedDeckGenerator extends DeckProxy implements Comparable<Car
@Override @Override
public Deck getDeck() { public Deck getDeck() {
return DeckgenUtil.buildCardGenDeck(name,format); return DeckgenUtil.buildCardGenDeck(name,format,isForAi);
} }
@Override @Override

View File

@@ -4,6 +4,7 @@ import com.google.common.base.Predicate;
import com.google.common.base.Predicates; import com.google.common.base.Predicates;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import forge.card.CardDb; import forge.card.CardDb;
import forge.card.CardRules; import forge.card.CardRules;
import forge.card.CardRulesPredicates; import forge.card.CardRulesPredicates;
@@ -26,10 +27,7 @@ import forge.util.MyRandom;
import forge.util.gui.SOptionPane; import forge.util.gui.SOptionPane;
import forge.util.storage.IStorage; import forge.util.storage.IStorage;
import java.util.ArrayList; import java.util.*;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
/** /**
* Utility collection for various types of decks. * Utility collection for various types of decks.
@@ -41,35 +39,125 @@ import java.util.Random;
// TODO This class can be used for home menu constructed deck generation as well. // TODO This class can be used for home menu constructed deck generation as well.
public class DeckgenUtil { public class DeckgenUtil {
public static Deck buildCardGenDeck(GameFormat format){ public static Deck buildCardGenDeck(GameFormat format, boolean isForAI){
Random random = new Random(); Random random = new Random();
List<String> keys = new ArrayList<>(CardRelationMatrixGenerator.cardPools.get(format).keySet()); List<String> keys = new ArrayList<>(CardRelationMatrixGenerator.cardPools.get(format).keySet());
String randomKey = keys.get( random.nextInt(keys.size()) ); String randomKey = keys.get( random.nextInt(keys.size()) );
Predicate<PaperCard> cardFilter = Predicates.and(format.getFilterPrinted(),PaperCard.Predicates.name(randomKey)); Predicate<PaperCard> cardFilter = Predicates.and(format.getFilterPrinted(),PaperCard.Predicates.name(randomKey));
PaperCard keyCard = FModel.getMagicDb().getCommonCards().getAllCards(cardFilter).get(0); PaperCard keyCard = FModel.getMagicDb().getCommonCards().getAllCards(cardFilter).get(0);
try { try {
return buildCardGenDeck(keyCard,format); return buildCardGenDeck(keyCard,format,isForAI);
}catch (Exception e){ }catch (Exception e){
e.printStackTrace(); e.printStackTrace();
return buildCardGenDeck(format); return buildCardGenDeck(format,isForAI);
} }
} }
public static Deck buildCardGenDeck(String cardName, GameFormat format){ public static Deck buildCardGenDeck(String cardName, GameFormat format, boolean isForAI){
try { try {
Predicate<PaperCard> cardFilter = Predicates.and(format.getFilterPrinted(),PaperCard.Predicates.name(cardName)); Predicate<PaperCard> cardFilter = Predicates.and(format.getFilterPrinted(),PaperCard.Predicates.name(cardName));
return buildCardGenDeck(FModel.getMagicDb().getCommonCards().getAllCards(cardFilter).get(0),format); return buildCardGenDeck(FModel.getMagicDb().getCommonCards().getAllCards(cardFilter).get(0),format,isForAI);
}catch (Exception e){ }catch (Exception e){
e.printStackTrace(); e.printStackTrace();
return buildCardGenDeck(format); return buildCardGenDeck(format,isForAI);
} }
} }
public static Deck buildCardGenDeck(PaperCard card, GameFormat format){ /**
List<PaperCard> selectedCards = new ArrayList<>(); * Take two lists of cards with counts of each and combine the second into the first by adding a mean normalized fraction
selectedCards.addAll(CardRelationMatrixGenerator.cardPools.get(format).get(card.getName())); * of the count in the second list to the first list.
List<PaperCard> toRemove = new ArrayList<>(); * @param cards1
* @param cards2
*/
public static void combineDistances(List<Map.Entry<PaperCard,Integer>> cards1,List<Map.Entry<PaperCard,Integer>> cards2){
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()*0.4*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(pair2);
}
}
}
public static class CardDistanceComparator implements Comparator<Map.Entry<PaperCard,Integer>>
{
@Override
public int compare(Map.Entry<PaperCard,Integer> index1, Map.Entry<PaperCard,Integer> index2)
{
// Autounbox from Integer to int to use as array indexes
return index1.getValue().compareTo(index2.getValue());
}
}
/**
* Build a deck based on the chosen card.
*
* @param card
* @param format
* @param isForAI
* @return
*/
public static Deck buildCardGenDeck(PaperCard card, GameFormat format, boolean isForAI){
List<Map.Entry<PaperCard,Integer>> potentialCards = new ArrayList<>();
potentialCards.addAll(CardRelationMatrixGenerator.cardPools.get(format).get(card.getName()));
Collections.sort(potentialCards,new CardDistanceComparator());
Collections.reverse(potentialCards);
//get second keycard
Random r = new Random(); Random r = new Random();
List<PaperCard> preSelectedCards = new ArrayList<>();
for(Map.Entry<PaperCard,Integer> pair:potentialCards){
preSelectedCards.add(pair.getKey());
}
//filter out land cards and if for AI non-playable cards as potential second key cards
Iterable<PaperCard> preSelectedNonLandCards;
if(isForAI){
preSelectedNonLandCards=Iterables.filter(preSelectedCards,Predicates.and(
Predicates.compose(CardRulesPredicates.IS_KEPT_IN_AI_DECKS, PaperCard.FN_GET_RULES),
Predicates.compose(CardRulesPredicates.Presets.IS_NON_LAND, PaperCard.FN_GET_RULES)));
}else{
preSelectedNonLandCards=Iterables.filter(preSelectedCards,
Predicates.compose(CardRulesPredicates.Presets.IS_NON_LAND, PaperCard.FN_GET_RULES));
}
preSelectedCards= Lists.newArrayList(preSelectedNonLandCards);
//choose a second card randomly from the top 8 cards if possible
int randMax=8;
if(preSelectedCards.size()<randMax){
randMax=preSelectedCards.size();
}
PaperCard secondKeycard = preSelectedCards.get(r.nextInt(randMax));
List<Map.Entry<PaperCard,Integer>> potentialSecondCards = CardRelationMatrixGenerator.cardPools.get(format).get(secondKeycard.getName());
//combine card distances from second key card and re-sort
if(potentialSecondCards !=null && potentialSecondCards.size()>0) {
combineDistances(potentialCards, potentialSecondCards);
Collections.sort(potentialCards, new CardDistanceComparator());
Collections.reverse(potentialCards);
}
List<PaperCard> selectedCards = new ArrayList<>();
for(Map.Entry<PaperCard,Integer> pair:potentialCards){
selectedCards.add(pair.getKey());
}
List<PaperCard> toRemove = new ArrayList<>();
//randomly remove cards //randomly remove cards
int removeCount=0; int removeCount=0;
int i=0; int i=0;
@@ -78,9 +166,16 @@ public class DeckgenUtil {
toRemove.add(c); toRemove.add(c);
removeCount++; removeCount++;
} }
if(c.getName().equals(card.getName())){//may have been added in secondary list
toRemove.add(c);
}
if(c.getName().equals(secondKeycard.getName())){//remove so we can add correct amount
toRemove.add(c);
}
++i; ++i;
} }
selectedCards.removeAll(toRemove); selectedCards.removeAll(toRemove);
//Add keycard
List<PaperCard> playsetList = new ArrayList<>(); List<PaperCard> playsetList = new ArrayList<>();
int keyCardCount=4; int keyCardCount=4;
if(card.getRules().getMainPart().getManaCost().getCMC()>7){ if(card.getRules().getMainPart().getManaCost().getCMC()>7){
@@ -91,6 +186,16 @@ public class DeckgenUtil {
for(int j=0;j<keyCardCount;++j) { for(int j=0;j<keyCardCount;++j) {
playsetList.add(card); playsetList.add(card);
} }
//Add 2nd keycard
int keyCard2Count=4;
if(card.getRules().getMainPart().getManaCost().getCMC()>7){
keyCard2Count=1+r.nextInt(4);
}else if(card.getRules().getMainPart().getManaCost().getCMC()>5){
keyCard2Count=2+r.nextInt(3);
}
for(int j=0;j<keyCard2Count;++j) {
playsetList.add(secondKeycard);
}
for (PaperCard c:selectedCards){ for (PaperCard c:selectedCards){
for(int j=0;j<4;++j) { for(int j=0;j<4;++j) {
if(r.nextInt(100)<90) { if(r.nextInt(100)<90) {
@@ -98,16 +203,18 @@ public class DeckgenUtil {
} }
} }
} }
CardThemedDeckBuilder dBuilder = new CardThemedDeckBuilder(card, playsetList,format);
//build deck from combined list
CardThemedDeckBuilder dBuilder = new CardThemedDeckBuilder(card,secondKeycard, playsetList,format,isForAI);
Deck deck = dBuilder.buildDeck(); Deck deck = dBuilder.buildDeck();
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); deck=buildCardGenDeck(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); deck=buildCardGenDeck(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));

View File

@@ -99,9 +99,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()); return DeckgenUtil.buildCardGenDeck(FModel.getFormats().getStandard(),isAi);
case MODERN_CARDGEN_DECK: case MODERN_CARDGEN_DECK:
return DeckgenUtil.buildCardGenDeck(FModel.getFormats().getModern()); return DeckgenUtil.buildCardGenDeck(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);

View File

@@ -30,7 +30,7 @@ public class CardThemedMatrixIO {
/** suffix for all gauntlet data files */ /** suffix for all gauntlet data files */
public static final String SUFFIX_DATA = ".dat"; public static final String SUFFIX_DATA = ".dat";
public static void saveMatrix(GameFormat format, HashMap<String,List<PaperCard>> map){ public static void saveMatrix(GameFormat format, HashMap<String,List<Map.Entry<PaperCard,Integer>>> map){
File file = getMatrixFile(format); File file = getMatrixFile(format);
ObjectOutputStream s = null; ObjectOutputStream s = null;
try { try {
@@ -51,11 +51,11 @@ public class CardThemedMatrixIO {
} }
} }
public static HashMap<String,List<PaperCard>> loadMatrix(GameFormat format){ public static HashMap<String,List<Map.Entry<PaperCard,Integer>>> loadMatrix(GameFormat format){
try { try {
FileInputStream fin = new FileInputStream(getMatrixFile(format)); FileInputStream fin = new FileInputStream(getMatrixFile(format));
ObjectInputStream s = new ObjectInputStream(fin); ObjectInputStream s = new ObjectInputStream(fin);
HashMap<String, List<PaperCard>> matrix = (HashMap<String, List<PaperCard>>) s.readObject(); HashMap<String, List<Map.Entry<PaperCard,Integer>>> matrix = (HashMap<String, List<Map.Entry<PaperCard,Integer>>>) s.readObject();
s.close(); s.close();
return matrix; return matrix;
}catch (Exception e){ }catch (Exception e){

View File

@@ -33,10 +33,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()); deck = DeckgenUtil.buildCardGenDeck(FModel.getFormats().getStandard(),true);
break; break;
case MODERN_CARDGEN_DECK: case MODERN_CARDGEN_DECK:
deck = DeckgenUtil.buildCardGenDeck(FModel.getFormats().getModern()); deck = DeckgenUtil.buildCardGenDeck(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);

View File

@@ -46,6 +46,7 @@ public class CardThemedDeckBuilder extends DeckGeneratorBase {
protected int landsNeeded = 25; protected int landsNeeded = 25;
protected final PaperCard keyCard; protected final PaperCard keyCard;
protected final PaperCard secondKeyCard;
protected DeckColors deckColors; protected DeckColors deckColors;
protected Predicate<CardRules> hasColor; protected Predicate<CardRules> hasColor;
@@ -71,14 +72,19 @@ public class CardThemedDeckBuilder extends DeckGeneratorBase {
* @param dList * @param dList
* Cards to build the deck from. * Cards to build the deck from.
*/ */
public CardThemedDeckBuilder(PaperCard keyCard0, final List<PaperCard> dList, GameFormat format) { public CardThemedDeckBuilder(PaperCard keyCard0,PaperCard secondKeyCard0, final List<PaperCard> dList, GameFormat format, boolean isForAI) {
super(FModel.getMagicDb().getCommonCards(), DeckFormat.Limited, format.getFilterPrinted()); super(FModel.getMagicDb().getCommonCards(), DeckFormat.Limited, format.getFilterPrinted());
this.availableList = dList; this.availableList = dList;
keyCard=keyCard0; keyCard=keyCard0;
secondKeyCard=secondKeyCard0;
// remove Unplayables // remove Unplayables
if(isForAI) {
final Iterable<PaperCard> playables = Iterables.filter(availableList, final Iterable<PaperCard> playables = Iterables.filter(availableList,
Predicates.compose(CardRulesPredicates.IS_KEPT_IN_AI_DECKS, PaperCard.FN_GET_RULES)); Predicates.compose(CardRulesPredicates.IS_KEPT_IN_AI_DECKS, PaperCard.FN_GET_RULES));
this.aiPlayables = Lists.newArrayList(playables); this.aiPlayables = Lists.newArrayList(playables);
}else{
this.aiPlayables = Lists.newArrayList(availableList);
}
this.availableList.removeAll(aiPlayables); this.availableList.removeAll(aiPlayables);
deckColors = new DeckColors(); deckColors = new DeckColors();
for(PaperCard c:getAiPlayables()){ for(PaperCard c:getAiPlayables()){
@@ -94,6 +100,9 @@ public class CardThemedDeckBuilder extends DeckGeneratorBase {
if(!colors.hasAllColors(keyCard.getRules().getColorIdentity().getColor())){ if(!colors.hasAllColors(keyCard.getRules().getColorIdentity().getColor())){
colors = ColorSet.fromMask(colors.getColor() | keyCard.getRules().getColorIdentity().getColor()); colors = ColorSet.fromMask(colors.getColor() | keyCard.getRules().getColorIdentity().getColor());
} }
if(!colors.hasAllColors(secondKeyCard.getRules().getColorIdentity().getColor())){
colors = ColorSet.fromMask(colors.getColor() | secondKeyCard.getRules().getColorIdentity().getColor());
}
if (logColorsToConsole) { if (logColorsToConsole) {
System.out.println(keyCard.getName()); System.out.println(keyCard.getName());
System.out.println("Pre Colors: " + colors.toEnumSet().toString()); System.out.println("Pre Colors: " + colors.toEnumSet().toString());
@@ -136,6 +145,14 @@ public class CardThemedDeckBuilder extends DeckGeneratorBase {
aiPlayables.removeAll(keyCardList); aiPlayables.removeAll(keyCardList);
rankedColorList.removeAll(keyCardList); rankedColorList.removeAll(keyCardList);
} }
// Add the deck card
if(!secondKeyCard.getRules().getMainPart().getType().isLand()&&!keyCard.getRules().getMainPart().getType().isCreature()) {
Iterable<PaperCard> secondKeyCards = Iterables.filter(aiPlayables,PaperCard.Predicates.name(secondKeyCard.getName()));
final List<PaperCard> keyCardList = Lists.newArrayList(secondKeyCards);
deckList.addAll(keyCardList);
aiPlayables.removeAll(keyCardList);
rankedColorList.removeAll(keyCardList);
}
onColorNonCreatures = Iterables.filter(rankedColorList, onColorNonCreatures = Iterables.filter(rankedColorList,
Predicates.compose(CardRulesPredicates.Presets.IS_NON_CREATURE_SPELL, PaperCard.FN_GET_RULES)); Predicates.compose(CardRulesPredicates.Presets.IS_NON_CREATURE_SPELL, PaperCard.FN_GET_RULES));
// Guava iterables do not copy the collection contents, instead they act // Guava iterables do not copy the collection contents, instead they act
@@ -302,7 +319,7 @@ public class CardThemedDeckBuilder extends DeckGeneratorBase {
* @return name * @return name
*/ */
private String generateName() { private String generateName() {
return keyCard.getName() + " based deck"; return keyCard.getName() + " / " + secondKeyCard.getName() +" based deck";
} }
/** /**
@@ -754,11 +771,11 @@ public class CardThemedDeckBuilder extends DeckGeneratorBase {
rankedColorList.removeAll(keyCardList); rankedColorList.removeAll(keyCardList);
} }
final Map<Integer,Integer> targetCMCs = new HashMap<>(); final Map<Integer,Integer> targetCMCs = new HashMap<>();
targetCMCs.put(1,r.nextInt(5));//2 targetCMCs.put(1,r.nextInt(4)+2);//2
targetCMCs.put(2,r.nextInt(5)+4);//6 targetCMCs.put(2,r.nextInt(5)+5);//6
targetCMCs.put(3,r.nextInt(5)+5);//7 targetCMCs.put(3,r.nextInt(5)+6);//7
targetCMCs.put(4,r.nextInt(5)+2);//4 targetCMCs.put(4,r.nextInt(3)+3);//4
targetCMCs.put(5,r.nextInt(5)+2);//3 targetCMCs.put(5,r.nextInt(3)+3);//3
targetCMCs.put(6,r.nextInt(3)+1);//2 targetCMCs.put(6,r.nextInt(3)+1);//2

View File

@@ -33,10 +33,10 @@ public class TournamentUtil {
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()); deck = DeckgenUtil.buildCardGenDeck(FModel.getFormats().getStandard(),true);
break; break;
case MODERN_CARDGEN_DECK: case MODERN_CARDGEN_DECK:
deck = DeckgenUtil.buildCardGenDeck(FModel.getFormats().getModern()); deck = DeckgenUtil.buildCardGenDeck(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);