mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-16 18:58:00 +00:00
Refactor to only rank cards once
This commit is contained in:
@@ -37,10 +37,7 @@ public class CardRankerTest {
|
||||
PaperCard c1 = readCard("makindi_patrol.txt");
|
||||
list.add(c1);
|
||||
|
||||
List<Pair<Double, PaperCard>> ranked = ranker.rankCards(list);
|
||||
for (Pair<Double, PaperCard> pair : ranked) {
|
||||
System.out.println(pair.getKey().toString() + " " + pair.getValue().getName());
|
||||
}
|
||||
List<PaperCard> ranked = ranker.rankCards(list);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,6 +5,5 @@ PT:6/6
|
||||
K:Vigilance
|
||||
A:AB$ ChangeZone | Cost$Sac<2/Eldrazi.Scion> | Origin$ Graveyard | Destination$ Hand | ActivationZone$ Graveyard | SorcerySpeed$ True | SpellDescription$ Return CARDNAME from your graveyard to your hand. Activate this ability only any time you could cast a sorcery.
|
||||
SVar:DiscardMe:1
|
||||
SVar:RemRandomDeck:True
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/deathless_behemoth.jpg
|
||||
Oracle:Vigilance\nSacrifice two Eldrazi Scions: Return Deathless Behemoth from your graveyard to your hand. Activate this ability only any time you could cast a sorcery.
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
package forge.limited;
|
||||
|
||||
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.card.CardRulesPredicates;
|
||||
import forge.card.DeckHints;
|
||||
import forge.item.PaperCard;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import java.awt.print.Paper;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -23,16 +20,23 @@ public class CardRanker {
|
||||
* @param cards PaperCards to rank
|
||||
* @return List of beans with card rankings
|
||||
*/
|
||||
public List<Pair<Double, PaperCard>> rankCards(final Iterable<PaperCard> cards) {
|
||||
final List<Pair<Double, PaperCard>> ranked = new ArrayList<Pair<Double, PaperCard>>();
|
||||
public List<PaperCard> rankCards(final Iterable<PaperCard> cards) {
|
||||
List<Pair<Double, PaperCard>> cardScores = getScores(cards);
|
||||
|
||||
getInitialRankings(cards, ranked);
|
||||
Collections.sort(cardScores, Collections.reverseOrder(new CardRankingComparator()));
|
||||
|
||||
Collections.sort(ranked, Collections.reverseOrder(new CardRankingComparator()));
|
||||
return ranked;
|
||||
List<PaperCard> rankedCards = new ArrayList<>(cardScores.size());
|
||||
for (Pair<Double, PaperCard> pair : cardScores) {
|
||||
System.out.println(pair.getKey().toString() + " " + pair.getValue().getName());
|
||||
rankedCards.add(pair.getValue());
|
||||
}
|
||||
|
||||
private void getInitialRankings(Iterable<PaperCard> cards, List<Pair<Double, PaperCard>> ranked) {
|
||||
return rankedCards;
|
||||
}
|
||||
|
||||
private List<Pair<Double, PaperCard>> getScores(Iterable<PaperCard> cards) {
|
||||
List<Pair<Double, PaperCard>> cardScores = new ArrayList<>();
|
||||
|
||||
List<PaperCard> cache = new ArrayList<>();
|
||||
for (PaperCard card : cards) {
|
||||
cache.add(card);
|
||||
@@ -42,6 +46,19 @@ public class CardRanker {
|
||||
for (int i = 0; i < cache.size(); i++) {
|
||||
final PaperCard card = cache.get(i);
|
||||
|
||||
double score = getRawScore(card, customRankings);
|
||||
|
||||
List<PaperCard> otherCards = getCardsExcept(cache, i);
|
||||
|
||||
score += calculateSynergies(card, otherCards);
|
||||
|
||||
cardScores.add(Pair.of(score, card));
|
||||
}
|
||||
|
||||
return cardScores;
|
||||
}
|
||||
|
||||
private double getRawScore(PaperCard card, String customRankings) {
|
||||
Double rkg;
|
||||
if (customRankings != null) {
|
||||
rkg = DraftRankCache.getCustomRanking(customRankings, card.getName());
|
||||
@@ -59,19 +76,16 @@ public class CardRanker {
|
||||
} else {
|
||||
rawScore = 0.0;
|
||||
}
|
||||
return rawScore;
|
||||
}
|
||||
|
||||
double score = rawScore;
|
||||
|
||||
private List<PaperCard> getCardsExcept(List<PaperCard> cache, int i) {
|
||||
List<PaperCard> otherCards = new ArrayList<>();
|
||||
otherCards.addAll(cache.subList(0, i));
|
||||
if (i + 1 < cache.size()) {
|
||||
otherCards.addAll(cache.subList(i + 1, cache.size()));
|
||||
}
|
||||
|
||||
score += calculateSynergies(card, otherCards);
|
||||
|
||||
ranked.add(Pair.of(score, card));
|
||||
}
|
||||
return otherCards;
|
||||
}
|
||||
|
||||
private double calculateSynergies(PaperCard card, Iterable<PaperCard> otherCards) {
|
||||
@@ -83,6 +97,16 @@ public class CardRanker {
|
||||
return synergyScore;
|
||||
}
|
||||
|
||||
private double getScoreForDeckHints(PaperCard card, Iterable<PaperCard> otherCards) {
|
||||
double score = 0.0;
|
||||
final DeckHints hints = card.getRules().getAiHints().getDeckHints();
|
||||
if (hints != null && hints.getType() != DeckHints.Type.NONE) {
|
||||
final List<PaperCard> comboCards = hints.filter(otherCards);
|
||||
score = comboCards.size() * 10;
|
||||
}
|
||||
return score;
|
||||
}
|
||||
|
||||
private double getScoreForBuffedBy(PaperCard card, Iterable<PaperCard> otherCards) {
|
||||
double matchBuffScore = 0.0;
|
||||
Iterable<Map.Entry<String, String>> vars = card.getRules().getMainPart().getVariables();
|
||||
@@ -91,20 +115,9 @@ public class CardRanker {
|
||||
String buff = var.getValue();
|
||||
final Iterable<PaperCard> buffers = Iterables.filter(otherCards,
|
||||
Predicates.compose(CardRulesPredicates.subType(buff), PaperCard.FN_GET_RULES));
|
||||
System.out.println(Iterables.size(buffers));
|
||||
matchBuffScore = Iterables.size(buffers) * 5;
|
||||
matchBuffScore = Iterables.size(buffers) * 3;
|
||||
}
|
||||
}
|
||||
return matchBuffScore;
|
||||
}
|
||||
|
||||
private double getScoreForDeckHints(PaperCard card, Iterable<PaperCard> otherCards) {
|
||||
double score = 0.0;
|
||||
final DeckHints hints = card.getRules().getAiHints().getDeckHints();
|
||||
if (hints != null && hints.getType() != DeckHints.Type.NONE) {
|
||||
final List<PaperCard> comboCards = hints.filter(otherCards);
|
||||
score = comboCards.size() * 3;
|
||||
}
|
||||
return score;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package forge.limited;
|
||||
|
||||
import java.awt.print.Paper;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
@@ -63,11 +64,11 @@ public class LimitedDeckBuilder extends DeckGeneratorBase {
|
||||
private final List<String> setsWithBasicLands = new ArrayList<String>();
|
||||
// Views for aiPlayable
|
||||
|
||||
private Iterable<PaperCard> colorList;
|
||||
protected CardRanker ranker = new CardRanker();
|
||||
private Iterable<PaperCard> onColorCreatures;
|
||||
private Iterable<PaperCard> onColorNonCreatures;
|
||||
|
||||
private static final boolean logToConsole = false;
|
||||
private static final boolean logToConsole = true;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -84,14 +85,13 @@ public class LimitedDeckBuilder extends DeckGeneratorBase {
|
||||
this.deckColors = pClrs;
|
||||
this.colors = pClrs.getChosenColors();
|
||||
|
||||
// removeUnplayables();
|
||||
// remove Unplayables
|
||||
final Iterable<PaperCard> playables = Iterables.filter(availableList,
|
||||
Predicates.compose(CardRulesPredicates.IS_KEPT_IN_AI_DECKS, PaperCard.FN_GET_RULES));
|
||||
this.aiPlayables = Lists.newArrayList(playables);
|
||||
this.availableList.removeAll(getAiPlayables());
|
||||
this.aiPlayables = this.ranker.rankCards(playables);
|
||||
this.availableList.removeAll(aiPlayables);
|
||||
|
||||
findBasicLandSets();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -132,7 +132,9 @@ public class LimitedDeckBuilder extends DeckGeneratorBase {
|
||||
public Deck buildDeck(final String landSetCode) {
|
||||
// 1. Prepare
|
||||
hasColor = Predicates.or(new MatchColorIdentity(colors), COLORLESS_CARDS);
|
||||
colorList = Iterables.filter(aiPlayables, Predicates.compose(hasColor, PaperCard.FN_GET_RULES));
|
||||
Iterable<PaperCard> colorList = Iterables.filter(aiPlayables,
|
||||
Predicates.compose(hasColor, PaperCard.FN_GET_RULES));
|
||||
|
||||
onColorCreatures = Iterables.filter(colorList,
|
||||
Predicates.compose(CardRulesPredicates.Presets.IS_CREATURE, PaperCard.FN_GET_RULES));
|
||||
onColorNonCreatures = Iterables.filter(colorList,
|
||||
@@ -153,28 +155,27 @@ public class LimitedDeckBuilder extends DeckGeneratorBase {
|
||||
}
|
||||
|
||||
// 3. Add creatures, trying to follow mana curve
|
||||
addManaCurveCreatures(rankCards(onColorCreatures), 15);
|
||||
addManaCurveCreatures(onColorCreatures, 15);
|
||||
|
||||
// 4.Try to fill up to 22 with on-color non-creature cards
|
||||
addNonCreatures(rankCards(onColorNonCreatures), numSpellsNeeded - deckList.size());
|
||||
addNonCreatures(onColorNonCreatures, numSpellsNeeded - deckList.size());
|
||||
|
||||
// 5.If we couldn't get up to 22, try to fill up to 22 with on-color
|
||||
// creature cards
|
||||
addCreatures(rankCards(onColorCreatures), numSpellsNeeded - deckList.size());
|
||||
addCreatures(onColorCreatures, numSpellsNeeded - deckList.size());
|
||||
|
||||
// 6. If there are still on-color cards, and the average cmc is low, add
|
||||
// a 23rd card.
|
||||
if (deckList.size() == numSpellsNeeded && getAverageCMC(deckList) < 3) {
|
||||
final Iterable<PaperCard> nonLands = Iterables.filter(colorList,
|
||||
Predicates.compose(CardRulesPredicates.Presets.IS_NON_LAND, PaperCard.FN_GET_RULES));
|
||||
if (deckList.size() == numSpellsNeeded && getAverageCMC(deckList) < 3) {
|
||||
final List<Pair<Double, PaperCard>> list = rankCards(nonLands);
|
||||
if (!list.isEmpty()) {
|
||||
final PaperCard c = list.get(0).getValue();
|
||||
deckList.add(c);
|
||||
getAiPlayables().remove(c);
|
||||
final PaperCard card = Iterables.getFirst(nonLands, null);
|
||||
if (card != null) {
|
||||
deckList.add(card);
|
||||
aiPlayables.remove(card);
|
||||
landsNeeded--;
|
||||
if (logToConsole) {
|
||||
System.out.println("Low CMC: " + c.getName());
|
||||
System.out.println("Low CMC: " + card.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -243,7 +244,7 @@ public class LimitedDeckBuilder extends DeckGeneratorBase {
|
||||
}
|
||||
i = 0;
|
||||
System.out.println("NOT PICKED");
|
||||
for (final PaperCard c : getAiPlayables()) {
|
||||
for (final PaperCard c : aiPlayables) {
|
||||
i++;
|
||||
System.out.println(i + ". " + c.toString() + ": " + c.getRules().getManaCost().toString());
|
||||
}
|
||||
@@ -265,7 +266,7 @@ public class LimitedDeckBuilder extends DeckGeneratorBase {
|
||||
}
|
||||
final PaperCard c = deckList.get(MyRandom.getRandom().nextInt(deckList.size() - 1));
|
||||
deckList.remove(c);
|
||||
getAiPlayables().add(c);
|
||||
aiPlayables.add(c);
|
||||
if (logToConsole) {
|
||||
System.out.println(" - Removed " + c.getName() + " randomly.");
|
||||
}
|
||||
@@ -275,17 +276,17 @@ public class LimitedDeckBuilder extends DeckGeneratorBase {
|
||||
if (logToConsole) {
|
||||
System.out.println("WARNING: Fixing deck size, currently " + deckList.size() + " cards.");
|
||||
}
|
||||
if (getAiPlayables().size() > 1) {
|
||||
final PaperCard c = getAiPlayables().get(MyRandom.getRandom().nextInt(getAiPlayables().size() - 1));
|
||||
if (aiPlayables.size() > 1) {
|
||||
final PaperCard c = aiPlayables.get(MyRandom.getRandom().nextInt(aiPlayables.size() - 1));
|
||||
deckList.add(c);
|
||||
getAiPlayables().remove(c);
|
||||
aiPlayables.remove(c);
|
||||
if (logToConsole) {
|
||||
System.out.println(" - Added " + c.getName() + " randomly.");
|
||||
}
|
||||
} else if (getAiPlayables().size() == 1) {
|
||||
final PaperCard c = getAiPlayables().get(0);
|
||||
} else if (aiPlayables.size() == 1) {
|
||||
final PaperCard c = aiPlayables.get(0);
|
||||
deckList.add(c);
|
||||
getAiPlayables().remove(c);
|
||||
aiPlayables.remove(c);
|
||||
if (logToConsole) {
|
||||
System.out.println(" - Added " + c.getName() + " randomly.");
|
||||
}
|
||||
@@ -429,39 +430,41 @@ public class LimitedDeckBuilder extends DeckGeneratorBase {
|
||||
final List<String> inverseDuals = getInverseDualLandList();
|
||||
final Iterable<PaperCard> lands = Iterables.filter(aiPlayables,
|
||||
Predicates.compose(CardRulesPredicates.Presets.IS_NONBASIC_LAND, PaperCard.FN_GET_RULES));
|
||||
final List<Pair<Double, PaperCard>> ranked = rankCards(lands);
|
||||
for (final Pair<Double, PaperCard> bean : ranked) {
|
||||
List<PaperCard> landsToAdd = new ArrayList<>();
|
||||
for (final PaperCard card : lands) {
|
||||
if (landsNeeded > 0) {
|
||||
// Throw out any dual-lands for the wrong colors. Assume
|
||||
// everything else is either
|
||||
// (a) dual-land of the correct two colors, or
|
||||
// (b) a land that generates colorless mana and has some other
|
||||
// beneficial effect.
|
||||
if (!inverseDuals.contains(bean.getValue().getName())) {
|
||||
deckList.add(bean.getValue());
|
||||
aiPlayables.remove(bean.getValue());
|
||||
if (!inverseDuals.contains(card.getName())) {
|
||||
landsToAdd.add(card);
|
||||
landsNeeded--;
|
||||
if (logToConsole) {
|
||||
System.out.println("NonBasicLand[" + landsNeeded + "]:" + bean.getValue().getName());
|
||||
System.out.println("NonBasicLand[" + landsNeeded + "]:" + card.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
deckList.addAll(landsToAdd);
|
||||
aiPlayables.removeAll(landsToAdd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a third color to the deck.
|
||||
*
|
||||
* @param nCards
|
||||
* @param num
|
||||
* number to add
|
||||
*/
|
||||
private void addThirdColorCards(int nCards) {
|
||||
if (nCards > 0) {
|
||||
private void addThirdColorCards(int num) {
|
||||
if (num > 0) {
|
||||
final Iterable<PaperCard> others = Iterables.filter(aiPlayables,
|
||||
Predicates.compose(CardRulesPredicates.Presets.IS_NON_LAND, PaperCard.FN_GET_RULES));
|
||||
List<Pair<Double, PaperCard>> ranked = rankCards(others);
|
||||
for (final Pair<Double, PaperCard> bean : ranked) {
|
||||
List<PaperCard> toAdd = new ArrayList<>(num);
|
||||
for (final PaperCard card : others) {
|
||||
// Want a card that has just one "off" color.
|
||||
final ColorSet off = colors.getOffColors(bean.getValue().getRules().getColor());
|
||||
final ColorSet off = colors.getOffColors(card.getRules().getColor());
|
||||
if (off.isMonoColor()) {
|
||||
colors = ColorSet.fromMask(colors.getColor() | off.getColor());
|
||||
break;
|
||||
@@ -472,45 +475,47 @@ public class LimitedDeckBuilder extends DeckGeneratorBase {
|
||||
DeckGeneratorBase.COLORLESS_CARDS);
|
||||
final Iterable<PaperCard> threeColorList = Iterables.filter(aiPlayables,
|
||||
Predicates.compose(hasColor, PaperCard.FN_GET_RULES));
|
||||
ranked = rankCards(threeColorList);
|
||||
for (final Pair<Double, PaperCard> bean : ranked) {
|
||||
if (nCards > 0) {
|
||||
deckList.add(bean.getValue());
|
||||
aiPlayables.remove(bean.getValue());
|
||||
nCards--;
|
||||
for (final PaperCard card : threeColorList) {
|
||||
if (num > 0) {
|
||||
toAdd.add(card);
|
||||
num--;
|
||||
if (logToConsole) {
|
||||
System.out.println("Third Color[" + nCards + "]:" + bean.getValue().getName() + "("
|
||||
+ bean.getValue().getRules().getManaCost() + ")");
|
||||
System.out.println("Third Color[" + num + "]:" + card.getName() + "("
|
||||
+ card.getRules().getManaCost() + ")");
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
deckList.addAll(toAdd);
|
||||
aiPlayables.removeAll(toAdd);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add random cards to the deck.
|
||||
*
|
||||
* @param nCards
|
||||
* @param num
|
||||
* number to add
|
||||
*/
|
||||
private void addRandomCards(int nCards) {
|
||||
private void addRandomCards(int num) {
|
||||
final Iterable<PaperCard> others = Iterables.filter(aiPlayables,
|
||||
Predicates.compose(CardRulesPredicates.Presets.IS_NON_LAND, PaperCard.FN_GET_RULES));
|
||||
final List<Pair<Double, PaperCard>> ranked = rankCards(others);
|
||||
for (final Pair<Double, PaperCard> bean : ranked) {
|
||||
if (nCards > 0) {
|
||||
deckList.add(bean.getValue());
|
||||
aiPlayables.remove(bean.getValue());
|
||||
nCards--;
|
||||
List <PaperCard> toAdd = new ArrayList<>(num);
|
||||
for (final PaperCard card : others) {
|
||||
if (num > 0) {
|
||||
toAdd.add(card);
|
||||
num--;
|
||||
if (logToConsole) {
|
||||
System.out.println("Random[" + nCards + "]:" + bean.getValue().getName() + "("
|
||||
+ bean.getValue().getRules().getManaCost() + ")");
|
||||
System.out.println("Random[" + num + "]:" + card.getName() + "("
|
||||
+ card.getRules().getManaCost() + ")");
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
deckList.addAll(toAdd);
|
||||
aiPlayables.removeAll(toAdd);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -519,60 +524,24 @@ public class LimitedDeckBuilder extends DeckGeneratorBase {
|
||||
* @param nonCreatures
|
||||
* cards to choose from
|
||||
* @param num
|
||||
* number to add
|
||||
*/
|
||||
private void addNonCreatures(final List<Pair<Double, PaperCard>> nonCreatures, int num) {
|
||||
for (final Pair<Double, PaperCard> bean : nonCreatures) {
|
||||
private void addNonCreatures(final Iterable<PaperCard> nonCreatures, int num) {
|
||||
List<PaperCard> toAdd = new ArrayList<>(num);
|
||||
for (final PaperCard card : nonCreatures) {
|
||||
if (num > 0) {
|
||||
final PaperCard cardToAdd = bean.getValue();
|
||||
deckList.add(cardToAdd);
|
||||
toAdd.add(card);
|
||||
num--;
|
||||
getAiPlayables().remove(cardToAdd);
|
||||
if (logToConsole) {
|
||||
System.out.println("Others[" + num + "]:" + cardToAdd.getName() + " ("
|
||||
+ cardToAdd.getRules().getManaCost() + ")");
|
||||
System.out.println("Others[" + num + "]:" + card.getName() + " ("
|
||||
+ card.getRules().getManaCost() + ")");
|
||||
}
|
||||
num = addDeckHintsCards(cardToAdd, num);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add cards that work well with the given card.
|
||||
*
|
||||
* @param cardToAdd
|
||||
* card being checked
|
||||
* @param num
|
||||
* number of cards
|
||||
* @return number left after adding
|
||||
*/
|
||||
private int addDeckHintsCards(final PaperCard cardToAdd, int num) {
|
||||
// cards with DeckHints will try to grab additional cards from the pool
|
||||
final DeckHints hints = cardToAdd.getRules().getAiHints().getDeckHints();
|
||||
if (hints != null && hints.getType() != DeckHints.Type.NONE) {
|
||||
final Iterable<PaperCard> onColor = Iterables.filter(aiPlayables, Predicates.compose(hasColor, PaperCard.FN_GET_RULES));
|
||||
final List<PaperCard> comboCards = hints.filter(onColor);
|
||||
if (logToConsole) {
|
||||
System.out.println("Found " + comboCards.size() + " cards for " + cardToAdd.getName());
|
||||
}
|
||||
for (final Pair<Double, PaperCard> comboBean : rankCards(comboCards)) {
|
||||
if (num > 0) {
|
||||
// This is not exactly right, because the
|
||||
// rankedComboCards could include creatures and
|
||||
// non-creatures.
|
||||
// This code could add too many of one or the other.
|
||||
final PaperCard combo = comboBean.getValue();
|
||||
deckList.add(combo);
|
||||
num--;
|
||||
getAiPlayables().remove(combo);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return num;
|
||||
deckList.addAll(toAdd);
|
||||
aiPlayables.removeAll(toAdd);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -620,10 +589,10 @@ public class LimitedDeckBuilder extends DeckGeneratorBase {
|
||||
}
|
||||
}
|
||||
if (numCreatures > 0) {
|
||||
addCreatures(rankCards(onColorCreatures), numCreatures);
|
||||
addCreatures(onColorCreatures, numCreatures);
|
||||
}
|
||||
if (numOthers > 0) {
|
||||
addNonCreatures(rankCards(onColorNonCreatures), numOthers);
|
||||
addNonCreatures(onColorNonCreatures, numOthers);
|
||||
}
|
||||
// If we added some replacement cards, and we still have cards available
|
||||
// in aiPlayables, call this function again in case the replacement
|
||||
@@ -639,22 +608,23 @@ public class LimitedDeckBuilder extends DeckGeneratorBase {
|
||||
* @param creatures
|
||||
* cards to choose from
|
||||
* @param num
|
||||
* number to add
|
||||
*/
|
||||
private void addCreatures(final List<Pair<Double, PaperCard>> creatures, int num) {
|
||||
for (final Pair<Double, PaperCard> bean : creatures) {
|
||||
private void addCreatures(final Iterable<PaperCard> creatures, int num) {
|
||||
List<PaperCard> creaturesToAdd = new ArrayList<>(num);
|
||||
for (final PaperCard card : creatures) {
|
||||
if (num > 0) {
|
||||
final PaperCard c = bean.getValue();
|
||||
deckList.add(c);
|
||||
creaturesToAdd.add(card);
|
||||
num--;
|
||||
getAiPlayables().remove(c);
|
||||
if (logToConsole) {
|
||||
System.out.println("Creature[" + num + "]:" + c.getName() + " (" + c.getRules().getManaCost() + ")");
|
||||
System.out.println("Creature[" + num + "]:" + card.getName() + " (" + card.getRules().getManaCost() + ")");
|
||||
}
|
||||
num = addDeckHintsCards(c, num);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
deckList.addAll(creaturesToAdd);
|
||||
aiPlayables.removeAll(creaturesToAdd);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -665,8 +635,9 @@ public class LimitedDeckBuilder extends DeckGeneratorBase {
|
||||
* @param creatures
|
||||
* cards to choose from
|
||||
* @param num
|
||||
* number to add
|
||||
*/
|
||||
private void addManaCurveCreatures(final List<Pair<Double, PaperCard>> creatures, int num) {
|
||||
private void addManaCurveCreatures(final Iterable<PaperCard> creatures, int num) {
|
||||
final Map<Integer, Integer> creatureCosts = new HashMap<Integer, Integer>();
|
||||
for (int i = 1; i < 7; i++) {
|
||||
creatureCosts.put(i, 0);
|
||||
@@ -683,9 +654,9 @@ public class LimitedDeckBuilder extends DeckGeneratorBase {
|
||||
creatureCosts.put(cmc, creatureCosts.get(cmc) + 1);
|
||||
}
|
||||
|
||||
for (final Pair<Double, PaperCard> bean : creatures) {
|
||||
final PaperCard c = bean.getValue();
|
||||
int cmc = c.getRules().getManaCost().getCMC();
|
||||
List<PaperCard> creaturesToAdd = new ArrayList<>(num);
|
||||
for (final PaperCard card : creatures) {
|
||||
int cmc = card.getRules().getManaCost().getCMC();
|
||||
if (cmc < 1) {
|
||||
cmc = 1;
|
||||
} else if (cmc > 6) {
|
||||
@@ -708,58 +679,24 @@ public class LimitedDeckBuilder extends DeckGeneratorBase {
|
||||
}
|
||||
|
||||
if (willAddCreature) {
|
||||
deckList.add(c);
|
||||
creaturesToAdd.add(card);
|
||||
num--;
|
||||
getAiPlayables().remove(c);
|
||||
creatureCosts.put(cmc, creatureCosts.get(cmc) + 1);
|
||||
if (logToConsole) {
|
||||
System.out.println("Creature[" + num + "]:" + c.getName() + " (" + c.getRules().getManaCost() + ")");
|
||||
System.out.println("Creature[" + num + "]:" + card.getName() + " (" + card.getRules().getManaCost() + ")");
|
||||
}
|
||||
num = addDeckHintsCards(c, num);
|
||||
} else {
|
||||
if (logToConsole) {
|
||||
System.out.println(c.getName() + " not added because CMC " + c.getRules().getManaCost().getCMC()
|
||||
System.out.println(card.getName() + " not added because CMC " + card.getRules().getManaCost().getCMC()
|
||||
+ " has " + currentAtCmc + " already.");
|
||||
}
|
||||
}
|
||||
if (num <= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rank cards.
|
||||
*
|
||||
* @param cards
|
||||
* CardPrinteds to rank
|
||||
* @return List of beans with card rankings
|
||||
*/
|
||||
protected List<Pair<Double, PaperCard>> rankCards(final Iterable<PaperCard> cards) {
|
||||
final List<Pair<Double, PaperCard>> ranked = new ArrayList<Pair<Double, PaperCard>>();
|
||||
for (final PaperCard card : cards) {
|
||||
Double rkg;
|
||||
String customRankings = IBoosterDraft.CUSTOM_RANKINGS_FILE[0];
|
||||
|
||||
if (customRankings != null) {
|
||||
rkg = DraftRankCache.getCustomRanking(customRankings, card.getName());
|
||||
if (rkg == null) {
|
||||
// try the default rankings if custom rankings contain no entry
|
||||
rkg = DraftRankCache.getRanking(card.getName(), card.getEdition());
|
||||
}
|
||||
} else {
|
||||
rkg = DraftRankCache.getRanking(card.getName(), card.getEdition());
|
||||
}
|
||||
|
||||
if (rkg != null) {
|
||||
ranked.add(Pair.of(rkg, card));
|
||||
} else {
|
||||
ranked.add(Pair.of(0.0, card));
|
||||
}
|
||||
}
|
||||
Collections.sort(ranked, new CardRankingComparator());
|
||||
return ranked;
|
||||
deckList.addAll(creaturesToAdd);
|
||||
aiPlayables.removeAll(creaturesToAdd);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -31,13 +31,11 @@ public class SealedDeckBuilder extends LimitedDeckBuilder {
|
||||
* @return DeckColors
|
||||
*/
|
||||
private ColorSet chooseColors() {
|
||||
List<Pair<Double, PaperCard>> rankedCards = rankCards(getAiPlayables());
|
||||
|
||||
// choose colors based on top 33% of cards
|
||||
final List<PaperCard> colorChooserList = new ArrayList<PaperCard>();
|
||||
double limit = rankedCards.size() * .33;
|
||||
double limit = getAiPlayables().size() * .33;
|
||||
for (int i = 0; i < limit; i++) {
|
||||
PaperCard cp = rankedCards.get(i).getValue();
|
||||
PaperCard cp = getAiPlayables().get(i);
|
||||
colorChooserList.add(cp);
|
||||
//System.out.println(cp.getName() + " " + cp.getRules().getManaCost().toString());
|
||||
}
|
||||
@@ -64,8 +62,8 @@ public class SealedDeckBuilder extends LimitedDeckBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
String color1 = MagicColor.Constant.GREEN;
|
||||
String color2 = MagicColor.Constant.BLACK;
|
||||
String color1;
|
||||
String color2;
|
||||
final Random r = MyRandom.getRandom();
|
||||
if (maxColors.size() > 1) {
|
||||
int n = r.nextInt(maxColors.size());
|
||||
|
||||
Reference in New Issue
Block a user