mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 11:18:01 +00:00
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:
@@ -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");
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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){
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user