mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 12:48:00 +00:00
- work on limited deck using rankings
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -268,7 +268,9 @@ res/decks/Zack[!!-~]Shaffner's[!!-~]Creatureless[!!-~]Control.dck
|
|||||||
res/decks/Zemox's[!!-~]Mono-Green[!!-~]Infect.dck
|
res/decks/Zemox's[!!-~]Mono-Green[!!-~]Infect.dck
|
||||||
res/decks/Zvi[!!-~]Mowshowitz's[!!-~]Mono-Black[!!-~]Control.dck
|
res/decks/Zvi[!!-~]Mowshowitz's[!!-~]Mono-Black[!!-~]Control.dck
|
||||||
res/decks/constructed/*.dck
|
res/decks/constructed/*.dck
|
||||||
|
res/decks/draft/*
|
||||||
res/decks/o1.bdk
|
res/decks/o1.bdk
|
||||||
|
res/decks/sealed/*
|
||||||
res/images
|
res/images
|
||||||
res/layouts/*.xml
|
res/layouts/*.xml
|
||||||
res/oracleScript.log
|
res/oracleScript.log
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ public class BoosterDraftAI {
|
|||||||
|
|
||||||
pickedCard = pickCard(rankedCards, rankedPlayableCards);
|
pickedCard = pickCard(rankedCards, rankedPlayableCards);
|
||||||
|
|
||||||
if (!pickedCard.isColorless()) {
|
if (!pickedCard.isColorless() && aiPlayables.contains(pickedCard)) {
|
||||||
this.playerColors.get(player).setColor1(pickedCard.getColor().get(0).toStringArray().get(0));
|
this.playerColors.get(player).setColor1(pickedCard.getColor().get(0).toStringArray().get(0));
|
||||||
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());
|
||||||
@@ -162,7 +162,8 @@ public class BoosterDraftAI {
|
|||||||
pickedCard = pickCard(rankedCards, rankedPlayableCards);
|
pickedCard = pickCard(rankedCards, rankedPlayableCards);
|
||||||
|
|
||||||
String pickedCardColor = pickedCard.getColor().get(0).toStringArray().get(0);
|
String pickedCardColor = pickedCard.getColor().get(0).toStringArray().get(0);
|
||||||
if (!pickedCard.isColorless() && !pickedCardColor.equals(this.playerColors.get(player).getColor1())) {
|
if (!pickedCard.isColorless() && !pickedCardColor.equals(this.playerColors.get(player).getColor1())
|
||||||
|
&& aiPlayables.contains(pickedCard)) {
|
||||||
this.playerColors.get(player).setColor2(pickedCardColor);
|
this.playerColors.get(player).setColor2(pickedCardColor);
|
||||||
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());
|
||||||
@@ -353,7 +354,6 @@ public class BoosterDraftAI {
|
|||||||
|
|
||||||
// Initialize card rankings
|
// Initialize card rankings
|
||||||
this.draftRankings = new ReadDraftRankings();
|
this.draftRankings = new ReadDraftRankings();
|
||||||
|
|
||||||
} // BoosterDraftAI()
|
} // BoosterDraftAI()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -79,27 +79,29 @@ public class LimitedDeck extends Deck {
|
|||||||
System.out.println("Planeswalker: " + walkers.get(0).toString());
|
System.out.println("Planeswalker: " + walkers.get(0).toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0.5. Add combo cards (should this be done later? or perhaps within
|
|
||||||
// each method?)
|
|
||||||
addComboCards();
|
|
||||||
|
|
||||||
// 1. Add creatures, trying to follow mana curve
|
// 1. Add creatures, trying to follow mana curve
|
||||||
addManaCurveCreatures(15 - deckList.getType("Creature").size());
|
CardList creatures = getAiPlayables().getType("Creature").getOnly2Colors(getColors().getColor1(),
|
||||||
|
getColors().getColor2());
|
||||||
|
addManaCurveCreatures(rankCards(creatures), 15 - deckList.getType("Creature").size());
|
||||||
|
|
||||||
// 2.Try to fill up to 22 with on-color non-creature cards
|
// 2.Try to fill up to 22 with on-color non-creature cards
|
||||||
addNonCreatures(numSpellsNeeded - deckList.size());
|
CardList nonCreatures = getAiPlayables().getNotType("Creature").getNotType("Land")
|
||||||
|
.getOnly2Colors(getColors().getColor1(), getColors().getColor2());
|
||||||
|
addNonCreatures(rankCards(nonCreatures), numSpellsNeeded - deckList.size());
|
||||||
|
|
||||||
// 3.Try to fill up to 22 with on-color creatures cards (if more than 15
|
// 3.Try to fill up to 22 with on-color creatures cards (if more than 15
|
||||||
// are present)
|
// are present)
|
||||||
addBestCreatures(numSpellsNeeded - deckList.size());
|
creatures = getAiPlayables().getType("Creature").getOnly2Colors(getColors().getColor1(),
|
||||||
|
|
||||||
CardList nonLands = getAiPlayables().getNotType("Land").getOnly2Colors(getColors().getColor1(),
|
|
||||||
getColors().getColor2());
|
getColors().getColor2());
|
||||||
|
addCreatures(rankCards(creatures), numSpellsNeeded - deckList.size());
|
||||||
|
|
||||||
// 4. If there are still on-color cards and the average cmc is low add a
|
// 4. If there are still on-color cards and the average cmc is low add a
|
||||||
// 23rd card.
|
// 23rd card.
|
||||||
|
CardList nonLands = getAiPlayables().getNotType("Land").getOnly2Colors(getColors().getColor1(),
|
||||||
|
getColors().getColor2());
|
||||||
if (deckList.size() == numSpellsNeeded && CardListUtil.getAverageCMC(deckList) < 3 && !nonLands.isEmpty()) {
|
if (deckList.size() == numSpellsNeeded && CardListUtil.getAverageCMC(deckList) < 3 && !nonLands.isEmpty()) {
|
||||||
Card c = nonLands.get(0);
|
List<CardRankingBean> list = rankCards(nonLands);
|
||||||
|
Card c = list.get(0).getCard();
|
||||||
deckList.add(c);
|
deckList.add(c);
|
||||||
getAiPlayables().remove(0);
|
getAiPlayables().remove(0);
|
||||||
landsNeeded--;
|
landsNeeded--;
|
||||||
@@ -141,7 +143,8 @@ public class LimitedDeck extends Deck {
|
|||||||
// if no playable cards remain fill up with basic lands
|
// if no playable cards remain fill up with basic lands
|
||||||
for (int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
if (clrCnts[i].getCount() > 0) {
|
if (clrCnts[i].getCount() > 0) {
|
||||||
final CardPrinted cp = CardDb.instance().getCard(clrCnts[i].getColor(), IBoosterDraft.LAND_SET_CODE[0]);
|
final CardPrinted cp = CardDb.instance().getCard(clrCnts[i].getColor(),
|
||||||
|
IBoosterDraft.LAND_SET_CODE[0]);
|
||||||
deckList.add(cp.toForgeCard());
|
deckList.add(cp.toForgeCard());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -220,7 +223,8 @@ public class LimitedDeck extends Deck {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < nLand; j++) {
|
for (int j = 0; j < nLand; j++) {
|
||||||
final CardPrinted cp = CardDb.instance().getCard(clrCnts[i].getColor(), IBoosterDraft.LAND_SET_CODE[0]);
|
final CardPrinted cp = CardDb.instance().getCard(clrCnts[i].getColor(),
|
||||||
|
IBoosterDraft.LAND_SET_CODE[0]);
|
||||||
deckList.add(cp.toForgeCard());
|
deckList.add(cp.toForgeCard());
|
||||||
landsAdded++;
|
landsAdded++;
|
||||||
}
|
}
|
||||||
@@ -331,30 +335,22 @@ public class LimitedDeck extends Deck {
|
|||||||
/**
|
/**
|
||||||
* Add highest ranked non-creatures to the deck.
|
* Add highest ranked non-creatures to the deck.
|
||||||
*
|
*
|
||||||
* @param nCards
|
* @param nonCreatures
|
||||||
|
* cards to choose from
|
||||||
|
* @param num
|
||||||
*/
|
*/
|
||||||
private void addNonCreatures(int nCards) {
|
private void addNonCreatures(List<CardRankingBean> nonCreatures, int num) {
|
||||||
CardList others = getAiPlayables().getNotType("Creature").getNotType("Land")
|
for (CardRankingBean bean : nonCreatures) {
|
||||||
.getOnly2Colors(getColors().getColor1(), getColors().getColor2());
|
if (num > 0) {
|
||||||
List<CardRankingBean> rankedOthers = new ArrayList<CardRankingBean>();
|
|
||||||
for (Card card : others) {
|
|
||||||
Integer rkg = draftRankings.getRanking(card.getName(), card.getCurSetCode());
|
|
||||||
if (rkg != null) {
|
|
||||||
rankedOthers.add(new CardRankingBean(rkg, card));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Collections.sort(rankedOthers, new CardRankingComparator());
|
|
||||||
|
|
||||||
for (CardRankingBean bean : rankedOthers) {
|
|
||||||
if (nCards > 0) {
|
|
||||||
Card cardToAdd = bean.getCard();
|
Card cardToAdd = bean.getCard();
|
||||||
deckList.add(cardToAdd);
|
deckList.add(cardToAdd);
|
||||||
nCards--;
|
num--;
|
||||||
getAiPlayables().remove(cardToAdd);
|
getAiPlayables().remove(cardToAdd);
|
||||||
if (Constant.Runtime.DEV_MODE[0]) {
|
if (Constant.Runtime.DEV_MODE[0]) {
|
||||||
System.out.println("Others[" + nCards + "]:" + cardToAdd.getName() + " (" + cardToAdd.getManaCost()
|
System.out.println("Others[" + num + "]:" + cardToAdd.getName() + " (" + cardToAdd.getManaCost()
|
||||||
+ ")");
|
+ ")");
|
||||||
}
|
}
|
||||||
|
num = addComboCards(cardToAdd, num);
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -362,29 +358,61 @@ public class LimitedDeck extends Deck {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add the best creatures to the deck.
|
* Add cards that work well with the given card.
|
||||||
*
|
*
|
||||||
* @param nCreatures
|
* @param cardToAdd
|
||||||
|
* card being checked
|
||||||
|
* @param num
|
||||||
|
* number of cards
|
||||||
|
* @return number left after adding
|
||||||
*/
|
*/
|
||||||
private void addBestCreatures(int nCreatures) {
|
private int addComboCards(Card cardToAdd, int num) {
|
||||||
CardList creatures = getAiPlayables().getType("Creature").getOnly2Colors(getColors().getColor1(),
|
if (!cardToAdd.getSVar("DeckWants").equals("")) {
|
||||||
getColors().getColor2());
|
DeckWants wants = cardToAdd.getDeckWants();
|
||||||
creatures.sort(new CreatureComparator());
|
CardList comboCards = wants.filter(getAiPlayables());
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
while (nCreatures > 0 && creatures.size() > 0) {
|
|
||||||
final Card c = creatures.get(0);
|
|
||||||
|
|
||||||
deckList.add(c);
|
|
||||||
nCreatures--;
|
|
||||||
getAiPlayables().remove(c);
|
|
||||||
creatures.remove(c);
|
|
||||||
|
|
||||||
if (Constant.Runtime.DEV_MODE[0]) {
|
if (Constant.Runtime.DEV_MODE[0]) {
|
||||||
System.out.println("Creature[" + i + "]:" + c.getName() + " (" + c.getManaCost() + ")");
|
System.out.println("Found " + comboCards.size() + " cards for " + cardToAdd.getName());
|
||||||
|
}
|
||||||
|
List<CardRankingBean> rankedComboCards = rankCards(comboCards);
|
||||||
|
for (CardRankingBean comboBean : rankedComboCards) {
|
||||||
|
if (num > 0) {
|
||||||
|
// TODO: This is not exactly right, because the
|
||||||
|
// rankedComboCards could include creatures and
|
||||||
|
// non-creatures. This code could add too many of one or the
|
||||||
|
// other.
|
||||||
|
Card combo = comboBean.getCard();
|
||||||
|
deckList.add(combo);
|
||||||
|
num--;
|
||||||
|
getAiPlayables().remove(combo);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
i++;
|
/**
|
||||||
|
* Add creatures to the deck.
|
||||||
|
*
|
||||||
|
* @param creatures
|
||||||
|
* cards to choose from
|
||||||
|
* @param num
|
||||||
|
*/
|
||||||
|
private void addCreatures(List<CardRankingBean> creatures, int num) {
|
||||||
|
for (CardRankingBean bean : creatures) {
|
||||||
|
if (num > 0) {
|
||||||
|
Card c = bean.getCard();
|
||||||
|
deckList.add(c);
|
||||||
|
num--;
|
||||||
|
getAiPlayables().remove(c);
|
||||||
|
if (Constant.Runtime.DEV_MODE[0]) {
|
||||||
|
System.out.println("Creature[" + num + "]:" + c.getName() + " (" + c.getManaCost() + ")");
|
||||||
|
}
|
||||||
|
num = addComboCards(c, num);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -393,13 +421,11 @@ public class LimitedDeck extends Deck {
|
|||||||
* have generous limits at each cost, but perhaps still too strict. But
|
* have generous limits at each cost, but perhaps still too strict. But
|
||||||
* we're trying to prevent the AI from adding everything at a single cost.
|
* we're trying to prevent the AI from adding everything at a single cost.
|
||||||
*
|
*
|
||||||
* @param nCreatures
|
* @param creatures
|
||||||
|
* cards to choose from
|
||||||
|
* @param num
|
||||||
*/
|
*/
|
||||||
private void addManaCurveCreatures(int nCreatures) {
|
private void addManaCurveCreatures(List<CardRankingBean> creatures, int num) {
|
||||||
CardList creatures = getAiPlayables().getType("Creature").getOnly2Colors(getColors().getColor1(),
|
|
||||||
getColors().getColor2());
|
|
||||||
creatures.sort(new CreatureComparator());
|
|
||||||
|
|
||||||
Map<Integer, Integer> creatureCosts = new HashMap<Integer, Integer>();
|
Map<Integer, Integer> creatureCosts = new HashMap<Integer, Integer>();
|
||||||
for (int i = 1; i < 7; i++) {
|
for (int i = 1; i < 7; i++) {
|
||||||
creatureCosts.put(i, 0);
|
creatureCosts.put(i, 0);
|
||||||
@@ -414,8 +440,9 @@ public class LimitedDeck extends Deck {
|
|||||||
}
|
}
|
||||||
creatureCosts.put(cmc, creatureCosts.get(cmc) + 1);
|
creatureCosts.put(cmc, creatureCosts.get(cmc) + 1);
|
||||||
}
|
}
|
||||||
int i = 0;
|
|
||||||
for (Card c : creatures) {
|
for (CardRankingBean bean : creatures) {
|
||||||
|
Card c = bean.getCard();
|
||||||
int cmc = c.getCMC();
|
int cmc = c.getCMC();
|
||||||
if (cmc < 1) {
|
if (cmc < 1) {
|
||||||
cmc = 1;
|
cmc = 1;
|
||||||
@@ -440,21 +467,20 @@ public class LimitedDeck extends Deck {
|
|||||||
|
|
||||||
if (willAddCreature) {
|
if (willAddCreature) {
|
||||||
deckList.add(c);
|
deckList.add(c);
|
||||||
nCreatures--;
|
num--;
|
||||||
getAiPlayables().remove(c);
|
getAiPlayables().remove(c);
|
||||||
creatureCosts.put(cmc, creatureCosts.get(cmc) + 1);
|
creatureCosts.put(cmc, creatureCosts.get(cmc) + 1);
|
||||||
|
|
||||||
if (Constant.Runtime.DEV_MODE[0]) {
|
if (Constant.Runtime.DEV_MODE[0]) {
|
||||||
System.out.println("Creature[" + i + "]:" + c.getName() + " (" + c.getManaCost() + ")");
|
System.out.println("Creature[" + num + "]:" + c.getName() + " (" + c.getManaCost() + ")");
|
||||||
}
|
}
|
||||||
i++;
|
num = addComboCards(c, num);
|
||||||
} else {
|
} else {
|
||||||
if (Constant.Runtime.DEV_MODE[0]) {
|
if (Constant.Runtime.DEV_MODE[0]) {
|
||||||
System.out.println(c.getName() + " not added because CMC " + c.getCMC() + " has " + currentAtCmc
|
System.out.println(c.getName() + " not added because CMC " + c.getCMC() + " has " + currentAtCmc
|
||||||
+ " already.");
|
+ " already.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (nCreatures <= 0) {
|
if (num <= 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -462,39 +488,21 @@ public class LimitedDeck extends Deck {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add cards that need other cards to be in the deck.
|
* Rank cards.
|
||||||
|
*
|
||||||
|
* @param cards
|
||||||
|
* @return List of beans with card rankings
|
||||||
*/
|
*/
|
||||||
private void addComboCards() {
|
private List<CardRankingBean> rankCards(CardList cards) {
|
||||||
CardList onColorPlayables = getAiPlayables().getOnly2Colors(getColors().getColor1(), getColors().getColor2());
|
List<CardRankingBean> ranked = new ArrayList<CardRankingBean>();
|
||||||
for (Card c : onColorPlayables) {
|
for (Card card : cards) {
|
||||||
if (!c.getSVar("DeckWants").equals("")) {
|
Integer rkg = draftRankings.getRanking(card.getName(), card.getCurSetCode());
|
||||||
DeckWants wants = c.getDeckWants();
|
if (rkg != null) {
|
||||||
CardList cards = wants.filter(onColorPlayables);
|
ranked.add(new CardRankingBean(rkg, card));
|
||||||
if (cards.size() >= wants.getMinCardsNeeded()) {
|
|
||||||
if (Constant.Runtime.DEV_MODE[0]) {
|
|
||||||
System.out.println("Adding " + c.getName() + " with up to " + cards.size()
|
|
||||||
+ " combo cards (e.g., " + cards.get(0).getName() + ").");
|
|
||||||
}
|
|
||||||
deckList.add(c);
|
|
||||||
getAiPlayables().remove(c);
|
|
||||||
if (cards.size() <= 4) {
|
|
||||||
deckList.addAll(cards);
|
|
||||||
getAiPlayables().removeAll(cards);
|
|
||||||
} else {
|
|
||||||
cards.shuffle();
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
Card theCard = cards.get(i);
|
|
||||||
deckList.add(theCard);
|
|
||||||
getAiPlayables().remove(theCard);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Could not find combo cards, so don't put this card in the
|
|
||||||
// deck.
|
|
||||||
getAiPlayables().remove(c);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Collections.sort(ranked, new CardRankingComparator());
|
||||||
|
return ranked;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user