From 2c12e12e898207453428f0b795dd21fbad55e4a8 Mon Sep 17 00:00:00 2001 From: austinio7116 Date: Wed, 19 Jun 2019 19:52:08 +0100 Subject: [PATCH] Improved land counts in deck generation to use linear regression to generate land requirements from average CMC - also increased variance of CMC ratios and reduced land count requirements if filtered decks enabled --- .../forge/limited/CardThemedDeckBuilder.java | 48 +++++++++++-------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/forge-gui/src/main/java/forge/limited/CardThemedDeckBuilder.java b/forge-gui/src/main/java/forge/limited/CardThemedDeckBuilder.java index c4ee7b701d4..769e7a34801 100644 --- a/forge-gui/src/main/java/forge/limited/CardThemedDeckBuilder.java +++ b/forge-gui/src/main/java/forge/limited/CardThemedDeckBuilder.java @@ -19,6 +19,7 @@ import forge.game.GameFormat; import forge.item.IPaperCard; import forge.item.PaperCard; import forge.model.FModel; +import forge.properties.ForgePreferences; import forge.util.MyRandom; import java.util.*; @@ -206,22 +207,27 @@ public class CardThemedDeckBuilder extends DeckGeneratorBase { // 5. If there are still on-color cards, and the average cmc is low, add // extras. double avCMC = getAverageCMC(deckList); - int maxCMC = getMaxCMC(deckList); - if (avCMC < 4) { - addLowCMCCard(); - if (targetSize > 60) { - addLowCMCCard(); - } - } - if (avCMC < 3 && maxCMC < 6) { - addLowCMCCard(); - } - if (avCMC < 2.5 && maxCMC < 5) { - addLowCMCCard(); - if (targetSize > 60) { + //calculated required lands based on https://www.channelfireball.com/articles/how-many-lands-do-you-need-to-consistently-hit-your-land-drops/ + float baseLandParameter = 16f; + //reduce landcount if filtered hands enabled + if(FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.FILTERED_HANDS)){ + baseLandParameter--; + } + landsNeeded = new Double((baseLandParameter + 3.14f * avCMC) * targetSize/60f).intValue(); + if (logToConsole) { + System.out.println("Required lands from linear regression : " + avCMC + " cmc, needed: " + landsNeeded); + } + numSpellsNeeded = targetSize-landsNeeded; + int extraCardsToAdd = numSpellsNeeded - deckList.size(); + if (logToConsole) { + System.out.println("Extra cards to add : " + extraCardsToAdd); + } + if(extraCardsToAdd>0){ + for(int i=0; i 0) addCards(onColorCreaturesAndSpells, stillNeeds); stillNeeds = numSpellsNeeded - deckList.size(); @@ -274,12 +283,13 @@ public class CardThemedDeckBuilder extends DeckGeneratorBase { } } - + if (logToConsole) { + System.out.println("Lands needed : " + landsNeeded); + } if (landsNeeded > 0) { addLands(clrCnts); } if (logToConsole) { - System.out.println("Lands needed : " + landsNeeded); System.out.println("Post Lands : " + deckList.size()); } addWastesIfRequired(); @@ -345,8 +355,8 @@ public class CardThemedDeckBuilder extends DeckGeneratorBase { protected void generateTargetCMCs(){ targetCMCs = new HashMap<>(); - targetCMCs.put(1,Math.round((MyRandom.getRandom().nextInt(12)+4)*targetSize/60));//10 - targetCMCs.put(2,Math.round((MyRandom.getRandom().nextInt(16)+8)*targetSize/60));//16 + targetCMCs.put(1,Math.round((MyRandom.getRandom().nextInt(16)+2)*targetSize/60));//10 + targetCMCs.put(2,Math.round((MyRandom.getRandom().nextInt(20)+6)*targetSize/60));//16 targetCMCs.put(3,Math.round((MyRandom.getRandom().nextInt(10)+8)*targetSize/60));//13 targetCMCs.put(4,Math.round((MyRandom.getRandom().nextInt(8)+6)*targetSize/60));//8 targetCMCs.put(5,Math.round((MyRandom.getRandom().nextInt(8)+6)*targetSize/60));//7 @@ -488,7 +498,7 @@ public class CardThemedDeckBuilder extends DeckGeneratorBase { aiPlayables.remove(card); rankedColorList.remove(card); - landsNeeded--; + //landsNeeded--; if (logToConsole) { System.out.println("Low CMC: " + card.getName()); } @@ -681,7 +691,7 @@ public class CardThemedDeckBuilder extends DeckGeneratorBase { float p = (float) clrCnts[i] / (float) totalColor; int nLand = Math.round(landsNeeded * p); // desired truncation to int if (logToConsole) { - System.out.printf("Basics[%s]: %d/%d = %f%% = %d cards%n", MagicColor.Constant.BASIC_LANDS.get(i), clrCnts[i], totalColor, 100*p, nLand); + System.out.printf("Basics[%s]: %d/%d = %f%% = %d cards%n", MagicColor.Constant.BASIC_LANDS.get(i), clrCnts[i], totalColor, 100*p, nLand + 1); } PaperCard snowLand = null;