mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 04:08:01 +00:00
Deck generation based on color profile, strictly follows profile
cmc curve uses relative weights
This commit is contained in:
@@ -26,8 +26,6 @@ import java.util.Map;
|
|||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
|
||||||
import forge.card.MagicColor;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* Constant interface.
|
* Constant interface.
|
||||||
|
|||||||
@@ -17,9 +17,11 @@
|
|||||||
*/
|
*/
|
||||||
package forge.deck.generate;
|
package forge.deck.generate;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
import forge.card.ColorSet;
|
import forge.card.ColorSet;
|
||||||
import forge.card.MagicColor;
|
import forge.card.MagicColor;
|
||||||
import forge.deck.generate.GenerateDeckUtil.FilterCMC;
|
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 getCreatPercentage() { return 0.36f; }
|
||||||
@Override protected final float getSpellPercentage() { return 0.25f; }
|
@Override protected final float getSpellPercentage() { return 0.25f; }
|
||||||
|
|
||||||
final List<FilterCMC> cmcLevels = Arrays.asList(
|
@SuppressWarnings("unchecked")
|
||||||
new GenerateDeckUtil.FilterCMC(0, 2),
|
final List<ImmutablePair<FilterCMC, Integer>> cmcRelativeWeights = Lists.newArrayList(
|
||||||
new GenerateDeckUtil.FilterCMC(3, 4),
|
ImmutablePair.of(new GenerateDeckUtil.FilterCMC(0, 2), 6),
|
||||||
new GenerateDeckUtil.FilterCMC(5, 6),
|
ImmutablePair.of(new GenerateDeckUtil.FilterCMC(3, 4), 4),
|
||||||
new GenerateDeckUtil.FilterCMC(7, 20));
|
ImmutablePair.of(new GenerateDeckUtil.FilterCMC(5, 6), 2),
|
||||||
final int[] cmcAmounts = {10, 8, 6, 2};
|
ImmutablePair.of(new GenerateDeckUtil.FilterCMC(7, 20), 1)
|
||||||
|
);
|
||||||
|
|
||||||
// mana curve of the card pool
|
// mana curve of the card pool
|
||||||
// 20x 0 - 2
|
// 20x 0 - 2
|
||||||
@@ -77,15 +80,14 @@ public class Generate2ColorDeck extends GenerateColoredDeckBase {
|
|||||||
|
|
||||||
|
|
||||||
public final ItemPoolView<CardPrinted> getDeck(final int size, final PlayerType pt) {
|
public final ItemPoolView<CardPrinted> getDeck(final int size, final PlayerType pt) {
|
||||||
addCreaturesAndSpells(size, cmcLevels, cmcAmounts, pt);
|
addCreaturesAndSpells(size, cmcRelativeWeights, pt);
|
||||||
|
|
||||||
// Add lands
|
// Add lands
|
||||||
int numLands = (int) (getLandsPercentage() * size);
|
int numLands = Math.round(size * getLandsPercentage());
|
||||||
|
adjustDeckSize(size - numLands);
|
||||||
tmpDeck.append("numLands:").append(numLands).append("\n");
|
tmpDeck.append(String.format("Adjusted deck size to: %d, should add %d land(s)%n", size - numLands, numLands));
|
||||||
|
|
||||||
// Add dual lands
|
// Add dual lands
|
||||||
|
|
||||||
List<String> duals = GenerateDeckUtil.getDualLandList(colors);
|
List<String> duals = GenerateDeckUtil.getDualLandList(colors);
|
||||||
for (String s : duals) {
|
for (String s : duals) {
|
||||||
this.cardCounts.put(s, 0);
|
this.cardCounts.put(s, 0);
|
||||||
@@ -97,8 +99,7 @@ public class Generate2ColorDeck extends GenerateColoredDeckBase {
|
|||||||
addBasicLand(numLands);
|
addBasicLand(numLands);
|
||||||
tmpDeck.append("DeckSize:").append(tDeck.countAll()).append("\n");
|
tmpDeck.append("DeckSize:").append(tDeck.countAll()).append("\n");
|
||||||
|
|
||||||
adjustDeckSize(size);
|
//System.out.println(tmpDeck.toString());
|
||||||
tmpDeck.append("DeckSize:").append(tDeck.countAll()).append("\n");
|
|
||||||
|
|
||||||
return tDeck;
|
return tDeck;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,9 +17,12 @@
|
|||||||
*/
|
*/
|
||||||
package forge.deck.generate;
|
package forge.deck.generate;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
import forge.card.ColorSet;
|
import forge.card.ColorSet;
|
||||||
import forge.card.MagicColor;
|
import forge.card.MagicColor;
|
||||||
import forge.deck.generate.GenerateDeckUtil.FilterCMC;
|
import forge.deck.generate.GenerateDeckUtil.FilterCMC;
|
||||||
@@ -36,11 +39,12 @@ import forge.item.ItemPoolView;
|
|||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
public class Generate3ColorDeck extends GenerateColoredDeckBase {
|
public class Generate3ColorDeck extends GenerateColoredDeckBase {
|
||||||
final List<FilterCMC> cmcLevels = Arrays.asList(
|
@SuppressWarnings("unchecked")
|
||||||
new GenerateDeckUtil.FilterCMC(0, 2),
|
final List<ImmutablePair<FilterCMC, Integer>> cmcLevels = Lists.newArrayList(
|
||||||
new GenerateDeckUtil.FilterCMC(3, 5),
|
ImmutablePair.of(new GenerateDeckUtil.FilterCMC(0, 2), 12),
|
||||||
new GenerateDeckUtil.FilterCMC(6, 20));
|
ImmutablePair.of(new GenerateDeckUtil.FilterCMC(3, 5), 9),
|
||||||
final int[] cmcAmounts = {12, 9, 3};
|
ImmutablePair.of(new GenerateDeckUtil.FilterCMC(6, 20), 3)
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
@@ -76,28 +80,24 @@ public class Generate3ColorDeck extends GenerateColoredDeckBase {
|
|||||||
* @return a {@link forge.CardList} object.
|
* @return a {@link forge.CardList} object.
|
||||||
*/
|
*/
|
||||||
public final ItemPoolView<CardPrinted> getDeck(final int size, final PlayerType pt) {
|
public final ItemPoolView<CardPrinted> getDeck(final int size, final PlayerType pt) {
|
||||||
addCreaturesAndSpells(size, cmcLevels, cmcAmounts, pt);
|
addCreaturesAndSpells(size, cmcLevels, pt);
|
||||||
|
|
||||||
// Add lands
|
// Add lands
|
||||||
int numLands = (int) (getLandsPercentage() * size);
|
int numLands = Math.round(size * getLandsPercentage());
|
||||||
|
adjustDeckSize(size - numLands);
|
||||||
tmpDeck.append("numLands:").append(numLands).append("\n");
|
tmpDeck.append("numLands:").append(numLands).append("\n");
|
||||||
|
|
||||||
// Add dual lands
|
// Add dual lands
|
||||||
|
|
||||||
List<String> duals = GenerateDeckUtil.getDualLandList(colors);
|
List<String> duals = GenerateDeckUtil.getDualLandList(colors);
|
||||||
for (String s : duals) {
|
for (String s : duals) {
|
||||||
this.cardCounts.put(s, 0);
|
this.cardCounts.put(s, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int dblsAdded = addSomeStr((numLands / 4), duals);
|
int dblsAdded = addSomeStr((numLands / 4), duals);
|
||||||
numLands -= dblsAdded;
|
numLands -= dblsAdded;
|
||||||
|
|
||||||
addBasicLand(numLands);
|
addBasicLand(numLands);
|
||||||
tmpDeck.append("DeckSize:").append(tDeck.countAll()).append("\n");
|
tmpDeck.append("DeckSize:").append(tDeck.countAll()).append("\n");
|
||||||
|
|
||||||
adjustDeckSize(size);
|
|
||||||
tmpDeck.append("DeckSize:").append(tDeck.countAll()).append("\n");
|
|
||||||
|
|
||||||
return tDeck;
|
return tDeck;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,9 +17,12 @@
|
|||||||
*/
|
*/
|
||||||
package forge.deck.generate;
|
package forge.deck.generate;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
import forge.card.ColorSet;
|
import forge.card.ColorSet;
|
||||||
import forge.deck.generate.GenerateDeckUtil.FilterCMC;
|
import forge.deck.generate.GenerateDeckUtil.FilterCMC;
|
||||||
import forge.game.player.PlayerType;
|
import forge.game.player.PlayerType;
|
||||||
@@ -35,11 +38,12 @@ import forge.item.ItemPoolView;
|
|||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
public class Generate5ColorDeck extends GenerateColoredDeckBase {
|
public class Generate5ColorDeck extends GenerateColoredDeckBase {
|
||||||
final List<FilterCMC> cmcLevels = Arrays.asList(
|
@SuppressWarnings("unchecked")
|
||||||
new GenerateDeckUtil.FilterCMC(0, 2),
|
final List<ImmutablePair<FilterCMC, Integer>> cmcLevels = Lists.newArrayList(
|
||||||
new GenerateDeckUtil.FilterCMC(3, 5),
|
ImmutablePair.of(new GenerateDeckUtil.FilterCMC(0, 2), 3),
|
||||||
new GenerateDeckUtil.FilterCMC(6, 20));
|
ImmutablePair.of(new GenerateDeckUtil.FilterCMC(3, 5), 2),
|
||||||
final int[] cmcAmounts = {15, 10, 5};
|
ImmutablePair.of(new GenerateDeckUtil.FilterCMC(6, 20), 1)
|
||||||
|
);
|
||||||
|
|
||||||
// resulting mana curve of the card pool
|
// resulting mana curve of the card pool
|
||||||
// 30x 0 - 2
|
// 30x 0 - 2
|
||||||
@@ -66,28 +70,24 @@ public class Generate5ColorDeck extends GenerateColoredDeckBase {
|
|||||||
* @return a {@link forge.CardList} object.
|
* @return a {@link forge.CardList} object.
|
||||||
*/
|
*/
|
||||||
public final ItemPoolView<CardPrinted> getDeck(final int size, final PlayerType pt) {
|
public final ItemPoolView<CardPrinted> getDeck(final int size, final PlayerType pt) {
|
||||||
addCreaturesAndSpells(size, cmcLevels, cmcAmounts, pt);
|
addCreaturesAndSpells(size, cmcLevels, pt);
|
||||||
|
|
||||||
// Add lands
|
// Add lands
|
||||||
int numLands = (int) (getLandsPercentage() * size);
|
int numLands = Math.round(size * getLandsPercentage());
|
||||||
|
adjustDeckSize(size - numLands);
|
||||||
tmpDeck.append("numLands:").append(numLands).append("\n");
|
tmpDeck.append("numLands:").append(numLands).append("\n");
|
||||||
|
|
||||||
// Add dual lands
|
// Add dual lands
|
||||||
|
|
||||||
List<String> duals = GenerateDeckUtil.getDualLandList(colors);
|
List<String> duals = GenerateDeckUtil.getDualLandList(colors);
|
||||||
for (String s : duals) {
|
for (String s : duals) {
|
||||||
this.cardCounts.put(s, 0);
|
this.cardCounts.put(s, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int dblsAdded = addSomeStr((numLands / 4), duals);
|
int dblsAdded = addSomeStr((numLands / 4), duals);
|
||||||
numLands -= dblsAdded;
|
numLands -= dblsAdded;
|
||||||
|
|
||||||
addBasicLand(numLands);
|
addBasicLand(numLands);
|
||||||
tmpDeck.append("DeckSize:").append(tDeck.countAll()).append("\n");
|
tmpDeck.append("DeckSize:").append(tDeck.countAll()).append("\n");
|
||||||
|
|
||||||
adjustDeckSize(size);
|
|
||||||
tmpDeck.append("DeckSize:").append(tDeck.countAll()).append("\n");
|
|
||||||
|
|
||||||
return tDeck;
|
return tDeck;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
*/
|
*/
|
||||||
package forge.deck.generate;
|
package forge.deck.generate;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -25,9 +24,12 @@ import java.util.Map.Entry;
|
|||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
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.Constant;
|
import forge.Constant;
|
||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
@@ -73,20 +75,24 @@ public abstract class GenerateColoredDeckBase {
|
|||||||
tDeck = new ItemPool<CardPrinted>(CardPrinted.class);
|
tDeck = new ItemPool<CardPrinted>(CardPrinted.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void addCreaturesAndSpells(int size, List<FilterCMC> cmcLevels, int[] cmcAmounts, PlayerType pt) {
|
protected void addCreaturesAndSpells(int size, List<ImmutablePair<FilterCMC, Integer>> cmcLevels, PlayerType pt) {
|
||||||
|
tmpDeck.append("Building deck of ").append(size).append("cards\n");
|
||||||
|
|
||||||
final Iterable<CardPrinted> cards = selectCardsOfMatchingColorForPlayer(pt);
|
final Iterable<CardPrinted> cards = selectCardsOfMatchingColorForPlayer(pt);
|
||||||
// build subsets based on type
|
// build subsets based on type
|
||||||
|
|
||||||
final Iterable<CardPrinted> creatures = Iterables.filter(cards, Predicates.compose(CardRulesPredicates.Presets.IS_CREATURE, CardPrinted.FN_GET_RULES));
|
final Iterable<CardPrinted> creatures = Iterables.filter(cards, Predicates.compose(CardRulesPredicates.Presets.IS_CREATURE, CardPrinted.FN_GET_RULES));
|
||||||
final int creatCnt = (int) (getCreatPercentage() * size);
|
final int creatCnt = (int) Math.ceil(getCreatPercentage() * size);
|
||||||
tmpDeck.append("Creature Count:").append(creatCnt).append("\n");
|
tmpDeck.append("Creatures to add:").append(creatCnt).append("\n");
|
||||||
addCmcAdjusted(creatures, creatCnt, cmcLevels, cmcAmounts);
|
addCmcAdjusted(creatures, creatCnt, cmcLevels);
|
||||||
|
|
||||||
Predicate<CardPrinted> preSpells = Predicates.compose(CardRulesPredicates.Presets.IS_NONCREATURE_SPELL_FOR_GENERATOR, CardPrinted.FN_GET_RULES);
|
Predicate<CardPrinted> preSpells = Predicates.compose(CardRulesPredicates.Presets.IS_NONCREATURE_SPELL_FOR_GENERATOR, CardPrinted.FN_GET_RULES);
|
||||||
final Iterable<CardPrinted> spells = Iterables.filter(cards, preSpells);
|
final Iterable<CardPrinted> spells = Iterables.filter(cards, preSpells);
|
||||||
final int spellCnt = (int) (getSpellPercentage() * size);
|
final int spellCnt = (int) Math.ceil(getSpellPercentage() * size);
|
||||||
tmpDeck.append("Spell Count:").append(spellCnt).append("\n");
|
tmpDeck.append("Spells to add:").append(spellCnt).append("\n");
|
||||||
addCmcAdjusted(spells, spellCnt, cmcLevels, cmcAmounts);
|
addCmcAdjusted(spells, spellCnt, cmcLevels);
|
||||||
|
|
||||||
|
tmpDeck.append(String.format("Current deck size: %d... should be %f%n", tDeck.countAll(), size * (getCreatPercentage() + getSpellPercentage())));
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemPoolView<CardPrinted> getDeck(final int size, final PlayerType pt) {
|
public ItemPoolView<CardPrinted> getDeck(final int size, final PlayerType pt) {
|
||||||
@@ -97,19 +103,22 @@ public abstract class GenerateColoredDeckBase {
|
|||||||
for (int i = 0; i < cnt; i++) {
|
for (int i = 0; i < cnt; i++) {
|
||||||
CardPrinted cp;
|
CardPrinted cp;
|
||||||
int lc = 0;
|
int lc = 0;
|
||||||
|
int srcLen = source.size();
|
||||||
do {
|
do {
|
||||||
cp = source.get(this.r.nextInt(source.size()));
|
cp = source.get(this.r.nextInt(srcLen));
|
||||||
lc++;
|
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) {
|
if (lc > 100) {
|
||||||
throw new RuntimeException("Generate2ColorDeck : get2ColorDeck -- looped too much -- Cr12");
|
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());
|
final int n = this.cardCounts.get(cp.getName());
|
||||||
this.cardCounts.put(cp.getName(), n + 1);
|
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) {
|
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
|
// attempt to optimize basic land counts according to colors of picked cards
|
||||||
final Map<String, Integer> clrCnts = countLands(tDeck);
|
final Map<String, Integer> clrCnts = countLands(tDeck);
|
||||||
// total of all ClrCnts
|
// total of all ClrCnts
|
||||||
@@ -147,24 +158,23 @@ public abstract class GenerateColoredDeckBase {
|
|||||||
|
|
||||||
tmpDeck.append("totalColor:").append(totalColor).append("\n");
|
tmpDeck.append("totalColor:").append(totalColor).append("\n");
|
||||||
|
|
||||||
|
int landsLeft = cnt;
|
||||||
for (Entry<String, Integer> c : clrCnts.entrySet()) {
|
for (Entry<String, Integer> c : clrCnts.entrySet()) {
|
||||||
String color = c.getKey();
|
String color = c.getKey();
|
||||||
|
|
||||||
|
|
||||||
// calculate number of lands for each color
|
// calculate number of lands for each color
|
||||||
float p = (float) c.getValue() / totalColor;
|
final int nLand = Math.min(landsLeft, Math.round(cnt * c.getValue() / totalColor));
|
||||||
final int nLand = (int) (cnt * p);
|
|
||||||
tmpDeck.append("nLand-").append(color).append(":").append(nLand).append("\n");
|
tmpDeck.append("nLand-").append(color).append(":").append(nLand).append("\n");
|
||||||
|
|
||||||
// just to prevent a null exception by the deck size fixing
|
// just to prevent a null exception by the deck size fixing code
|
||||||
// code
|
|
||||||
this.cardCounts.put(color, nLand);
|
this.cardCounts.put(color, nLand);
|
||||||
|
|
||||||
CardPrinted cp = CardDb.instance().getCard(color);
|
CardPrinted cp = CardDb.instance().getCard(color);
|
||||||
String basicLandSet = Aggregates.random(cp.getRules().getSets());
|
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<CardPrinted> source, int cnt, List<FilterCMC> cmcLevels, int[] cmcAmounts) {
|
protected void addCmcAdjusted(Iterable<CardPrinted> source, int cnt, List<ImmutablePair<FilterCMC, Integer>> cmcLevels) {
|
||||||
final List<CardPrinted> curved = new ArrayList<CardPrinted>();
|
int totalWeight = 0;
|
||||||
|
for (ImmutablePair<FilterCMC, Integer> pair : cmcLevels) {
|
||||||
for (int i = 0; i < cmcAmounts.length; i++) {
|
totalWeight += pair.getRight();
|
||||||
Iterable<CardPrinted> matchingCards = Iterables.filter(source, Predicates.compose(cmcLevels.get(i), CardPrinted.FN_GET_RULES));
|
|
||||||
curved.addAll(Aggregates.random(matchingCards, cmcAmounts[i]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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<FilterCMC, Integer> pair : cmcLevels) {
|
||||||
|
Iterable<CardPrinted> 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));
|
||||||
|
|
||||||
|
final List<CardPrinted> curved = Aggregates.random(matchingCards, cmcCountForPool);
|
||||||
|
final List<CardPrinted> curvedRandomized = Lists.newArrayList();
|
||||||
for (CardPrinted c : curved) {
|
for (CardPrinted c : curved) {
|
||||||
this.cardCounts.put(c.getName(), 0);
|
this.cardCounts.put(c.getName(), 0);
|
||||||
|
CardPrinted cpRandomSet = CardDb.instance().getCard(c.getName(), Aggregates.random(c.getRules().getSets()));
|
||||||
|
curvedRandomized.add(cpRandomSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
addSome(cnt, curved);
|
addSome(addOfThisCmc, curvedRandomized);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Iterable<CardPrinted> selectCardsOfMatchingColorForPlayer(PlayerType pt) {
|
protected Iterable<CardPrinted> selectCardsOfMatchingColorForPlayer(PlayerType pt) {
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ public class GenerateDeckUtil {
|
|||||||
@Override
|
@Override
|
||||||
public boolean apply(CardRules c) {
|
public boolean apply(CardRules c) {
|
||||||
ManaCost mc = c.getManaCost();
|
ManaCost mc = c.getManaCost();
|
||||||
return mc.getColorProfile() == 0 && !mc.isNoCost();
|
return c.getColorIdentity().isColorless() && !mc.isNoCost();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -72,7 +72,8 @@ public class GenerateDeckUtil {
|
|||||||
@Override
|
@Override
|
||||||
public boolean apply(CardRules subject) {
|
public boolean apply(CardRules subject) {
|
||||||
ManaCost mc = subject.getManaCost();
|
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());
|
// return allowedColor.containsAllColorsFrom(mc.getColorProfile());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,9 +17,12 @@
|
|||||||
*/
|
*/
|
||||||
package forge.deck.generate;
|
package forge.deck.generate;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
import forge.card.ColorSet;
|
import forge.card.ColorSet;
|
||||||
import forge.card.MagicColor;
|
import forge.card.MagicColor;
|
||||||
import forge.deck.generate.GenerateDeckUtil.FilterCMC;
|
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 getCreatPercentage() { return 0.36f; }
|
||||||
@Override protected final float getSpellPercentage() { return 0.25f; }
|
@Override protected final float getSpellPercentage() { return 0.25f; }
|
||||||
|
|
||||||
final List<FilterCMC> cmcLevels = Arrays.asList(
|
@SuppressWarnings("unchecked")
|
||||||
new GenerateDeckUtil.FilterCMC(0, 2),
|
final List<ImmutablePair<FilterCMC, Integer>> cmcLevels = Lists.newArrayList(
|
||||||
new GenerateDeckUtil.FilterCMC(3, 4),
|
ImmutablePair.of(new GenerateDeckUtil.FilterCMC(0, 2), 10),
|
||||||
new GenerateDeckUtil.FilterCMC(5, 6),
|
ImmutablePair.of(new GenerateDeckUtil.FilterCMC(3, 4), 8),
|
||||||
new GenerateDeckUtil.FilterCMC(7, 20));
|
ImmutablePair.of(new GenerateDeckUtil.FilterCMC(5, 6), 5),
|
||||||
final int[] cmcAmounts = {10, 8, 5, 3};
|
ImmutablePair.of(new GenerateDeckUtil.FilterCMC(7, 20), 3)
|
||||||
|
);
|
||||||
|
|
||||||
// mana curve of the card pool
|
// mana curve of the card pool
|
||||||
// 20x 0 - 2
|
// 20x 0 - 2
|
||||||
@@ -76,7 +80,7 @@ public class GenerateMonoColorDeck extends GenerateColoredDeckBase {
|
|||||||
|
|
||||||
|
|
||||||
public final ItemPoolView<CardPrinted> getDeck(final int size, final PlayerType pt) {
|
public final ItemPoolView<CardPrinted> getDeck(final int size, final PlayerType pt) {
|
||||||
addCreaturesAndSpells(size, cmcLevels, cmcAmounts, pt);
|
addCreaturesAndSpells(size, cmcLevels, pt);
|
||||||
|
|
||||||
// Add lands
|
// Add lands
|
||||||
int numLands = (int) (getLandsPercentage() * size);
|
int numLands = (int) (getLandsPercentage() * size);
|
||||||
|
|||||||
Reference in New Issue
Block a user