diff --git a/src/main/java/forge/game/limited/BoosterDraft.java b/src/main/java/forge/game/limited/BoosterDraft.java index ab08aae76c0..6b10a7439f9 100644 --- a/src/main/java/forge/game/limited/BoosterDraft.java +++ b/src/main/java/forge/game/limited/BoosterDraft.java @@ -275,18 +275,9 @@ public final class BoosterDraft implements IBoosterDraft { for (final CardPrinted cr : booster) { forAi.add(cr.toForgeCard()); } - // TODO: Please write this drafting code to work without heavy card - // objects - final Card aiPick = this.draftAI.choose(forAi, iPlayer++); - final String pickedName = aiPick.getName(); - for (int pick = booster.size() - 1; pick >= 0; pick--) { - final CardPrinted cp = booster.get(pick); - if (cp.getName().equalsIgnoreCase(pickedName)) { - booster.remove(pick); - break; - } - } + final CardPrinted aiPick = this.draftAI.choose(booster, iPlayer++); + booster.remove(aiPick); } } // computerChoose() diff --git a/src/main/java/forge/game/limited/BoosterDraftAI.java b/src/main/java/forge/game/limited/BoosterDraftAI.java index ecf9cb6499d..0fc08d5d95c 100644 --- a/src/main/java/forge/game/limited/BoosterDraftAI.java +++ b/src/main/java/forge/game/limited/BoosterDraftAI.java @@ -18,19 +18,22 @@ package forge.game.limited; import java.util.ArrayList; +import java.util.List; import java.util.Map; import java.util.Random; import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; -import forge.Card; import forge.CardList; -import forge.CardListFilter; -import forge.CardUtil; import forge.Constant; +import forge.card.CardColor; +import forge.card.CardRules; import forge.deck.Deck; +import forge.deck.generate.GenerateDeckUtil; +import forge.item.CardPrinted; import forge.util.MyRandom; +import forge.util.closures.Predicate; /** *

@@ -68,38 +71,28 @@ public class BoosterDraftAI { *

* * @param chooseFrom - * a {@link forge.CardList} object. + * List of CardPrinted * @param player * a int. * @return a {@link forge.CardList} object. */ - public Card choose(final CardList chooseFrom, final int player) { - // in_choose should ONLY be on the RIGHT side of any equal sign - // only 1 card should be removed from in_choose - + public CardPrinted choose(final List chooseFrom, final int player) { if (Constant.Runtime.DEV_MODE[0]) { System.out.println("Player[" + player + "] pack: " + chooseFrom.toString()); - System.out.println("Set Code: " + chooseFrom.get(0).getCurSetCode()); } - Card pickedCard = null; + CardPrinted pickedCard = null; - final CardList aiPlayables = chooseFrom.filter(new CardListFilter() { - @Override - public boolean addCard(final Card c) { - boolean unPlayable = c.getSVar("RemAIDeck").equals("True"); - unPlayable |= c.getSVar("RemRandomDeck").equals("True") && c.getSVar("DeckWants").equals(""); - return !unPlayable; - } - }); + 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 (Card card : chooseFrom) { - Integer rkg = draftRankings.getRanking(card.getName(), card.getCurSetCode()); + TreeMap rankedCards = new TreeMap(); + for (CardPrinted card : chooseFrom) { + Integer rkg = draftRankings.getRanking(card.getName(), card.getEdition()); if (rkg != null) { rankedCards.put(rkg, card); } else { @@ -112,9 +105,9 @@ public class BoosterDraftAI { // Generally the first pick of the draft, no colors selected yet. // Sort playable cards by rank - TreeMap rankedPlayableCards = new TreeMap(); - for (Card card : aiPlayables) { - Integer rkg = draftRankings.getRanking(card.getName(), card.getCurSetCode()); + TreeMap rankedPlayableCards = new TreeMap(); + for (CardPrinted card : aiPlayables) { + Integer rkg = draftRankings.getRanking(card.getName(), card.getEdition()); if (rkg != null) { rankedPlayableCards.put(rkg, card); } @@ -122,23 +115,54 @@ public class BoosterDraftAI { pickedCard = pickCard(rankedCards, rankedPlayableCards); - if (!pickedCard.isColorless() && aiPlayables.contains(pickedCard)) { - this.playerColors.get(player).setColor1(pickedCard.getColor().get(0).toStringArray().get(0)); + if (!pickedCard.getCard().getColor().isColorless() && aiPlayables.contains(pickedCard)) { + CardColor 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 (Constant.Runtime.DEV_MODE[0]) { System.out.println("Player[" + player + "] Color1: " + this.playerColors.get(player).getColor1()); - } - this.playerColors.get(player).setMana1( - this.playerColors.get(player).colorToMana(this.playerColors.get(player).getColor1())); - - // if the first pick has more than one color add the second as - // second color to draft - if (pickedCard.getColor().get(0).toStringArray().size() > 1) { - this.playerColors.get(player).setColor2(pickedCard.getColor().get(0).toStringArray().get(1)); - if (Constant.Runtime.DEV_MODE[0]) { + if (!this.playerColors.get(player).getColor2().equals("none")) { System.out.println("Player[" + player + "] Color2: " + this.playerColors.get(player).getColor2()); } - + } + this.playerColors.get(player).setMana1( + this.playerColors.get(player).colorToMana(this.playerColors.get(player).getColor1())); + if (!this.playerColors.get(player).getColor2().equals("none")) { this.playerColors.get(player).setMana2( this.playerColors.get(player).colorToMana(this.playerColors.get(player).getColor2())); } @@ -148,11 +172,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(); - for (Card card : aiPlayables) { - if (card.isColorless() || CardUtil.isColor(card, this.playerColors.get(player).getColor1()) - || CardUtil.getColors(card).size() == 1) { - Integer rkg = draftRankings.getRanking(card.getName(), card.getCurSetCode()); + 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()); if (rkg != null) { rankedPlayableCards.put(rkg, card); } @@ -161,28 +186,55 @@ public class BoosterDraftAI { pickedCard = pickCard(rankedCards, rankedPlayableCards); - String pickedCardColor = pickedCard.getColor().get(0).toStringArray().get(0); - if (!pickedCard.isColorless() && !pickedCardColor.equals(this.playerColors.get(player).getColor1()) - && aiPlayables.contains(pickedCard)) { - this.playerColors.get(player).setColor2(pickedCardColor); + CardColor color = pickedCard.getCard().getColor(); + if (!color.isColorless() && aiPlayables.contains(pickedCard)) { + CardColor currentColor1 = CardColor.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()) { + if (!currentColor1.isWhite()) { + this.playerColors.get(player).setColor2(Constant.Color.WHITE); + } + } else if (color.hasBlue()) { + if (!currentColor1.isBlue()) { + this.playerColors.get(player).setColor2(Constant.Color.BLUE); + } + } else if (color.hasBlack()) { + if (!currentColor1.isBlack()) { + this.playerColors.get(player).setColor2(Constant.Color.BLACK); + } + } else if (color.hasRed()) { + if (!currentColor1.isRed()) { + this.playerColors.get(player).setColor2(Constant.Color.RED); + } + } else if (color.hasGreen()) { + if (!currentColor1.isGreen()) { + this.playerColors.get(player).setColor2(Constant.Color.GREEN); + } + } + } + this.playerColors.get(player).setMana2( + this.playerColors.get(player).colorToMana(this.playerColors.get(player).getColor2())); if (Constant.Runtime.DEV_MODE[0]) { System.out.println("Player[" + player + "] Color2: " + this.playerColors.get(player).getColor2()); } - - this.playerColors.get(player).setMana2( - this.playerColors.get(player).colorToMana(this.playerColors.get(player).getColor2())); } } else { // Has already picked both colors. - CardList colorList; - - colorList = aiPlayables.getOnly2Colors(this.playerColors.get(player).getColor1(), + CardColor colors = CardColor.fromNames(this.playerColors.get(player).getColor1(), this.playerColors.get(player).getColor2()); + Predicate hasColor = Predicate.or(new GenerateDeckUtil.ContainsAllColorsFrom(colors), + GenerateDeckUtil.COLORLESS_CARDS); + List colorList = hasColor.select(aiPlayables, CardPrinted.FN_GET_RULES); // Sort playable, on-color cards by rank - TreeMap rankedPlayableCards = new TreeMap(); - for (Card card : colorList) { - Integer rkg = draftRankings.getRanking(card.getName(), card.getCurSetCode()); + TreeMap rankedPlayableCards = new TreeMap(); + for (CardPrinted card : colorList) { + Integer rkg = draftRankings.getRanking(card.getName(), card.getEdition()); if (rkg != null) { rankedPlayableCards.put(rkg, card); } @@ -198,7 +250,8 @@ public class BoosterDraftAI { if (pickedCard != null) { chooseFrom.remove(pickedCard); - this.deck[player].add(pickedCard); + // TODO: Write deckbuilding code to work with CardPrinted. + this.deck[player].add(pickedCard.toForgeCard()); } return pickedCard; @@ -209,25 +262,26 @@ public class BoosterDraftAI { * * @param rankedCards * @param rankedPlayableCards - * @return Card + * @return CardPrinted */ - private Card pickCard(TreeMap rankedCards, TreeMap rankedPlayableCards) { - Card pickedCard = null; - Map.Entry best = rankedCards.firstEntry(); + 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("Chose Best: " + "[" + best.getKey() + "] " + pickedCard.getName() + " (" - + pickedCard.getManaCost() + ") " + pickedCard.getType().toString()); + + 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(); System.out.println("Nothing playable, chose Best: " + "[" + best.getKey() + "] " - + pickedCard.getName() + " (" + pickedCard.getManaCost() + ") " + + pickedCard.getName() + " (" + pickedCard.getCard().getManaCost() + ") " + pickedCard.getType().toString()); } else { // If the best card is far better than the best playable, @@ -235,21 +289,20 @@ public class BoosterDraftAI { 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.getManaCost() + ") " + + "] " + pickedCard.getName() + " (" + pickedCard.getCard().getManaCost() + ") " + pickedCard.getType().toString()); System.out.println("Playable was: " + "[" + bestPlayable.getKey() + "] " + bestPlayable.getValue().getName()); } else { pickedCard = bestPlayable.getValue(); System.out.println("Chose Playable: " + "[" + bestPlayable.getKey() + "] " - + pickedCard.getName() + " (" + pickedCard.getManaCost() + ") " + + pickedCard.getName() + " (" + pickedCard.getCard().getManaCost() + ") " + pickedCard.getType().toString()); System.out.println("Best was: " + "[" + best.getKey() + "] " + best.getValue().getName()); } } } } - System.out.println(""); return pickedCard; }