diff --git a/src/main/java/forge/card/ColorSet.java b/src/main/java/forge/card/ColorSet.java index 7340aedb8ca..4a90290d381 100644 --- a/src/main/java/forge/card/ColorSet.java +++ b/src/main/java/forge/card/ColorSet.java @@ -58,7 +58,7 @@ public final class ColorSet implements Comparable { } public static ColorSet fromMask(final int mask) { - int mask32 = (mask & 0x3E) >> 1; + int mask32 = (mask & MagicColor.ALL_COLORS) >> 1; if (allColors[mask32] == null) { allColors[mask32] = new ColorSet((byte) mask); } diff --git a/src/main/java/forge/card/MagicColor.java b/src/main/java/forge/card/MagicColor.java index 8641afdb9df..83349c52ac5 100644 --- a/src/main/java/forge/card/MagicColor.java +++ b/src/main/java/forge/card/MagicColor.java @@ -14,7 +14,9 @@ public class MagicColor { public static final byte RED = 1 << 4; public static final byte WHITE = 1 << 1; - + public static final byte ALL_COLORS = BLACK | BLUE | WHITE | RED | GREEN; + public static final int NUMBER_OR_COLORS = 5; + public static byte fromName(String s) { if (s.equalsIgnoreCase(Constant.Color.WHITE) || s.equalsIgnoreCase("w")) { diff --git a/src/main/java/forge/card/spellability/AbilityManaPart.java b/src/main/java/forge/card/spellability/AbilityManaPart.java index bb3e7410931..e4a01a8eaea 100644 --- a/src/main/java/forge/card/spellability/AbilityManaPart.java +++ b/src/main/java/forge/card/spellability/AbilityManaPart.java @@ -115,13 +115,11 @@ public class AbilityManaPart implements java.io.Serializable { for (final String c : produced.split(" ")) { try { int colorlessAmount = Integer.parseInt(c); - final String color = InputPayManaCostUtil.getLongColorString(c); for (int i = 0; i < colorlessAmount; i++) { - this.lastProduced.add(new Mana(color, source, this)); + this.lastProduced.add(new Mana(c, source, this)); } } catch (NumberFormatException e) { - final String color = InputPayManaCostUtil.getLongColorString(c); - this.lastProduced.add(new Mana(color, source, this)); + this.lastProduced.add(new Mana(c, source, this)); } } diff --git a/src/main/java/forge/game/limited/BoosterDraftAI.java b/src/main/java/forge/game/limited/BoosterDraftAI.java index ab43fd7266c..1be2b45bdb5 100644 --- a/src/main/java/forge/game/limited/BoosterDraftAI.java +++ b/src/main/java/forge/game/limited/BoosterDraftAI.java @@ -19,23 +19,13 @@ package forge.game.limited; import java.util.ArrayList; import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.TreeMap; +import org.apache.commons.lang3.tuple.Pair; -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.Constant; import forge.Constant.Preferences; import forge.card.ColorSet; -import forge.card.CardRulesPredicates; -import forge.card.CardRules; import forge.deck.Deck; -import forge.deck.generate.GenerateDeckUtil; import forge.item.CardPrinted; +import forge.util.Aggregates; /** *

@@ -79,141 +69,50 @@ public class BoosterDraftAI { System.out.println("Player[" + player + "] pack: " + chooseFrom.toString()); } - CardPrinted pickedCard = null; + DeckColors deckCols = this.playerColors.get(player); + ColorSet currentChoice = deckCols.getChosenColors(); + boolean canAddMoreColors = deckCols.canChoseMoreColors(); + + List> rankedCards = rankCards(chooseFrom); + + for(Pair p : rankedCards) { + // If a card is not ai playable, somewhat decreare its rating + if( p.getKey().getCard().getRemAIDecks() ) + p.setValue(p.getValue() - TAKE_BEST_THRESHOLD); - Predicate pred = Predicates.compose(CardRulesPredicates.IS_KEPT_IN_AI_DECKS, CardPrinted.FN_GET_RULES); - Iterable aiPlayablesView = Iterables.filter(chooseFrom, pred); - List aiPlayables = Lists.newArrayList(aiPlayablesView); - - 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 = rankCards(aiPlayables); - - pickedCard = pickCard(rankedCards, rankedPlayableCards); - - if (!pickedCard.getCard().getColor().isColorless() && aiPlayables.contains(pickedCard)) { - ColorSet color = pickedCard.getCard().getColor(); - if (color.isMonoColor()) { - this.playerColors.get(player).setColor1(color.toString()); - } else { - // Arbitrary ordering here... - if (color.hasWhite()) { - this.playerColors.get(player).setColor1(Constant.Color.WHITE); - } - if (color.hasBlue()) { - if (this.playerColors.get(player).getColor1().equals("none")) { - this.playerColors.get(player).setColor1(Constant.Color.BLUE); - } else { - this.playerColors.get(player).setColor2(Constant.Color.BLUE); - } - } - if (color.hasBlack()) { - if (this.playerColors.get(player).getColor1().equals("none")) { - this.playerColors.get(player).setColor1(Constant.Color.BLACK); - } else { - this.playerColors.get(player).setColor2(Constant.Color.BLACK); - } - } - if (color.hasRed()) { - if (this.playerColors.get(player).getColor1().equals("none")) { - this.playerColors.get(player).setColor1(Constant.Color.RED); - } else { - this.playerColors.get(player).setColor2(Constant.Color.RED); - } - } - if (color.hasGreen()) { - if (this.playerColors.get(player).getColor1().equals("none")) { - this.playerColors.get(player).setColor1(Constant.Color.GREEN); - } else { - this.playerColors.get(player).setColor2(Constant.Color.GREEN); - } - } - } - if (Preferences.DEV_MODE) { - System.out.println("Player[" + player + "] Color1: " + this.playerColors.get(player).getColor1()); - if (!this.playerColors.get(player).getColor2().equals("none")) { - System.out.println("Player[" + player + "] Color2: " - + this.playerColors.get(player).getColor2()); - } - } - } - } else if (!this.playerColors.get(player).getColor1().equals("none") - && this.playerColors.get(player).getColor2().equals("none")) { - // Has already picked one color, but not the second. - - // Sort playable, on-color, or mono-colored, or colorless cards - TreeMap rankedPlayableCards = new TreeMap(); - for (CardPrinted card : aiPlayables) { - ColorSet currentColor1 = ColorSet.fromNames(this.playerColors.get(player).getColor1()); - ColorSet color = card.getCard().getColor(); - if (color.isColorless() || color.sharesColorWith(currentColor1) || color.isMonoColor()) { - Double rkg = draftRankings.getRanking(card.getName(), card.getEdition()); - if (rkg != null) { - rankedPlayableCards.put(rkg, card); - } else { - rankedPlayableCards.put(0.0, card); - } - } - } - - pickedCard = pickCard(rankedCards, rankedPlayableCards); - - ColorSet color = pickedCard.getCard().getColor(); - if (!color.isColorless() && aiPlayables.contains(pickedCard)) { - ColorSet currentColor1 = ColorSet.fromNames(this.playerColors.get(player).getColor1()); - if (color.isMonoColor()) { - if (!color.sharesColorWith(currentColor1)) { - this.playerColors.get(player).setColor2(color.toString()); - } - } else { - // Arbitrary ordering... - if (color.hasWhite() && !currentColor1.isWhite()) { - this.playerColors.get(player).setColor2(Constant.Color.WHITE); - } else if (color.hasBlue() && !currentColor1.isBlue()) { - this.playerColors.get(player).setColor2(Constant.Color.BLUE); - } else if (color.hasBlack() && !currentColor1.isBlack()) { - this.playerColors.get(player).setColor2(Constant.Color.BLACK); - } else if (color.hasRed() && !currentColor1.isRed()) { - this.playerColors.get(player).setColor2(Constant.Color.RED); - } else if (color.hasGreen() && !currentColor1.isGreen()) { - this.playerColors.get(player).setColor2(Constant.Color.GREEN); - } - } - if (Preferences.DEV_MODE) { - System.out.println("Player[" + player + "] Color2: " + this.playerColors.get(player).getColor2()); - } - } - } else { - // Has already picked both colors. - DeckColors dckColors = this.playerColors.get(player); - ColorSet colors = ColorSet.fromNames(dckColors.getColor1(), dckColors.getColor2()); - Predicate hasColor = Predicates.or(new GenerateDeckUtil.CanBePaidWithColors(colors), - GenerateDeckUtil.COLORLESS_CARDS); - - Iterable colorList = Iterables.filter(aiPlayables, Predicates.compose(hasColor, CardPrinted.FN_GET_RULES)); - - // Sort playable, on-color cards by rank - TreeMap rankedPlayableCards = rankCards(colorList); - - pickedCard = pickCard(rankedCards, rankedPlayableCards); + // if I cannot choose more colors, and the card cannot be played with chosen colors, decrease its rating. + if( !canAddMoreColors && !p.getKey().getCard().getManaCost().canBePaidWithAvaliable(currentChoice)) + p.setValue(p.getValue() - 10); } - if (pickedCard == null) { - final Random r = new Random(); - pickedCard = chooseFrom.get(r.nextInt(chooseFrom.size())); + int cntBestCards = 0; + double bestRating = Double.NEGATIVE_INFINITY; + CardPrinted bestPick = null; + for(Pair p : rankedCards) { + double rating = p.getValue(); + if( rating > bestRating ) + { + bestRating = rating; + bestPick = p.getKey(); + cntBestCards = 1; + } else if ( rating == bestRating ) { + cntBestCards++; + } } - if (pickedCard != null) { - chooseFrom.remove(pickedCard); - this.deck.get(player).add(pickedCard); + if (cntBestCards > 1) { + final List possiblePick = new ArrayList(); + for(Pair p : rankedCards) { + if ( p.getValue() == bestRating ) + possiblePick.add(p.getKey()); + } + bestPick = Aggregates.random(possiblePick); } - return pickedCard; + if (canAddMoreColors) + deckCols.addColorsOf(bestPick); + + return bestPick; } /** @@ -225,69 +124,20 @@ public class BoosterDraftAI { * List of cards * @return map of rankings */ - private TreeMap rankCards(final Iterable chooseFrom) { - TreeMap rankedCards = new TreeMap(); + private List> rankCards(final Iterable chooseFrom) { + List> rankedCards = new ArrayList>(); for (CardPrinted card : chooseFrom) { Double rkg = draftRankings.getRanking(card.getName(), card.getEdition()); if (rkg != null) { - rankedCards.put(rkg, card); + rankedCards.add(Pair.of(card, rkg)); } else { System.out.println("Draft Rankings - Card Not Found: " + card.getName()); - rankedCards.put(0.0, card); + rankedCards.add(Pair.of(card, 0.0)); } } return rankedCards; } - /** - * Pick a card. - * - * @param rankedCards - * @param rankedPlayableCards - * @return CardPrinted - */ - private CardPrinted pickCard(TreeMap rankedCards, - TreeMap rankedPlayableCards) { - CardPrinted pickedCard = null; - Map.Entry best = rankedCards.firstEntry(); - if (best != null) { - if (rankedPlayableCards.containsValue(best.getValue())) { - // If best card is playable, pick it. - pickedCard = best.getValue(); - System.out.println("Choose Best: " + "[" + best.getKey() + "] " + pickedCard.getName() + " (" - + pickedCard.getCard().getManaCost() + ") " + pickedCard.getCard().getType().toString()); - } else { - // If not, find the best card that is playable. - Map.Entry bestPlayable = rankedPlayableCards.firstEntry(); - if (bestPlayable == null) { - // Nothing is playable, so just take the best card. - pickedCard = best.getValue(); - System.out.println("Nothing playable, choose Best: " + "[" + best.getKey() + "] " - + pickedCard.getName() + " (" + pickedCard.getCard().getManaCost() + ") " - + pickedCard.getCard().getType().toString()); - } else { - // If the best card is far better than the best playable, - // take the best. Otherwise, take the one that is playable. - if (best.getKey() + TAKE_BEST_THRESHOLD < bestPlayable.getKey()) { - pickedCard = best.getValue(); - System.out.println("Best is much better than playable; chose Best: " + "[" + best.getKey() - + "] " + pickedCard.getName() + " (" + pickedCard.getCard().getManaCost() + ") " - + pickedCard.getCard().getType().toString()); - System.out.println("Playable was: " + "[" + bestPlayable.getKey() + "] " - + bestPlayable.getValue().getName()); - } else { - pickedCard = bestPlayable.getValue(); - System.out.println("Chosen Playable: " + "[" + bestPlayable.getKey() + "] " - + pickedCard.getName() + " (" + pickedCard.getCard().getManaCost() + ") " - + pickedCard.getCard().getType().toString()); - System.out.println("Best was: " + "[" + best.getKey() + "] " + best.getValue().getName()); - } - } - } - } - return pickedCard; - } - /** *

* getDecks. diff --git a/src/main/java/forge/game/limited/DeckColors.java b/src/main/java/forge/game/limited/DeckColors.java index 034f2b95b4f..dee3a1a77a5 100644 --- a/src/main/java/forge/game/limited/DeckColors.java +++ b/src/main/java/forge/game/limited/DeckColors.java @@ -17,7 +17,10 @@ */ package forge.game.limited; +import forge.card.CardManaCost; import forge.card.ColorSet; +import forge.card.MagicColor; +import forge.item.CardPrinted; /** * Created by IntelliJ IDEA. User: dhudson Date: 6/24/11 Time: 8:42 PM To change @@ -25,96 +28,45 @@ import forge.card.ColorSet; */ class DeckColors { - /** The Color1. */ - private String color1 = "none"; - - /** The Color2. */ - private String color2 = "none"; - + private ColorSet chosen; + private int colorMask; + public final static int MAX_COLORS = 2; // public String Splash = "none"; - /** - *

- * Constructor for deckColors. - *

- * - * @param c1 - * a {@link java.lang.String} object. - * @param c2 - * a {@link java.lang.String} object. - * @param sp - * a {@link java.lang.String} object. - */ - public DeckColors(final String c1, final String c2, final String sp) { - this.setColor1(c1); - this.setColor2(c2); - // Splash = sp; + public ColorSet getChosenColors() { + if ( null == chosen ) + chosen = ColorSet.fromMask(colorMask); + return chosen; } /** - *

- * Constructor for DeckColors. - *

+ * TODO: Write javadoc for this method. + * @param pickedCard */ - public DeckColors() { + public void addColorsOf(CardPrinted pickedCard) { + + CardManaCost colorsInCard = pickedCard.getCard().getManaCost(); + int colorsCanAdd = MagicColor.ALL_COLORS & ~getChosenColors().getColor(); + int colorsWantAdd = colorsInCard.getColorProfile() & colorsCanAdd; + ColorSet toAdd = ColorSet.fromMask(colorsWantAdd); + + int cntColorsAssigned = getChosenColors().countColors(); + boolean haveSpace = cntColorsAssigned < MAX_COLORS; + if( !haveSpace || toAdd.isColorless() ) + return; + + for(int i = 0; i < MagicColor.NUMBER_OR_COLORS && cntColorsAssigned < MAX_COLORS; i++ ) + if (( colorsWantAdd & MagicColor.WHITE << i ) > 0) { + colorMask |= MagicColor.WHITE << i; + chosen = null; // invalidate color set + cntColorsAssigned++; + } } - /** - * Gets the color1. - * - * @return the color1 - */ - public String getColor1() { - return this.color1; - } - /** - * Sets the color1. - * - * @param color1in - * the color1 to set - */ - public void setColor1(final String color1in) { - this.color1 = color1in; - } - - /** - * Gets the color2. - * - * @return the color2 - */ - public String getColor2() { - return this.color2; - } - - /** - * Sets the color2. - * - * @param color2in - * the color2 to set - */ - public void setColor2(final String color2in) { - this.color2 = color2in; - } - - /** - * Convert this to CardColor. - * - * @return equivalent CardColor - */ - public ColorSet getCardColors() { - return ColorSet.fromNames(color1, color2); - } - - /** - * toString. - * - * @return description. - */ - @Override - public String toString() { - return color1 + '/' + color2; + public boolean canChoseMoreColors() { + return getChosenColors().countColors() < MAX_COLORS; } } diff --git a/src/main/java/forge/game/limited/LimitedDeck.java b/src/main/java/forge/game/limited/LimitedDeck.java index 77a9b8dc2b4..ace6328e368 100644 --- a/src/main/java/forge/game/limited/LimitedDeck.java +++ b/src/main/java/forge/game/limited/LimitedDeck.java @@ -66,7 +66,7 @@ public class LimitedDeck { public LimitedDeck(List dList, DeckColors pClrs) { this.availableList = dList; this.deckColors = pClrs; - this.colors = pClrs.getCardColors(); + this.colors = pClrs.getChosenColors(); // removeUnplayables(); Iterable playables = Iterables.filter(availableList,