From feffeea5b4304977dde639441427df0df9612f07 Mon Sep 17 00:00:00 2001 From: mcrawford620 Date: Mon, 27 Aug 2012 17:04:02 +0000 Subject: [PATCH] - improve DraftRankings to handle sets with different number of cards --- .../forge/game/limited/BoosterDraftAI.java | 64 +++++++++---------- .../java/forge/game/limited/LimitedDeck.java | 8 +-- .../forge/game/limited/ReadDraftRankings.java | 26 ++++++-- .../java/forge/ReadDraftRankingsTest.java | 8 +-- 4 files changed, 61 insertions(+), 45 deletions(-) diff --git a/src/main/java/forge/game/limited/BoosterDraftAI.java b/src/main/java/forge/game/limited/BoosterDraftAI.java index 92a0cf00e40..4e947ed8de3 100644 --- a/src/main/java/forge/game/limited/BoosterDraftAI.java +++ b/src/main/java/forge/game/limited/BoosterDraftAI.java @@ -77,32 +77,14 @@ public class BoosterDraftAI { List 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 rankedCards = new TreeMap(); - 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 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 rankedPlayableCards = new TreeMap(); - for (CardPrinted card : aiPlayables) { - Integer rkg = draftRankings.getRanking(card.getName(), card.getEdition()); - if (rkg != null) { - rankedPlayableCards.put(rkg, card); - } - } + TreeMap 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 rankedPlayableCards = new TreeMap(); + TreeMap rankedPlayableCards = new TreeMap(); 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 colorList = hasColor.select(aiPlayables, CardPrinted.FN_GET_RULES); // Sort playable, on-color cards by rank - TreeMap rankedPlayableCards = new TreeMap(); - for (CardPrinted card : colorList) { - Integer rkg = draftRankings.getRanking(card.getName(), card.getEdition()); - if (rkg != null) { - rankedPlayableCards.put(rkg, card); - } - } + TreeMap 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 rankCards(final List chooseFrom) { + TreeMap rankedCards = new TreeMap(); + 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 rankedCards, - TreeMap rankedPlayableCards) { + private CardPrinted pickCard(TreeMap rankedCards, + TreeMap rankedPlayableCards) { CardPrinted pickedCard = null; - Map.Entry best = rankedCards.firstEntry(); + Map.Entry 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 bestPlayable = rankedPlayableCards.firstEntry(); + Map.Entry bestPlayable = rankedPlayableCards.firstEntry(); if (bestPlayable == null) { // Nothing is playable, so just take the best card. pickedCard = best.getValue(); diff --git a/src/main/java/forge/game/limited/LimitedDeck.java b/src/main/java/forge/game/limited/LimitedDeck.java index 91c4c5f677d..0856eb85eb8 100644 --- a/src/main/java/forge/game/limited/LimitedDeck.java +++ b/src/main/java/forge/game/limited/LimitedDeck.java @@ -641,7 +641,7 @@ public class LimitedDeck { protected List rankCards(List cards) { List ranked = new ArrayList(); 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; } diff --git a/src/main/java/forge/game/limited/ReadDraftRankings.java b/src/main/java/forge/game/limited/ReadDraftRankings.java index 10b73528699..e013cb41764 100644 --- a/src/main/java/forge/game/limited/ReadDraftRankings.java +++ b/src/main/java/forge/game/limited/ReadDraftRankings.java @@ -23,6 +23,7 @@ public class ReadDraftRankings { private static final String COMMENT = "//"; private Map> draftRankings; + private Map setSizes; /** *

@@ -39,6 +40,7 @@ public class ReadDraftRankings { *

*/ private void setup() { + this.setSizes = new HashMap(); this.draftRankings = this.readFile(ForgeProps.getFile(NewConstants.Draft.RANKINGS)); } // setup() @@ -74,6 +76,11 @@ public class ReadDraftRankings { map.put(edition, new HashMap()); } 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; } diff --git a/src/test/java/forge/ReadDraftRankingsTest.java b/src/test/java/forge/ReadDraftRankingsTest.java index 0065cd6c144..e16db9c198a 100644 --- a/src/test/java/forge/ReadDraftRankingsTest.java +++ b/src/test/java/forge/ReadDraftRankingsTest.java @@ -30,22 +30,22 @@ public class ReadDraftRankingsTest { List 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()); } }