From d1ca72d0e777950d98fc9cf2ddafc2cbb003ccf2 Mon Sep 17 00:00:00 2001 From: magenoxx Date: Thu, 30 Dec 2010 00:46:38 +0300 Subject: [PATCH] New Deck Generator that builds stronger random decks + better mana fixing. --- .../java/mage/client/cards/CardsStorage.java | 16 +- .../client/deck/generator/DeckGenerator.java | 742 ++++++++++-------- 2 files changed, 410 insertions(+), 348 deletions(-) diff --git a/Mage.Client/src/main/java/mage/client/cards/CardsStorage.java b/Mage.Client/src/main/java/mage/client/cards/CardsStorage.java index 3be58950ce1..036bacd350b 100644 --- a/Mage.Client/src/main/java/mage/client/cards/CardsStorage.java +++ b/Mage.Client/src/main/java/mage/client/cards/CardsStorage.java @@ -1,7 +1,5 @@ package mage.client.cards; -import java.awt.image.BufferedImage; -import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.LinkedHashSet; @@ -9,20 +7,14 @@ import java.util.Map; import java.util.Scanner; import java.util.Set; -import javax.imageio.ImageIO; -import javax.swing.JComponent; -import javax.swing.JLayeredPane; - import mage.cards.Card; import mage.cards.ExpansionSet; -import mage.client.plugins.impl.Plugins; -import mage.components.ImagePanel; import mage.sets.Sets; import mage.utils.CardUtil; public class CardsStorage { private static Set allCards = new LinkedHashSet(); - private static Set landCards = new LinkedHashSet(); + private static Set nonBasicLandCards = new LinkedHashSet(); private static Map ratings; private static Integer min = Integer.MAX_VALUE, max = 0; @@ -32,7 +24,7 @@ public class CardsStorage { allCards.addAll(cards); for (Card card : cards) { if (CardUtil.isLand(card) && !CardUtil.isBasicLand(card)) { - landCards.add(card); + nonBasicLandCards.add(card); } } } @@ -42,8 +34,8 @@ public class CardsStorage { return allCards; } - public static Set getLandCards() { - return landCards; + public static Set getNonBasicLandCards() { + return nonBasicLandCards; } /** diff --git a/Mage.Client/src/main/java/mage/client/deck/generator/DeckGenerator.java b/Mage.Client/src/main/java/mage/client/deck/generator/DeckGenerator.java index fc01ce9129a..015abf0d671 100644 --- a/Mage.Client/src/main/java/mage/client/deck/generator/DeckGenerator.java +++ b/Mage.Client/src/main/java/mage/client/deck/generator/DeckGenerator.java @@ -3,12 +3,7 @@ package mage.client.deck.generator; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; +import java.util.*; import javax.swing.Box; import javax.swing.BoxLayout; @@ -32,373 +27,448 @@ import mage.utils.CardUtil; public class DeckGenerator { - private static JDialog dlg; - private static String selectedColors; + private static JDialog dlg; + private static String selectedColors; - private static final int SPELL_BOOSTER_PACK_SIZE = 60; + private static final int SPELL_CARD_POOL_SIZE = 60; - private static final int DECK_COUNT[] = { 3, 6, 6, 4, 3, 2 }; - private static final int DECK_COST[] = { 1, 2, 3, 4, 6, 10 }; - private static final int DECK_SPELLS = 24; - private static final int DECK_LANDS = 16; - private static final int DECK_SIZE = DECK_SPELLS + DECK_LANDS; - private static final int MIN_CARD_SCORE = 25; - private static final int MIN_SOURCE = 16; - private static final int MAX_NON_BASIC_SOURCE = DECK_LANDS / 2; + private static final int DECK_COUNT[] = {3, 6, 6, 4, 3, 2}; + private static final int DECK_COST[] = {1, 2, 3, 4, 6, 10}; + private static final int DECK_SPELLS = 24; + private static final int DECK_LANDS = 16; + private static final int DECK_SIZE = DECK_SPELLS + DECK_LANDS; + private static final int MIN_CARD_SCORE = 25; + private static final int MIN_SOURCE = 16; + private static final int MAX_NON_BASIC_SOURCE = DECK_LANDS / 2; private static final boolean GENERATE_RANDOM_BASIC_LAND = true; + private static final int MAX_TRIES = 4096; - private static Deck deck = new Deck(); - private static String manaSource; + private static Deck deck = new Deck(); + private static String manaSource; + private static final int ADDITIONAL_CARDS_FOR_3_COLOR_DECKS = 20; - public static String generateDeck() { - JPanel p0 = new JPanel(); - p0.setLayout(new BoxLayout(p0, BoxLayout.Y_AXIS)); - JLabel text = new JLabel("Choose color for your deck: "); - p0.add(text); - p0.add(Box.createVerticalStrut(5)); - final ColorsChooser colorsChooser = new ColorsChooser("bu"); - p0.add(colorsChooser); + public static String generateDeck() { + JPanel p0 = new JPanel(); + p0.setLayout(new BoxLayout(p0, BoxLayout.Y_AXIS)); + JLabel text = new JLabel("Choose color for your deck: "); + p0.add(text); + p0.add(Box.createVerticalStrut(5)); + final ColorsChooser colorsChooser = new ColorsChooser("bu"); + p0.add(colorsChooser); - final JButton btnGenerate = new JButton("Ok"); - btnGenerate.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - btnGenerate.setEnabled(false); - colorsChooser.setEnabled(false); - selectedColors = (String) colorsChooser.getSelectedItem(); - dlg.setVisible(false); - } - }); - final JButton btnCancel = new JButton("Cancel"); - btnCancel.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - dlg.setVisible(false); - selectedColors = null; - } - }); - Object[] options = { btnGenerate, btnCancel }; - JOptionPane optionPane = new JOptionPane(p0, JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null, options, options[1]); - dlg = optionPane.createDialog("Generating deck"); - dlg.setVisible(true); - dlg.dispose(); + final JButton btnGenerate = new JButton("Ok"); + btnGenerate.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + btnGenerate.setEnabled(false); + colorsChooser.setEnabled(false); + selectedColors = (String) colorsChooser.getSelectedItem(); + dlg.setVisible(false); + } + }); + final JButton btnCancel = new JButton("Cancel"); + btnCancel.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + dlg.setVisible(false); + selectedColors = null; + } + }); + Object[] options = {btnGenerate, btnCancel}; + JOptionPane optionPane = new JOptionPane(p0, JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null, options, options[1]); + dlg = optionPane.createDialog("Generating deck"); + dlg.setVisible(true); + dlg.dispose(); - if (selectedColors != null) { - buildDeck(); - try { - File tmp = File.createTempFile("tempDeck" + UUID.randomUUID().toString(), ".dck"); - tmp.createNewFile(); - deck.setName("Generated-Deck-" + UUID.randomUUID()); - Sets.saveDeck(tmp.getAbsolutePath(), deck.getDeckCardLists()); - //JOptionPane.showMessageDialog(null, "Deck has been generated."); - return tmp.getAbsolutePath(); - } catch (Exception e) { - e.printStackTrace(); - JOptionPane.showMessageDialog(null, "Couldn't generate deck. Try once again."); - } - } + if (selectedColors != null) { + buildDeck(); + try { + File tmp = File.createTempFile("tempDeck" + UUID.randomUUID().toString(), ".dck"); + tmp.createNewFile(); + deck.setName("Generated-Deck-" + UUID.randomUUID()); + Sets.saveDeck(tmp.getAbsolutePath(), deck.getDeckCardLists()); + //JOptionPane.showMessageDialog(null, "Deck has been generated."); + return tmp.getAbsolutePath(); + } catch (Exception e) { + e.printStackTrace(); + JOptionPane.showMessageDialog(null, "Couldn't generate deck. Try once again."); + } + } - return selectedColors; - } + return selectedColors; + } - protected static void buildDeck() { - deck = new Deck(); - List allowedColors = new ArrayList(); - selectedColors = selectedColors.toUpperCase(); - for (int i = 0; i < selectedColors.length(); i++) { - char c = selectedColors.charAt(i); - allowedColors.add(ColoredManaSymbol.lookup(c)); - } + protected static void buildDeck() { + deck = new Deck(); + List allowedColors = new ArrayList(); + selectedColors = selectedColors.toUpperCase(); + for (int i = 0; i < selectedColors.length(); i++) { + char c = selectedColors.charAt(i); + allowedColors.add(ColoredManaSymbol.lookup(c)); + } - List spellCardPool = new ArrayList(); - List landCardPool = new ArrayList(); - int nonBasicLandCount = 0; - for (ExpansionSet set : Sets.getInstance().values()) { - try { - List booster = set.createBooster(); - for (Card card : booster) { - if (!card.getCardType().contains(CardType.LAND)) { - spellCardPool.add(card); - } else { - if (!CardUtil.isBasicLand(card)) { - if (nonBasicLandCount < MAX_NON_BASIC_SOURCE) { - int score = 0; - for (Mana mana : card.getMana()) { - for (ColoredManaSymbol color : allowedColors) { - score += mana.getColor(color); - } - } - if (score > 1) { - nonBasicLandCount++; - landCardPool.add(card); - } - } - } - } - } - } catch (Exception e) { - //ignore - } - } - out: - while (nonBasicLandCount < MAX_NON_BASIC_SOURCE) { - boolean found = false; - for (Card card : CardsStorage.getLandCards()) { - int score = 0; - for (Mana mana : card.getMana()) { - for (ColoredManaSymbol color : allowedColors) { - score += mana.getColor(color); - } - } - if (score > 1) { - nonBasicLandCount++; - landCardPool.add(card); - found = true; - } - if (nonBasicLandCount > MAX_NON_BASIC_SOURCE) { - break out; - } - } - if (!found) { //there is no compatible non basic land - break out; - } - } - System.out.println("deck generator card pool: spells=" + spellCardPool.size() + ", lands=" + landCardPool.size()); + int cardPoolSize = SPELL_CARD_POOL_SIZE; + if (selectedColors.length() > 2) { + cardPoolSize += ADDITIONAL_CARDS_FOR_3_COLOR_DECKS; + } + List spellCardPool = generateSpellCardPool(cardPoolSize, allowedColors); + List landCardPool = generateNonBasicLandCardPool(MAX_NON_BASIC_SOURCE, allowedColors); - final Collection remainingCards = new ArrayList(); - for (final Card card : spellCardPool) { - remainingCards.add(new MageScoredCard(card, allowedColors)); - } - int min = 0; - for (int index = 0; index < DECK_COUNT.length; index++) { - final int max = DECK_COST[index]; - addCardsToDeck(remainingCards, min, max, DECK_COUNT[index]); - min = max + 1; - } - addCardsToDeck(remainingCards, 0, 4, DECK_SPELLS - deck.getCards().size()); - addCardsToDeck(remainingCards, 5, 10, DECK_SPELLS - deck.getCards().size()); - addLandsToDeck(allowedColors, landCardPool); - } + System.out.println("deck generator card pool: spells=" + spellCardPool.size() + ", lands=" + landCardPool.size()); - private static void addCardsToDeck(final Collection remainingCards, final int minCost, final int maxCost, - final int count) { + final Collection remainingCards = new ArrayList(); + for (final Card card : spellCardPool) { + remainingCards.add(new MageScoredCard(card, allowedColors)); + } + int min = 0; + for (int index = 0; index < DECK_COUNT.length; index++) { + final int max = DECK_COST[index]; + addCardsToDeck(remainingCards, min, max, DECK_COUNT[index]); + min = max + 1; + } + addCardsToDeck(remainingCards, 0, 4, DECK_SPELLS - deck.getCards().size()); + addCardsToDeck(remainingCards, 5, 10, DECK_SPELLS - deck.getCards().size()); + addLandsToDeck(allowedColors, landCardPool); + } - for (int c = count; c > 0; c--) { + /** + * Generates card pool of cardsCount cards that have manacost of allowed colors. + * + * @param cardsCount + * @param allowedColors + * @return + */ + private static List generateSpellCardPool(int cardsCount, List allowedColors) { + List spellCardPool = new ArrayList(); - MageScoredCard bestCard = null; - int bestScore = -1; + int count = 0; + List allCards = new ArrayList(); + allCards.addAll(CardsStorage.getAllCards()); + int allCount = allCards.size(); + Random random = new Random(); + if (allCount > 0) { + int tries = 0; + while (count < cardsCount) { + Card card = allCards.get(random.nextInt(allCount)); + if (!card.getCardType().contains(CardType.LAND)) { + if (cardFitsChosenColors(card, allowedColors)) { + spellCardPool.add(card); + count++; + } + } + tries++; + if (tries > MAX_TRIES) { // to avoid infinite loop + throw new IllegalStateException("Not enough cards for chosen colors to generate deck: " + selectedColors); + } + } + } else { + throw new IllegalStateException("Not enough cards to generate deck."); + } - for (final MageScoredCard draftedCard : remainingCards) { + return spellCardPool; + } - final int score = draftedCard.getScore(); - final int cost = draftedCard.getConvertedCost(); - if (score > bestScore && cost >= minCost && cost <= maxCost) { - bestScore = score; - bestCard = draftedCard; - } - } + /** + * Check that card can be played using chosen (allowed) colors. + * + * @param card + * @param allowedColors + * @return + */ + private static boolean cardFitsChosenColors(Card card, List allowedColors) { + for (String symbol : card.getManaCost().getSymbols()) { + boolean found = false; + symbol = symbol.replace("{", "").replace("}", ""); + if (isColoredMana(symbol)) { + for (ColoredManaSymbol allowed : allowedColors) { + if (allowed.toString().equals(symbol)) { + found = true; + break; + } + } + if (!found) { + return false; + } + } + } + return true; + } - if (bestCard == null || bestScore < MIN_CARD_SCORE) { - break; - } - deck.getCards().add(bestCard.card); - remainingCards.remove(bestCard); - } - } + /** + * Generates card pool of land cards that can produce allowed colors. + * + * @param landsCount + * @param allowedColors + * @return + */ + private static List generateNonBasicLandCardPool(int landsCount, List allowedColors) { + List nonBasicLandCardPool = new ArrayList(); - private static void addLandsToDeck(List allowedColors, List landCardPool) { + int count = 0; + List landCards = new ArrayList(); + landCards.addAll(CardsStorage.getNonBasicLandCards()); + int allCount = landCards.size(); + Random random = new Random(); + if (allCount > 0) { + int tries = 0; + while (count < landsCount) { + Card card = landCards.get(random.nextInt(allCount)); + if (!CardUtil.isBasicLand(card)) { + if (cardCardProduceChosenColors(card, allowedColors)) { + nonBasicLandCardPool.add(card); + count++; + } + } + tries++; + if (tries > MAX_TRIES) { // to avoid infinite loop + // return what have been found + return nonBasicLandCardPool; + } + } + } - // Calculate statistics per color. - final Map colorCount = new HashMap(); - for (final Card card : deck.getCards()) { + return nonBasicLandCardPool; + } - for (String symbol : card.getManaCost().getSymbols()) { - int count = 0; - symbol = symbol.replace("{", "").replace("}", ""); - if (isColoredMana(symbol)) { - for (ColoredManaSymbol allowed : allowedColors) { - if (allowed.toString().equals(symbol)) { - count++; - } - } - if (count > 0) { - Integer typeCount = colorCount.get(symbol); - if (typeCount == null) { - typeCount = new Integer(0); - } - typeCount += 1; - colorCount.put(symbol, typeCount); - } - } - } - } - - // Add suitable non basic lands to deck in order of pack. - final Map colorSource = new HashMap(); - for (final ColoredManaSymbol color : ColoredManaSymbol.values()) { - colorSource.put(color.toString(), 0); - } - for (final Card landCard : landCardPool) { - deck.getCards().add(landCard); - for (Mana mana : landCard.getMana()) { - for (ColoredManaSymbol color : allowedColors) { - int amount = mana.getColor(color); - if (amount > 0) { - Integer count = colorSource.get(color.toString()); - count += amount; - colorSource.put(color.toString(), count); - } - } - } + /** + * Checks that chosen card can produce mana of specific color. + * + * @param card + * @param allowedColors + * @return + */ + private static boolean cardCardProduceChosenColors(Card card, List allowedColors) { + int score = 0; + for (Mana mana : card.getMana()) { + for (ColoredManaSymbol color : allowedColors) { + score += mana.getColor(color); + } + } + if (score > 1) { + return true; + } + return false; + } - } + private static void addCardsToDeck(final Collection remainingCards, final int minCost, final int maxCost, + final int count) { - // Add optimal basic lands to deck. - while (deck.getCards().size() < DECK_SIZE) { + for (int c = count; c > 0; c--) { - ColoredManaSymbol bestColor = null; - int lowestRatio = Integer.MAX_VALUE; - for (final ColoredManaSymbol color : ColoredManaSymbol.values()) { + MageScoredCard bestCard = null; + int bestScore = -1; - final Integer count = colorCount.get(color.toString()); - if (count != null && count > 0) { - final int source = colorSource.get(color.toString()); - final int ratio; - if (source < MIN_SOURCE) { - ratio = source - count; - } else { - ratio = source * 100 / count; - } - if (ratio < lowestRatio) { - lowestRatio = ratio; - bestColor = color; - } - } - } - final Card landCard = getBestBasicLand(bestColor); - Integer count = colorSource.get(bestColor.toString()); - count++; - colorSource.put(bestColor.toString(), count); - deck.getCards().add(landCard); - } - } - - private static Card getBestBasicLand(ColoredManaSymbol color) { - manaSource = color.toString(); - if (color.equals(ColoredManaSymbol.G)) { - return CardImpl.createCard(Sets.findCard("Forest", GENERATE_RANDOM_BASIC_LAND)); - } - if (color.equals(ColoredManaSymbol.R)) { - return CardImpl.createCard(Sets.findCard("Mountain", GENERATE_RANDOM_BASIC_LAND)); - } - if (color.equals(ColoredManaSymbol.B)) { - return CardImpl.createCard(Sets.findCard("Swamp", GENERATE_RANDOM_BASIC_LAND)); - } - if (color.equals(ColoredManaSymbol.U)) { - return CardImpl.createCard(Sets.findCard("Island", GENERATE_RANDOM_BASIC_LAND)); - } - if (color.equals(ColoredManaSymbol.W)) { - return CardImpl.createCard(Sets.findCard("Plains", GENERATE_RANDOM_BASIC_LAND)); - } + for (final MageScoredCard draftedCard : remainingCards) { - return null; - } + final int score = draftedCard.getScore(); + final int cost = draftedCard.getConvertedCost(); + if (score > bestScore && cost >= minCost && cost <= maxCost) { + bestScore = score; + bestCard = draftedCard; + } + } - private static class MageScoredCard { + if (bestCard == null || bestScore < MIN_CARD_SCORE) { + break; + } + deck.getCards().add(bestCard.card); + remainingCards.remove(bestCard); + } + } - private Card card; - private int score; + private static void addLandsToDeck(List allowedColors, List landCardPool) { - private static final int SINGLE_PENALTY[] = { 0, 1, 1, 3, 6, 9 }; - //private static final int DOUBLE_PENALTY[] = { 0, 0, 1, 2, 4, 6 }; + // Calculate statistics per color. + final Map colorCount = new HashMap(); + for (final Card card : deck.getCards()) { - public MageScoredCard(Card card, List allowedColors) { - this.card = card; + for (String symbol : card.getManaCost().getSymbols()) { + int count = 0; + symbol = symbol.replace("{", "").replace("}", ""); + if (isColoredMana(symbol)) { + for (ColoredManaSymbol allowed : allowedColors) { + if (allowed.toString().equals(symbol)) { + count++; + } + } + if (count > 0) { + Integer typeCount = colorCount.get(symbol); + if (typeCount == null) { + typeCount = new Integer(0); + } + typeCount += 1; + colorCount.put(symbol, typeCount); + } + } + } + } - int type = 0; - if (card.getCardType().contains(CardType.CREATURE)) { - type = 10; - } else if (card.getSubtype().contains("Equipment")) { - type = 8; - } else if (card.getSubtype().contains("Aura")) { - type = 5; - } else if (card.getCardType().contains(CardType.INSTANT)) { - type = 7; - } else { - type = 6; - } + // Add suitable non basic lands to deck in order of pack. + final Map colorSource = new HashMap(); + for (final ColoredManaSymbol color : ColoredManaSymbol.values()) { + colorSource.put(color.toString(), 0); + } + for (final Card landCard : landCardPool) { + deck.getCards().add(landCard); + for (Mana mana : landCard.getMana()) { + for (ColoredManaSymbol color : allowedColors) { + int amount = mana.getColor(color); + if (amount > 0) { + Integer count = colorSource.get(color.toString()); + count += amount; + colorSource.put(color.toString(), count); + } + } + } - this.score = - // 5*card.getValue() + // not possible now - 3 * CardsStorage.rateCard(card) + - // 3*card.getRemoval() + // not possible now - type + getManaCostScore(card, allowedColors); - } + } - private int getManaCostScore(Card card, List allowedColors) { - int converted = card.getManaCost().convertedManaCost(); - final Map singleCount = new HashMap(); - int maxSingleCount = 0; - for (String symbol : card.getManaCost().getSymbols()) { - int count = 0; - symbol = symbol.replace("{", "").replace("}", ""); - if (isColoredMana(symbol)) { - for (ColoredManaSymbol allowed : allowedColors) { - if (allowed.toString().equals(symbol)) { - count++; - } - } - if (count == 0) { - return -30; - } - Integer typeCount = singleCount.get(symbol); - if (typeCount == null) { - typeCount = new Integer(0); - } - typeCount += 1; - singleCount.put(symbol, typeCount); - maxSingleCount = Math.max(maxSingleCount, typeCount); - } - } - return 2 * converted + 3 * (10 - SINGLE_PENALTY[maxSingleCount]/*-DOUBLE_PENALTY[doubleCount]*/); - } + // Add optimal basic lands to deck. + while (deck.getCards().size() < DECK_SIZE) { - public int getScore() { - return this.score; - } + ColoredManaSymbol bestColor = null; + int lowestRatio = Integer.MAX_VALUE; + for (final ColoredManaSymbol color : ColoredManaSymbol.values()) { - public int getConvertedCost() { - return this.card.getManaCost().convertedManaCost(); - } + final Integer count = colorCount.get(color.toString()); + if (count != null && count > 0) { + final int source = colorSource.get(color.toString()); + final int ratio; + if (source < MIN_SOURCE) { + ratio = source - count; + } else { + ratio = source * 100 / count; + } + if (ratio < lowestRatio) { + lowestRatio = ratio; + bestColor = color; + } + } + } + final Card landCard = getBestBasicLand(bestColor); + Integer count = colorSource.get(bestColor.toString()); + count++; + colorSource.put(bestColor.toString(), count); + deck.getCards().add(landCard); + } + } - public Card getCard() { - return this.card; - } - } + private static Card getBestBasicLand(ColoredManaSymbol color) { + manaSource = color.toString(); + if (color.equals(ColoredManaSymbol.G)) { + return CardImpl.createCard(Sets.findCard("Forest", GENERATE_RANDOM_BASIC_LAND)); + } + if (color.equals(ColoredManaSymbol.R)) { + return CardImpl.createCard(Sets.findCard("Mountain", GENERATE_RANDOM_BASIC_LAND)); + } + if (color.equals(ColoredManaSymbol.B)) { + return CardImpl.createCard(Sets.findCard("Swamp", GENERATE_RANDOM_BASIC_LAND)); + } + if (color.equals(ColoredManaSymbol.U)) { + return CardImpl.createCard(Sets.findCard("Island", GENERATE_RANDOM_BASIC_LAND)); + } + if (color.equals(ColoredManaSymbol.W)) { + return CardImpl.createCard(Sets.findCard("Plains", GENERATE_RANDOM_BASIC_LAND)); + } - protected static boolean isColoredMana(String symbol) { - return symbol.equals("W") || symbol.equals("G") || symbol.equals("U") || symbol.equals("B") || symbol.equals("R"); - } + return null; + } - public static void main(String[] args) { - for (Card card : CardsStorage.getAllCards()) { - System.out.println(card.getName()); - System.out.print(" "); - for (String symbol : card.getManaCost().getSymbols()) { - symbol = symbol.replace("{", "").replace("}", ""); - System.out.print(symbol + " "); - } - System.out.println(CardUtil.isBasicLand(card)); - List allowedColors = new ArrayList(); - allowedColors.add(ColoredManaSymbol.lookup('B')); - allowedColors.add(ColoredManaSymbol.lookup('G')); - DeckGenerator.MageScoredCard m = new DeckGenerator.MageScoredCard(card, allowedColors); + private static class MageScoredCard { - System.out.println(); - System.out.println(" score: " + m.getScore()); - System.out.println(); - } - - //System.out.println("Done! Path: " + generateDeck()); - - } + private Card card; + private int score; + + private static final int SINGLE_PENALTY[] = {0, 1, 1, 3, 6, 9}; + //private static final int DOUBLE_PENALTY[] = { 0, 0, 1, 2, 4, 6 }; + + public MageScoredCard(Card card, List allowedColors) { + this.card = card; + + int type = 0; + if (card.getCardType().contains(CardType.CREATURE)) { + type = 10; + } else if (card.getSubtype().contains("Equipment")) { + type = 8; + } else if (card.getSubtype().contains("Aura")) { + type = 5; + } else if (card.getCardType().contains(CardType.INSTANT)) { + type = 7; + } else { + type = 6; + } + + this.score = + // 5*card.getValue() + // not possible now + 3 * CardsStorage.rateCard(card) + + // 3*card.getRemoval() + // not possible now + type + getManaCostScore(card, allowedColors); + } + + private int getManaCostScore(Card card, List allowedColors) { + int converted = card.getManaCost().convertedManaCost(); + final Map singleCount = new HashMap(); + int maxSingleCount = 0; + for (String symbol : card.getManaCost().getSymbols()) { + int count = 0; + symbol = symbol.replace("{", "").replace("}", ""); + if (isColoredMana(symbol)) { + for (ColoredManaSymbol allowed : allowedColors) { + if (allowed.toString().equals(symbol)) { + count++; + } + } + if (count == 0) { + return -30; + } + Integer typeCount = singleCount.get(symbol); + if (typeCount == null) { + typeCount = new Integer(0); + } + typeCount += 1; + singleCount.put(symbol, typeCount); + maxSingleCount = Math.max(maxSingleCount, typeCount); + } + } + return 2 * converted + 3 * (10 - SINGLE_PENALTY[maxSingleCount]/*-DOUBLE_PENALTY[doubleCount]*/); + } + + public int getScore() { + return this.score; + } + + public int getConvertedCost() { + return this.card.getManaCost().convertedManaCost(); + } + + public Card getCard() { + return this.card; + } + } + + protected static boolean isColoredMana(String symbol) { + return symbol.equals("W") || symbol.equals("G") || symbol.equals("U") || symbol.equals("B") || symbol.equals("R"); + } + + public static void main(String[] args) { + for (Card card : CardsStorage.getAllCards()) { + System.out.println(card.getName()); + System.out.print(" "); + for (String symbol : card.getManaCost().getSymbols()) { + symbol = symbol.replace("{", "").replace("}", ""); + System.out.print(symbol + " "); + } + System.out.println(CardUtil.isBasicLand(card)); + List allowedColors = new ArrayList(); + allowedColors.add(ColoredManaSymbol.lookup('B')); + allowedColors.add(ColoredManaSymbol.lookup('G')); + DeckGenerator.MageScoredCard m = new DeckGenerator.MageScoredCard(card, allowedColors); + + System.out.println(); + System.out.println(" score: " + m.getScore()); + System.out.println(); + } + + //System.out.println("Done! Path: " + generateDeck()); + + } }