diff --git a/src/main/java/forge/Constant.java b/src/main/java/forge/Constant.java
index 3c2c7b40238..50bad5332e6 100644
--- a/src/main/java/forge/Constant.java
+++ b/src/main/java/forge/Constant.java
@@ -26,8 +26,6 @@ import java.util.Map;
import com.google.common.collect.ImmutableList;
-import forge.card.MagicColor;
-
/**
*
* Constant interface.
diff --git a/src/main/java/forge/deck/generate/Generate2ColorDeck.java b/src/main/java/forge/deck/generate/Generate2ColorDeck.java
index 1e71bb96eea..758a1be7931 100644
--- a/src/main/java/forge/deck/generate/Generate2ColorDeck.java
+++ b/src/main/java/forge/deck/generate/Generate2ColorDeck.java
@@ -17,9 +17,11 @@
*/
package forge.deck.generate;
-import java.util.Arrays;
import java.util.List;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import com.google.common.collect.Lists;
+
import forge.card.ColorSet;
import forge.card.MagicColor;
import forge.deck.generate.GenerateDeckUtil.FilterCMC;
@@ -40,12 +42,13 @@ public class Generate2ColorDeck extends GenerateColoredDeckBase {
@Override protected final float getCreatPercentage() { return 0.36f; }
@Override protected final float getSpellPercentage() { return 0.25f; }
- final List cmcLevels = Arrays.asList(
- new GenerateDeckUtil.FilterCMC(0, 2),
- new GenerateDeckUtil.FilterCMC(3, 4),
- new GenerateDeckUtil.FilterCMC(5, 6),
- new GenerateDeckUtil.FilterCMC(7, 20));
- final int[] cmcAmounts = {10, 8, 6, 2};
+ @SuppressWarnings("unchecked")
+ final List> cmcRelativeWeights = Lists.newArrayList(
+ ImmutablePair.of(new GenerateDeckUtil.FilterCMC(0, 2), 6),
+ ImmutablePair.of(new GenerateDeckUtil.FilterCMC(3, 4), 4),
+ ImmutablePair.of(new GenerateDeckUtil.FilterCMC(5, 6), 2),
+ ImmutablePair.of(new GenerateDeckUtil.FilterCMC(7, 20), 1)
+ );
// mana curve of the card pool
// 20x 0 - 2
@@ -77,15 +80,14 @@ public class Generate2ColorDeck extends GenerateColoredDeckBase {
public final ItemPoolView getDeck(final int size, final PlayerType pt) {
- addCreaturesAndSpells(size, cmcLevels, cmcAmounts, pt);
+ addCreaturesAndSpells(size, cmcRelativeWeights, pt);
// Add lands
- int numLands = (int) (getLandsPercentage() * size);
-
- tmpDeck.append("numLands:").append(numLands).append("\n");
+ int numLands = Math.round(size * getLandsPercentage());
+ adjustDeckSize(size - numLands);
+ tmpDeck.append(String.format("Adjusted deck size to: %d, should add %d land(s)%n", size - numLands, numLands));
// Add dual lands
-
List duals = GenerateDeckUtil.getDualLandList(colors);
for (String s : duals) {
this.cardCounts.put(s, 0);
@@ -96,10 +98,9 @@ public class Generate2ColorDeck extends GenerateColoredDeckBase {
addBasicLand(numLands);
tmpDeck.append("DeckSize:").append(tDeck.countAll()).append("\n");
-
- adjustDeckSize(size);
- tmpDeck.append("DeckSize:").append(tDeck.countAll()).append("\n");
-
+
+ //System.out.println(tmpDeck.toString());
+
return tDeck;
}
}
diff --git a/src/main/java/forge/deck/generate/Generate3ColorDeck.java b/src/main/java/forge/deck/generate/Generate3ColorDeck.java
index bc1e7c7aac6..9ac2e06c879 100644
--- a/src/main/java/forge/deck/generate/Generate3ColorDeck.java
+++ b/src/main/java/forge/deck/generate/Generate3ColorDeck.java
@@ -17,9 +17,12 @@
*/
package forge.deck.generate;
-import java.util.Arrays;
import java.util.List;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+
+import com.google.common.collect.Lists;
+
import forge.card.ColorSet;
import forge.card.MagicColor;
import forge.deck.generate.GenerateDeckUtil.FilterCMC;
@@ -36,11 +39,12 @@ import forge.item.ItemPoolView;
* @version $Id$
*/
public class Generate3ColorDeck extends GenerateColoredDeckBase {
- final List cmcLevels = Arrays.asList(
- new GenerateDeckUtil.FilterCMC(0, 2),
- new GenerateDeckUtil.FilterCMC(3, 5),
- new GenerateDeckUtil.FilterCMC(6, 20));
- final int[] cmcAmounts = {12, 9, 3};
+ @SuppressWarnings("unchecked")
+ final List> cmcLevels = Lists.newArrayList(
+ ImmutablePair.of(new GenerateDeckUtil.FilterCMC(0, 2), 12),
+ ImmutablePair.of(new GenerateDeckUtil.FilterCMC(3, 5), 9),
+ ImmutablePair.of(new GenerateDeckUtil.FilterCMC(6, 20), 3)
+ );
/**
*
@@ -76,28 +80,24 @@ public class Generate3ColorDeck extends GenerateColoredDeckBase {
* @return a {@link forge.CardList} object.
*/
public final ItemPoolView getDeck(final int size, final PlayerType pt) {
- addCreaturesAndSpells(size, cmcLevels, cmcAmounts, pt);
+ addCreaturesAndSpells(size, cmcLevels, pt);
// Add lands
- int numLands = (int) (getLandsPercentage() * size);
-
+ int numLands = Math.round(size * getLandsPercentage());
+ adjustDeckSize(size - numLands);
tmpDeck.append("numLands:").append(numLands).append("\n");
// Add dual lands
-
List duals = GenerateDeckUtil.getDualLandList(colors);
for (String s : duals) {
this.cardCounts.put(s, 0);
}
+
int dblsAdded = addSomeStr((numLands / 4), duals);
numLands -= dblsAdded;
addBasicLand(numLands);
tmpDeck.append("DeckSize:").append(tDeck.countAll()).append("\n");
-
- adjustDeckSize(size);
- tmpDeck.append("DeckSize:").append(tDeck.countAll()).append("\n");
-
return tDeck;
}
}
diff --git a/src/main/java/forge/deck/generate/Generate5ColorDeck.java b/src/main/java/forge/deck/generate/Generate5ColorDeck.java
index 10f9475517e..852c966a692 100644
--- a/src/main/java/forge/deck/generate/Generate5ColorDeck.java
+++ b/src/main/java/forge/deck/generate/Generate5ColorDeck.java
@@ -17,9 +17,12 @@
*/
package forge.deck.generate;
-import java.util.Arrays;
import java.util.List;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+
+import com.google.common.collect.Lists;
+
import forge.card.ColorSet;
import forge.deck.generate.GenerateDeckUtil.FilterCMC;
import forge.game.player.PlayerType;
@@ -35,11 +38,12 @@ import forge.item.ItemPoolView;
* @version $Id$
*/
public class Generate5ColorDeck extends GenerateColoredDeckBase {
- final List cmcLevels = Arrays.asList(
- new GenerateDeckUtil.FilterCMC(0, 2),
- new GenerateDeckUtil.FilterCMC(3, 5),
- new GenerateDeckUtil.FilterCMC(6, 20));
- final int[] cmcAmounts = {15, 10, 5};
+ @SuppressWarnings("unchecked")
+ final List> cmcLevels = Lists.newArrayList(
+ ImmutablePair.of(new GenerateDeckUtil.FilterCMC(0, 2), 3),
+ ImmutablePair.of(new GenerateDeckUtil.FilterCMC(3, 5), 2),
+ ImmutablePair.of(new GenerateDeckUtil.FilterCMC(6, 20), 1)
+ );
// resulting mana curve of the card pool
// 30x 0 - 2
@@ -66,28 +70,24 @@ public class Generate5ColorDeck extends GenerateColoredDeckBase {
* @return a {@link forge.CardList} object.
*/
public final ItemPoolView getDeck(final int size, final PlayerType pt) {
- addCreaturesAndSpells(size, cmcLevels, cmcAmounts, pt);
+ addCreaturesAndSpells(size, cmcLevels, pt);
// Add lands
- int numLands = (int) (getLandsPercentage() * size);
-
+ int numLands = Math.round(size * getLandsPercentage());
+ adjustDeckSize(size - numLands);
tmpDeck.append("numLands:").append(numLands).append("\n");
// Add dual lands
-
List duals = GenerateDeckUtil.getDualLandList(colors);
for (String s : duals) {
this.cardCounts.put(s, 0);
}
+
int dblsAdded = addSomeStr((numLands / 4), duals);
numLands -= dblsAdded;
addBasicLand(numLands);
tmpDeck.append("DeckSize:").append(tDeck.countAll()).append("\n");
-
- adjustDeckSize(size);
- tmpDeck.append("DeckSize:").append(tDeck.countAll()).append("\n");
-
return tDeck;
}
}
diff --git a/src/main/java/forge/deck/generate/GenerateColoredDeckBase.java b/src/main/java/forge/deck/generate/GenerateColoredDeckBase.java
index 138366f0b18..f01c7d3a939 100644
--- a/src/main/java/forge/deck/generate/GenerateColoredDeckBase.java
+++ b/src/main/java/forge/deck/generate/GenerateColoredDeckBase.java
@@ -17,7 +17,6 @@
*/
package forge.deck.generate;
-import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -25,9 +24,12 @@ import java.util.Map.Entry;
import java.util.Random;
import java.util.TreeMap;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
import forge.Constant;
import forge.Singletons;
@@ -73,20 +75,24 @@ public abstract class GenerateColoredDeckBase {
tDeck = new ItemPool(CardPrinted.class);
}
- protected void addCreaturesAndSpells(int size, List cmcLevels, int[] cmcAmounts, PlayerType pt) {
+ protected void addCreaturesAndSpells(int size, List> cmcLevels, PlayerType pt) {
+ tmpDeck.append("Building deck of ").append(size).append("cards\n");
+
final Iterable cards = selectCardsOfMatchingColorForPlayer(pt);
// build subsets based on type
final Iterable creatures = Iterables.filter(cards, Predicates.compose(CardRulesPredicates.Presets.IS_CREATURE, CardPrinted.FN_GET_RULES));
- final int creatCnt = (int) (getCreatPercentage() * size);
- tmpDeck.append("Creature Count:").append(creatCnt).append("\n");
- addCmcAdjusted(creatures, creatCnt, cmcLevels, cmcAmounts);
+ final int creatCnt = (int) Math.ceil(getCreatPercentage() * size);
+ tmpDeck.append("Creatures to add:").append(creatCnt).append("\n");
+ addCmcAdjusted(creatures, creatCnt, cmcLevels);
Predicate preSpells = Predicates.compose(CardRulesPredicates.Presets.IS_NONCREATURE_SPELL_FOR_GENERATOR, CardPrinted.FN_GET_RULES);
final Iterable spells = Iterables.filter(cards, preSpells);
- final int spellCnt = (int) (getSpellPercentage() * size);
- tmpDeck.append("Spell Count:").append(spellCnt).append("\n");
- addCmcAdjusted(spells, spellCnt, cmcLevels, cmcAmounts);
+ final int spellCnt = (int) Math.ceil(getSpellPercentage() * size);
+ tmpDeck.append("Spells to add:").append(spellCnt).append("\n");
+ addCmcAdjusted(spells, spellCnt, cmcLevels);
+
+ tmpDeck.append(String.format("Current deck size: %d... should be %f%n", tDeck.countAll(), size * (getCreatPercentage() + getSpellPercentage())));
}
public ItemPoolView getDeck(final int size, final PlayerType pt) {
@@ -97,19 +103,22 @@ public abstract class GenerateColoredDeckBase {
for (int i = 0; i < cnt; i++) {
CardPrinted cp;
int lc = 0;
+ int srcLen = source.size();
do {
- cp = source.get(this.r.nextInt(source.size()));
+ cp = source.get(this.r.nextInt(srcLen));
lc++;
- } while ((this.cardCounts.get(cp.getName()) > (this.maxDuplicates - 1)) && (lc <= 100));
+ } while (this.cardCounts.get(cp.getName()) > this.maxDuplicates - 1 && lc <= 100);
if (lc > 100) {
throw new RuntimeException("Generate2ColorDeck : get2ColorDeck -- looped too much -- Cr12");
}
- tDeck.add(CardDb.instance().getCard(cp.getName(), Aggregates.random(cp.getRules().getSets())));
+ tDeck.add(cp);
final int n = this.cardCounts.get(cp.getName());
this.cardCounts.put(cp.getName(), n + 1);
- tmpDeck.append(cp.getName() + " " + cp.getRules().getManaCost() + "\n");
+ if( n + 1 == this.maxDuplicates )
+ source.remove(cp);
+ tmpDeck.append(String.format("(%d) %s [%s]%n", cp.getRules().getManaCost().getCMC(), cp.getName(), cp.getRules().getManaCost()));
}
}
@@ -136,6 +145,8 @@ public abstract class GenerateColoredDeckBase {
}
protected void addBasicLand(int cnt) {
+ tmpDeck.append(cnt).append(" basic lands remain").append("\n");
+
// attempt to optimize basic land counts according to colors of picked cards
final Map clrCnts = countLands(tDeck);
// total of all ClrCnts
@@ -147,24 +158,23 @@ public abstract class GenerateColoredDeckBase {
tmpDeck.append("totalColor:").append(totalColor).append("\n");
+ int landsLeft = cnt;
for (Entry c : clrCnts.entrySet()) {
String color = c.getKey();
// calculate number of lands for each color
- float p = (float) c.getValue() / totalColor;
- final int nLand = (int) (cnt * p);
+ final int nLand = Math.min(landsLeft, Math.round(cnt * c.getValue() / totalColor));
tmpDeck.append("nLand-").append(color).append(":").append(nLand).append("\n");
- // just to prevent a null exception by the deck size fixing
- // code
+ // just to prevent a null exception by the deck size fixing code
this.cardCounts.put(color, nLand);
CardPrinted cp = CardDb.instance().getCard(color);
String basicLandSet = Aggregates.random(cp.getRules().getSets());
- for (int j = 0; j <= nLand; j++) {
- tDeck.add(CardDb.instance().getCard(cp.getName(), basicLandSet));
- }
+
+ tDeck.add(CardDb.instance().getCard(cp.getName(), basicLandSet), nLand);
+ landsLeft -= nLand;
}
}
@@ -191,19 +201,34 @@ public abstract class GenerateColoredDeckBase {
}
}
- protected void addCmcAdjusted(Iterable source, int cnt, List cmcLevels, int[] cmcAmounts) {
- final List curved = new ArrayList();
-
- for (int i = 0; i < cmcAmounts.length; i++) {
- Iterable matchingCards = Iterables.filter(source, Predicates.compose(cmcLevels.get(i), CardPrinted.FN_GET_RULES));
- curved.addAll(Aggregates.random(matchingCards, cmcAmounts[i]));
+ protected void addCmcAdjusted(Iterable source, int cnt, List> cmcLevels) {
+ int totalWeight = 0;
+ for (ImmutablePair pair : cmcLevels) {
+ totalWeight += pair.getRight();
}
+
+ float variability = 0.6f; // if set to 1, you'll get minimum cards to choose from
+ float desiredWeight = (float)cnt / ( maxDuplicates * variability );
+ float desiredOverTotal = desiredWeight / totalWeight;
+ float requestedOverTotal = (float)cnt / totalWeight;
+
+ for (ImmutablePair pair : cmcLevels) {
+ Iterable matchingCards = Iterables.filter(source, Predicates.compose(pair.getLeft(), CardPrinted.FN_GET_RULES));
+ int cmcCountForPool = (int) Math.ceil(pair.getRight().intValue() * desiredOverTotal);
+
+ int addOfThisCmc = Math.round(pair.getRight().intValue() * requestedOverTotal);
+ tmpDeck.append(String.format("Adding %d cards for cmc range from a pool with %d cards:%n", addOfThisCmc, cmcCountForPool));
- for (CardPrinted c : curved) {
- this.cardCounts.put(c.getName(), 0);
+ final List curved = Aggregates.random(matchingCards, cmcCountForPool);
+ final List curvedRandomized = Lists.newArrayList();
+ for (CardPrinted c : curved) {
+ this.cardCounts.put(c.getName(), 0);
+ CardPrinted cpRandomSet = CardDb.instance().getCard(c.getName(), Aggregates.random(c.getRules().getSets()));
+ curvedRandomized.add(cpRandomSet);
+ }
+
+ addSome(addOfThisCmc, curvedRandomized);
}
-
- addSome(cnt, curved);
}
protected Iterable selectCardsOfMatchingColorForPlayer(PlayerType pt) {
diff --git a/src/main/java/forge/deck/generate/GenerateDeckUtil.java b/src/main/java/forge/deck/generate/GenerateDeckUtil.java
index 92df4b962dc..5ec67aa3194 100644
--- a/src/main/java/forge/deck/generate/GenerateDeckUtil.java
+++ b/src/main/java/forge/deck/generate/GenerateDeckUtil.java
@@ -58,7 +58,7 @@ public class GenerateDeckUtil {
@Override
public boolean apply(CardRules c) {
ManaCost mc = c.getManaCost();
- return mc.getColorProfile() == 0 && !mc.isNoCost();
+ return c.getColorIdentity().isColorless() && !mc.isNoCost();
}
};
@@ -72,7 +72,8 @@ public class GenerateDeckUtil {
@Override
public boolean apply(CardRules subject) {
ManaCost mc = subject.getManaCost();
- return !mc.isPureGeneric() && mc.canBePaidWithAvaliable(allowedColor);
+ return !mc.isPureGeneric() && allowedColor.containsAllColorsFrom(subject.getColorIdentity().getColor());
+ //return mc.canBePaidWithAvaliable(allowedColor);
// return allowedColor.containsAllColorsFrom(mc.getColorProfile());
}
}
diff --git a/src/main/java/forge/deck/generate/GenerateMonoColorDeck.java b/src/main/java/forge/deck/generate/GenerateMonoColorDeck.java
index 6de68421a63..b395860357d 100644
--- a/src/main/java/forge/deck/generate/GenerateMonoColorDeck.java
+++ b/src/main/java/forge/deck/generate/GenerateMonoColorDeck.java
@@ -17,9 +17,12 @@
*/
package forge.deck.generate;
-import java.util.Arrays;
import java.util.List;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+
+import com.google.common.collect.Lists;
+
import forge.card.ColorSet;
import forge.card.MagicColor;
import forge.deck.generate.GenerateDeckUtil.FilterCMC;
@@ -40,12 +43,13 @@ public class GenerateMonoColorDeck extends GenerateColoredDeckBase {
@Override protected final float getCreatPercentage() { return 0.36f; }
@Override protected final float getSpellPercentage() { return 0.25f; }
- final List cmcLevels = Arrays.asList(
- new GenerateDeckUtil.FilterCMC(0, 2),
- new GenerateDeckUtil.FilterCMC(3, 4),
- new GenerateDeckUtil.FilterCMC(5, 6),
- new GenerateDeckUtil.FilterCMC(7, 20));
- final int[] cmcAmounts = {10, 8, 5, 3};
+ @SuppressWarnings("unchecked")
+ final List> cmcLevels = Lists.newArrayList(
+ ImmutablePair.of(new GenerateDeckUtil.FilterCMC(0, 2), 10),
+ ImmutablePair.of(new GenerateDeckUtil.FilterCMC(3, 4), 8),
+ ImmutablePair.of(new GenerateDeckUtil.FilterCMC(5, 6), 5),
+ ImmutablePair.of(new GenerateDeckUtil.FilterCMC(7, 20), 3)
+ );
// mana curve of the card pool
// 20x 0 - 2
@@ -76,7 +80,7 @@ public class GenerateMonoColorDeck extends GenerateColoredDeckBase {
public final ItemPoolView getDeck(final int size, final PlayerType pt) {
- addCreaturesAndSpells(size, cmcLevels, cmcAmounts, pt);
+ addCreaturesAndSpells(size, cmcLevels, pt);
// Add lands
int numLands = (int) (getLandsPercentage() * size);