- Refactoring BoosterDraft to use CardPrinted

This commit is contained in:
mcrawford620
2012-08-01 00:23:50 +00:00
parent 57fa3acef2
commit 52e375fe1d
2 changed files with 120 additions and 76 deletions

View File

@@ -275,18 +275,9 @@ public final class BoosterDraft implements IBoosterDraft {
for (final CardPrinted cr : booster) { for (final CardPrinted cr : booster) {
forAi.add(cr.toForgeCard()); 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 aiPick = this.draftAI.choose(booster, iPlayer++);
final CardPrinted cp = booster.get(pick); booster.remove(aiPick);
if (cp.getName().equalsIgnoreCase(pickedName)) {
booster.remove(pick);
break;
}
}
} }
} // computerChoose() } // computerChoose()

View File

@@ -18,19 +18,22 @@
package forge.game.limited; package forge.game.limited;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.Set; import java.util.Set;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.TreeSet; import java.util.TreeSet;
import forge.Card;
import forge.CardList; import forge.CardList;
import forge.CardListFilter;
import forge.CardUtil;
import forge.Constant; import forge.Constant;
import forge.card.CardColor;
import forge.card.CardRules;
import forge.deck.Deck; import forge.deck.Deck;
import forge.deck.generate.GenerateDeckUtil;
import forge.item.CardPrinted;
import forge.util.MyRandom; import forge.util.MyRandom;
import forge.util.closures.Predicate;
/** /**
* <p> * <p>
@@ -68,38 +71,28 @@ public class BoosterDraftAI {
* </p> * </p>
* *
* @param chooseFrom * @param chooseFrom
* a {@link forge.CardList} object. * List of CardPrinted
* @param player * @param player
* a int. * a int.
* @return a {@link forge.CardList} object. * @return a {@link forge.CardList} object.
*/ */
public Card choose(final CardList chooseFrom, final int player) { public CardPrinted choose(final List<CardPrinted> 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
if (Constant.Runtime.DEV_MODE[0]) { if (Constant.Runtime.DEV_MODE[0]) {
System.out.println("Player[" + player + "] pack: " + chooseFrom.toString()); 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() { List<CardPrinted> aiPlayables = CardRules.Predicates.IS_KEPT_IN_AI_DECKS.select(chooseFrom,
@Override CardPrinted.FN_GET_RULES);
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;
}
});
// Sort cards by rank. // Sort cards by rank.
// Note that if pack has cards from different editions, they could have // Note that if pack has cards from different editions, they could have
// the same Integer rank. // the same Integer rank.
// In that (hopefully rare) case, only one will end up in the Map. // In that (hopefully rare) case, only one will end up in the Map.
TreeMap<Integer, Card> rankedCards = new TreeMap<Integer, Card>(); TreeMap<Integer, CardPrinted> rankedCards = new TreeMap<Integer, CardPrinted>();
for (Card card : chooseFrom) { for (CardPrinted card : chooseFrom) {
Integer rkg = draftRankings.getRanking(card.getName(), card.getCurSetCode()); Integer rkg = draftRankings.getRanking(card.getName(), card.getEdition());
if (rkg != null) { if (rkg != null) {
rankedCards.put(rkg, card); rankedCards.put(rkg, card);
} else { } else {
@@ -112,9 +105,9 @@ public class BoosterDraftAI {
// Generally the first pick of the draft, no colors selected yet. // Generally the first pick of the draft, no colors selected yet.
// Sort playable cards by rank // Sort playable cards by rank
TreeMap<Integer, Card> rankedPlayableCards = new TreeMap<Integer, Card>(); TreeMap<Integer, CardPrinted> rankedPlayableCards = new TreeMap<Integer, CardPrinted>();
for (Card card : aiPlayables) { for (CardPrinted card : aiPlayables) {
Integer rkg = draftRankings.getRanking(card.getName(), card.getCurSetCode()); Integer rkg = draftRankings.getRanking(card.getName(), card.getEdition());
if (rkg != null) { if (rkg != null) {
rankedPlayableCards.put(rkg, card); rankedPlayableCards.put(rkg, card);
} }
@@ -122,23 +115,54 @@ public class BoosterDraftAI {
pickedCard = pickCard(rankedCards, rankedPlayableCards); pickedCard = pickCard(rankedCards, rankedPlayableCards);
if (!pickedCard.isColorless() && aiPlayables.contains(pickedCard)) { if (!pickedCard.getCard().getColor().isColorless() && aiPlayables.contains(pickedCard)) {
this.playerColors.get(player).setColor1(pickedCard.getColor().get(0).toStringArray().get(0)); 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]) { if (Constant.Runtime.DEV_MODE[0]) {
System.out.println("Player[" + player + "] Color1: " + this.playerColors.get(player).getColor1()); System.out.println("Player[" + player + "] Color1: " + this.playerColors.get(player).getColor1());
} if (!this.playerColors.get(player).getColor2().equals("none")) {
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]) {
System.out.println("Player[" + player + "] Color2: " System.out.println("Player[" + player + "] Color2: "
+ this.playerColors.get(player).getColor2()); + 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).setMana2(
this.playerColors.get(player).colorToMana(this.playerColors.get(player).getColor2())); 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. // Has already picked one color, but not the second.
// Sort playable, on-color, or mono-colored, or colorless cards // Sort playable, on-color, or mono-colored, or colorless cards
TreeMap<Integer, Card> rankedPlayableCards = new TreeMap<Integer, Card>(); TreeMap<Integer, CardPrinted> rankedPlayableCards = new TreeMap<Integer, CardPrinted>();
for (Card card : aiPlayables) { for (CardPrinted card : aiPlayables) {
if (card.isColorless() || CardUtil.isColor(card, this.playerColors.get(player).getColor1()) CardColor currentColor1 = CardColor.fromNames(this.playerColors.get(player).getColor1());
|| CardUtil.getColors(card).size() == 1) { CardColor color = card.getCard().getColor();
Integer rkg = draftRankings.getRanking(card.getName(), card.getCurSetCode()); if (color.isColorless() || color.sharesColorWith(currentColor1) || color.isMonoColor()) {
Integer rkg = draftRankings.getRanking(card.getName(), card.getEdition());
if (rkg != null) { if (rkg != null) {
rankedPlayableCards.put(rkg, card); rankedPlayableCards.put(rkg, card);
} }
@@ -161,28 +186,55 @@ public class BoosterDraftAI {
pickedCard = pickCard(rankedCards, rankedPlayableCards); pickedCard = pickCard(rankedCards, rankedPlayableCards);
String pickedCardColor = pickedCard.getColor().get(0).toStringArray().get(0); CardColor color = pickedCard.getCard().getColor();
if (!pickedCard.isColorless() && !pickedCardColor.equals(this.playerColors.get(player).getColor1()) if (!color.isColorless() && aiPlayables.contains(pickedCard)) {
&& aiPlayables.contains(pickedCard)) { CardColor currentColor1 = CardColor.fromNames(this.playerColors.get(player).getColor1());
this.playerColors.get(player).setColor2(pickedCardColor); 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]) { if (Constant.Runtime.DEV_MODE[0]) {
System.out.println("Player[" + player + "] Color2: " + this.playerColors.get(player).getColor2()); 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 { } else {
// Has already picked both colors. // Has already picked both colors.
CardList colorList; CardColor colors = CardColor.fromNames(this.playerColors.get(player).getColor1(),
colorList = aiPlayables.getOnly2Colors(this.playerColors.get(player).getColor1(),
this.playerColors.get(player).getColor2()); this.playerColors.get(player).getColor2());
Predicate<CardRules> hasColor = Predicate.or(new GenerateDeckUtil.ContainsAllColorsFrom(colors),
GenerateDeckUtil.COLORLESS_CARDS);
List<CardPrinted> colorList = hasColor.select(aiPlayables, CardPrinted.FN_GET_RULES);
// Sort playable, on-color cards by rank // Sort playable, on-color cards by rank
TreeMap<Integer, Card> rankedPlayableCards = new TreeMap<Integer, Card>(); TreeMap<Integer, CardPrinted> rankedPlayableCards = new TreeMap<Integer, CardPrinted>();
for (Card card : colorList) { for (CardPrinted card : colorList) {
Integer rkg = draftRankings.getRanking(card.getName(), card.getCurSetCode()); Integer rkg = draftRankings.getRanking(card.getName(), card.getEdition());
if (rkg != null) { if (rkg != null) {
rankedPlayableCards.put(rkg, card); rankedPlayableCards.put(rkg, card);
} }
@@ -198,7 +250,8 @@ public class BoosterDraftAI {
if (pickedCard != null) { if (pickedCard != null) {
chooseFrom.remove(pickedCard); chooseFrom.remove(pickedCard);
this.deck[player].add(pickedCard); // TODO: Write deckbuilding code to work with CardPrinted.
this.deck[player].add(pickedCard.toForgeCard());
} }
return pickedCard; return pickedCard;
@@ -209,25 +262,26 @@ public class BoosterDraftAI {
* *
* @param rankedCards * @param rankedCards
* @param rankedPlayableCards * @param rankedPlayableCards
* @return Card * @return CardPrinted
*/ */
private Card pickCard(TreeMap<Integer, Card> rankedCards, TreeMap<Integer, Card> rankedPlayableCards) { private CardPrinted pickCard(TreeMap<Integer, CardPrinted> rankedCards,
Card pickedCard = null; TreeMap<Integer, CardPrinted> rankedPlayableCards) {
Map.Entry<Integer, Card> best = rankedCards.firstEntry(); CardPrinted pickedCard = null;
Map.Entry<Integer, CardPrinted> best = rankedCards.firstEntry();
if (best != null) { if (best != null) {
if (rankedPlayableCards.containsValue(best.getValue())) { if (rankedPlayableCards.containsValue(best.getValue())) {
// If best card is playable, pick it. // If best card is playable, pick it.
pickedCard = best.getValue(); pickedCard = best.getValue();
System.out.println("Chose Best: " + "[" + best.getKey() + "] " + pickedCard.getName() + " (" System.out.println("Chose Best: " + "[" + best.getKey() + "] " + pickedCard.getName() + " ("
+ pickedCard.getManaCost() + ") " + pickedCard.getType().toString()); + pickedCard.getCard().getManaCost() + ") " + pickedCard.getType().toString());
} else { } else {
// If not, find the best card that is playable. // If not, find the best card that is playable.
Map.Entry<Integer, Card> bestPlayable = rankedPlayableCards.firstEntry(); Map.Entry<Integer, CardPrinted> bestPlayable = rankedPlayableCards.firstEntry();
if (bestPlayable == null) { if (bestPlayable == null) {
// Nothing is playable, so just take the best card. // Nothing is playable, so just take the best card.
pickedCard = best.getValue(); pickedCard = best.getValue();
System.out.println("Nothing playable, chose Best: " + "[" + best.getKey() + "] " System.out.println("Nothing playable, chose Best: " + "[" + best.getKey() + "] "
+ pickedCard.getName() + " (" + pickedCard.getManaCost() + ") " + pickedCard.getName() + " (" + pickedCard.getCard().getManaCost() + ") "
+ pickedCard.getType().toString()); + pickedCard.getType().toString());
} else { } else {
// If the best card is far better than the best playable, // 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()) { if (best.getKey() + TAKE_BEST_THRESHOLD < bestPlayable.getKey()) {
pickedCard = best.getValue(); pickedCard = best.getValue();
System.out.println("Best is much better than playable; chose Best: " + "[" + best.getKey() 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()); + pickedCard.getType().toString());
System.out.println("Playable was: " + "[" + bestPlayable.getKey() + "] " System.out.println("Playable was: " + "[" + bestPlayable.getKey() + "] "
+ bestPlayable.getValue().getName()); + bestPlayable.getValue().getName());
} else { } else {
pickedCard = bestPlayable.getValue(); pickedCard = bestPlayable.getValue();
System.out.println("Chose Playable: " + "[" + bestPlayable.getKey() + "] " System.out.println("Chose Playable: " + "[" + bestPlayable.getKey() + "] "
+ pickedCard.getName() + " (" + pickedCard.getManaCost() + ") " + pickedCard.getName() + " (" + pickedCard.getCard().getManaCost() + ") "
+ pickedCard.getType().toString()); + pickedCard.getType().toString());
System.out.println("Best was: " + "[" + best.getKey() + "] " + best.getValue().getName()); System.out.println("Best was: " + "[" + best.getKey() + "] " + best.getValue().getName());
} }
} }
} }
} }
System.out.println("");
return pickedCard; return pickedCard;
} }