package magic.data; import java.util.Collection; import magic.generator.RandomDeckGenerator; import magic.model.MagicCardDefinition; import magic.model.MagicColor; import magic.model.MagicDeck; import magic.model.MagicDeckProfile; public class DeckGenerator { public int deckSize = MagicDeck.DEFAULT_SIZE; // percentage of deck size allocated to non-land cards. public int spellsPercent = 60; // maximum percentage of spells allocated to creature cards. public int maxCreaturesPercent = 66; // maximum random colors to use in deck. public int maxColors = 2; private MagicDeckProfile deckProfile; private MagicDeck deck; public int getSpellsCount() { return (int)(deckSize * ((double)spellsPercent / 100)); } public int getMaxCreaturesCount() { return (int)(getSpellsCount() * ((double)maxCreaturesPercent / 100)); } public int getLandsCount() { return deckSize - getSpellsCount(); } public void setDeckProfile(final MagicDeckProfile profile) { this.deckProfile = profile; } public MagicDeckProfile getDeckProfile() { return deckProfile; } public void setDeck(final MagicDeck deck) { this.deck = deck; } public MagicDeck getDeck() { return deck; } public MagicDeck getRandomDeck(final Collection<MagicCardDefinition> cardPool) { final MagicFormat cubeDefinition = MagicCustomFormat.create(cardPool); final RandomDeckGenerator generator = new RandomDeckGenerator(cubeDefinition); deck = new MagicDeck(); deckProfile = MagicDeckProfile.getDeckProfile(getColorText()); generator.generateDeck(this); addBasicLandsToDeck(deck, deckProfile, deckSize); return deck; } private String getColorText() { if (maxColors == 1) { return MagicDeckProfile.ANY_ONE; } else if (maxColors == 2) { return MagicDeckProfile.ANY_TWO; } else if (maxColors == 3) { return MagicDeckProfile.ANY_THREE; } else { throw new IndexOutOfBoundsException("maxColors = " + maxColors); } } public static void addBasicLandsToDeck(final MagicDeck newDeck, final MagicDeckProfile deckProfile, final int deckSize) { final int MIN_SOURCE = 16; // Calculate statistics per color. final int[] colorCount = new int[MagicColor.NR_COLORS]; final int[] colorSource = new int[MagicColor.NR_COLORS]; for (final MagicCardDefinition cardDefinition : newDeck) { if (cardDefinition.isLand()) { for (final MagicColor color : MagicColor.values()) { colorSource[color.ordinal()] += cardDefinition.getManaSource(color); } } else { final int colorFlags = cardDefinition.getColorFlags(); for (final MagicColor color : deckProfile.getColors()) { if (color.hasColor(colorFlags)) { colorCount[color.ordinal()]++; } } } } // Add optimal basic lands to deck. while (newDeck.size() < deckSize) { MagicColor bestColor = null; int lowestRatio = Integer.MAX_VALUE; for (final MagicColor color : MagicColor.values()) { final int index = color.ordinal(); final int count = colorCount[index]; if (count > 0) { final int source = colorSource[index]; final int ratio; if (source < MIN_SOURCE) { ratio = source - count; } else { ratio = source * 100 / count; } if (ratio < lowestRatio) { lowestRatio = ratio; bestColor = color; } } } // fix for issue 446 (http://code.google.com/p/magarena/issues/detail?id=446). if (bestColor == null) { bestColor = MagicColor.getColor(MagicColor.getRandomColors(1).charAt(0)); } final MagicCardDefinition landCard = CardDefinitions.getBasicLand(bestColor); colorSource[bestColor.ordinal()] += landCard.getManaSource(bestColor); newDeck.add(landCard); } } }