mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 11:18:01 +00:00
- improve DraftRankings to handle sets with different number of cards
This commit is contained in:
@@ -77,32 +77,14 @@ public class BoosterDraftAI {
|
||||
List<CardPrinted> aiPlayables = CardRules.Predicates.IS_KEPT_IN_AI_DECKS.select(chooseFrom,
|
||||
CardPrinted.FN_GET_RULES);
|
||||
|
||||
// Sort cards by rank.
|
||||
// Note that if pack has cards from different editions, they could have
|
||||
// the same Integer rank.
|
||||
// In that (hopefully rare) case, only one will end up in the Map.
|
||||
TreeMap<Integer, CardPrinted> rankedCards = new TreeMap<Integer, CardPrinted>();
|
||||
for (CardPrinted card : chooseFrom) {
|
||||
Integer rkg = draftRankings.getRanking(card.getName(), card.getEdition());
|
||||
if (rkg != null) {
|
||||
rankedCards.put(rkg, card);
|
||||
} else {
|
||||
System.out.println("Draft Rankings - Card Not Found: " + card.getName());
|
||||
}
|
||||
}
|
||||
TreeMap<Double, CardPrinted> rankedCards = rankCards(chooseFrom);
|
||||
|
||||
if (this.playerColors.get(player).getColor1().equals("none")
|
||||
&& this.playerColors.get(player).getColor2().equals("none")) {
|
||||
// Generally the first pick of the draft, no colors selected yet.
|
||||
|
||||
// Sort playable cards by rank
|
||||
TreeMap<Integer, CardPrinted> rankedPlayableCards = new TreeMap<Integer, CardPrinted>();
|
||||
for (CardPrinted card : aiPlayables) {
|
||||
Integer rkg = draftRankings.getRanking(card.getName(), card.getEdition());
|
||||
if (rkg != null) {
|
||||
rankedPlayableCards.put(rkg, card);
|
||||
}
|
||||
}
|
||||
TreeMap<Double, CardPrinted> rankedPlayableCards = rankCards(aiPlayables);
|
||||
|
||||
pickedCard = pickCard(rankedCards, rankedPlayableCards);
|
||||
|
||||
@@ -157,12 +139,12 @@ public class BoosterDraftAI {
|
||||
// Has already picked one color, but not the second.
|
||||
|
||||
// Sort playable, on-color, or mono-colored, or colorless cards
|
||||
TreeMap<Integer, CardPrinted> rankedPlayableCards = new TreeMap<Integer, CardPrinted>();
|
||||
TreeMap<Double, CardPrinted> rankedPlayableCards = new TreeMap<Double, CardPrinted>();
|
||||
for (CardPrinted card : aiPlayables) {
|
||||
CardColor currentColor1 = CardColor.fromNames(this.playerColors.get(player).getColor1());
|
||||
CardColor color = card.getCard().getColor();
|
||||
if (color.isColorless() || color.sharesColorWith(currentColor1) || color.isMonoColor()) {
|
||||
Integer rkg = draftRankings.getRanking(card.getName(), card.getEdition());
|
||||
Double rkg = draftRankings.getRanking(card.getName(), card.getEdition());
|
||||
if (rkg != null) {
|
||||
rankedPlayableCards.put(rkg, card);
|
||||
}
|
||||
@@ -215,13 +197,7 @@ public class BoosterDraftAI {
|
||||
List<CardPrinted> colorList = hasColor.select(aiPlayables, CardPrinted.FN_GET_RULES);
|
||||
|
||||
// Sort playable, on-color cards by rank
|
||||
TreeMap<Integer, CardPrinted> rankedPlayableCards = new TreeMap<Integer, CardPrinted>();
|
||||
for (CardPrinted card : colorList) {
|
||||
Integer rkg = draftRankings.getRanking(card.getName(), card.getEdition());
|
||||
if (rkg != null) {
|
||||
rankedPlayableCards.put(rkg, card);
|
||||
}
|
||||
}
|
||||
TreeMap<Double, CardPrinted> rankedPlayableCards = rankCards(colorList);
|
||||
|
||||
pickedCard = pickCard(rankedCards, rankedPlayableCards);
|
||||
}
|
||||
@@ -239,6 +215,28 @@ public class BoosterDraftAI {
|
||||
return pickedCard;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort cards by rank. Note that if pack has cards from different editions,
|
||||
* they could have the same rank. In that (hopefully rare) case, only one
|
||||
* will end up in the Map.
|
||||
*
|
||||
* @param chooseFrom
|
||||
* List of cards
|
||||
* @return map of rankings
|
||||
*/
|
||||
private TreeMap<Double, CardPrinted> rankCards(final List<CardPrinted> chooseFrom) {
|
||||
TreeMap<Double, CardPrinted> rankedCards = new TreeMap<Double, CardPrinted>();
|
||||
for (CardPrinted card : chooseFrom) {
|
||||
Double rkg = draftRankings.getRanking(card.getName(), card.getEdition());
|
||||
if (rkg != null) {
|
||||
rankedCards.put(rkg, card);
|
||||
} else {
|
||||
System.out.println("Draft Rankings - Card Not Found: " + card.getName());
|
||||
}
|
||||
}
|
||||
return rankedCards;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pick a card.
|
||||
*
|
||||
@@ -246,10 +244,10 @@ public class BoosterDraftAI {
|
||||
* @param rankedPlayableCards
|
||||
* @return CardPrinted
|
||||
*/
|
||||
private CardPrinted pickCard(TreeMap<Integer, CardPrinted> rankedCards,
|
||||
TreeMap<Integer, CardPrinted> rankedPlayableCards) {
|
||||
private CardPrinted pickCard(TreeMap<Double, CardPrinted> rankedCards,
|
||||
TreeMap<Double, CardPrinted> rankedPlayableCards) {
|
||||
CardPrinted pickedCard = null;
|
||||
Map.Entry<Integer, CardPrinted> best = rankedCards.firstEntry();
|
||||
Map.Entry<Double, CardPrinted> best = rankedCards.firstEntry();
|
||||
if (best != null) {
|
||||
if (rankedPlayableCards.containsValue(best.getValue())) {
|
||||
// If best card is playable, pick it.
|
||||
@@ -258,7 +256,7 @@ public class BoosterDraftAI {
|
||||
+ pickedCard.getCard().getManaCost() + ") " + pickedCard.getType().toString());
|
||||
} else {
|
||||
// If not, find the best card that is playable.
|
||||
Map.Entry<Integer, CardPrinted> bestPlayable = rankedPlayableCards.firstEntry();
|
||||
Map.Entry<Double, CardPrinted> bestPlayable = rankedPlayableCards.firstEntry();
|
||||
if (bestPlayable == null) {
|
||||
// Nothing is playable, so just take the best card.
|
||||
pickedCard = best.getValue();
|
||||
|
||||
@@ -641,7 +641,7 @@ public class LimitedDeck {
|
||||
protected List<CardRankingBean> rankCards(List<CardPrinted> cards) {
|
||||
List<CardRankingBean> ranked = new ArrayList<CardRankingBean>();
|
||||
for (CardPrinted card : cards) {
|
||||
Integer rkg = draftRankings.getRanking(card.getName(), card.getEdition());
|
||||
Double rkg = draftRankings.getRanking(card.getName(), card.getEdition());
|
||||
if (rkg != null) {
|
||||
ranked.add(new CardRankingBean(rkg, card));
|
||||
}
|
||||
@@ -699,7 +699,7 @@ public class LimitedDeck {
|
||||
*
|
||||
*/
|
||||
protected class CardRankingBean {
|
||||
private Integer rank;
|
||||
private Double rank;
|
||||
private CardPrinted card;
|
||||
|
||||
/**
|
||||
@@ -710,7 +710,7 @@ public class LimitedDeck {
|
||||
* @param card
|
||||
* the CardPrinted
|
||||
*/
|
||||
public CardRankingBean(Integer rank, CardPrinted card) {
|
||||
public CardRankingBean(Double rank, CardPrinted card) {
|
||||
this.rank = rank;
|
||||
this.card = card;
|
||||
}
|
||||
@@ -718,7 +718,7 @@ public class LimitedDeck {
|
||||
/**
|
||||
* @return the rank
|
||||
*/
|
||||
public Integer getRank() {
|
||||
public Double getRank() {
|
||||
return rank;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ public class ReadDraftRankings {
|
||||
private static final String COMMENT = "//";
|
||||
|
||||
private Map<String, Map<String, Integer>> draftRankings;
|
||||
private Map<String, Integer> setSizes;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -39,6 +40,7 @@ public class ReadDraftRankings {
|
||||
* </p>
|
||||
*/
|
||||
private void setup() {
|
||||
this.setSizes = new HashMap<String, Integer>();
|
||||
this.draftRankings = this.readFile(ForgeProps.getFile(NewConstants.Draft.RANKINGS));
|
||||
} // setup()
|
||||
|
||||
@@ -74,6 +76,11 @@ public class ReadDraftRankings {
|
||||
map.put(edition, new HashMap<String, Integer>());
|
||||
}
|
||||
map.get(edition).put(name, rank);
|
||||
if (setSizes.containsKey(edition)) {
|
||||
setSizes.put(edition, Math.max(setSizes.get(edition), rank));
|
||||
} else {
|
||||
setSizes.put(edition, rank);
|
||||
}
|
||||
} catch (NumberFormatException nfe) {
|
||||
Log.warn("NumberFormatException: " + nfe.getMessage());
|
||||
}
|
||||
@@ -86,7 +93,9 @@ public class ReadDraftRankings {
|
||||
throw new RuntimeException("ReadDraftRankings : readFile error, " + ex);
|
||||
} finally {
|
||||
try {
|
||||
if (in != null)in.close();
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
@@ -95,11 +104,20 @@ public class ReadDraftRankings {
|
||||
return map;
|
||||
} // readFile()
|
||||
|
||||
public Integer getRanking(String cardName, String edition) {
|
||||
Integer rank = null;
|
||||
/**
|
||||
* Get the relative ranking for the given card name in the given edition.
|
||||
*
|
||||
* @param cardName
|
||||
* the card name
|
||||
* @param edition
|
||||
* the card's edition
|
||||
* @return ranking
|
||||
*/
|
||||
public Double getRanking(String cardName, String edition) {
|
||||
Double rank = null;
|
||||
if (draftRankings.containsKey(edition)) {
|
||||
String safeName = cardName.replaceAll("-", " ").replaceAll("[^A-Za-z ]", "");
|
||||
rank = draftRankings.get(edition).get(safeName);
|
||||
rank = (double) draftRankings.get(edition).get(safeName) / (double) setSizes.get(edition);
|
||||
}
|
||||
return rank;
|
||||
}
|
||||
|
||||
@@ -30,22 +30,22 @@ public class ReadDraftRankingsTest {
|
||||
List<String> cardLines = FileUtil.readFile(new File(ForgeProps.getFile(NewConstants.CARDSFOLDER) + "/g",
|
||||
"garruk_primal_hunter.txt"));
|
||||
Card c = CardReader.readCard(cardLines);
|
||||
Assert.assertEquals(1, rdr.getRanking(c.getName(), "M13").intValue());
|
||||
Assert.assertEquals(1.0 / 234.0, rdr.getRanking(c.getName(), "M13").doubleValue());
|
||||
|
||||
cardLines = FileUtil.readFile(new File(ForgeProps.getFile(NewConstants.CARDSFOLDER) + "/c", "clone.txt"));
|
||||
c = CardReader.readCard(cardLines);
|
||||
Assert.assertEquals(38, rdr.getRanking(c.getName(), "M13").intValue());
|
||||
Assert.assertEquals(38.0 / 234.0, rdr.getRanking(c.getName(), "M13").doubleValue());
|
||||
|
||||
cardLines = FileUtil.readFile(new File(ForgeProps.getFile(NewConstants.CARDSFOLDER) + "/t",
|
||||
"tamiyo_the_moon_sage.txt"));
|
||||
c = CardReader.readCard(cardLines);
|
||||
Assert.assertEquals(1, rdr.getRanking(c.getName(), "AVR").intValue());
|
||||
Assert.assertEquals(1.0 / 234.0, rdr.getRanking(c.getName(), "AVR").doubleValue());
|
||||
|
||||
// Mikaeus, the Lunarch has a comma in its name in the rankings file
|
||||
cardLines = FileUtil.readFile(new File(ForgeProps.getFile(NewConstants.CARDSFOLDER) + "/m",
|
||||
"mikaeus_the_lunarch.txt"));
|
||||
c = CardReader.readCard(cardLines);
|
||||
Assert.assertEquals(4, rdr.getRanking(c.getName(), "ISD").intValue());
|
||||
Assert.assertEquals(4.0 / 255.0, rdr.getRanking(c.getName(), "ISD").doubleValue());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user