- Refactor Booster Deck building to separate class.

- SVar for creatures that are sacrificed at end of combat.
This commit is contained in:
mcrawford620
2012-07-08 05:21:45 +00:00
parent ef0e6514ad
commit 98fa689c66
10 changed files with 405 additions and 369 deletions

2
.gitattributes vendored
View File

@@ -12037,11 +12037,13 @@ src/main/java/forge/game/GamePlayerRating.java -text
src/main/java/forge/game/GameState.java -text
src/main/java/forge/game/GameSummary.java svneol=native#text/plain
src/main/java/forge/game/GameType.java -text
src/main/java/forge/game/limited/BoosterDeck.java -text
src/main/java/forge/game/limited/BoosterDraft.java svneol=native#text/plain
src/main/java/forge/game/limited/BoosterDraftAI.java svneol=native#text/plain
src/main/java/forge/game/limited/CCnt.java svneol=native#text/plain
src/main/java/forge/game/limited/CardPoolLimitation.java -text
src/main/java/forge/game/limited/CardRatings.java -text
src/main/java/forge/game/limited/CreatureComparator.java -text
src/main/java/forge/game/limited/CustomLimited.java svneol=native#text/plain
src/main/java/forge/game/limited/DeckColors.java svneol=native#text/plain
src/main/java/forge/game/limited/IBoosterDraft.java svneol=native#text/plain

View File

@@ -20,10 +20,21 @@
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>net.sf.eclipsecs.core.CheckstyleNature</nature>
<nature>org.eclipse.pde.PluginNature</nature>
</natures>
</projectDescription>

View File

@@ -7,6 +7,7 @@ K:Trample
T:Mode$ Attacks | ValidCard$ Card.Self | DelayedTrigger$ DelTrig | TriggerDescription$ When CARDNAME attacks, sacrifice it at end of combat.
SVar:DelTrig:Mode$ Phase | Phase$ EndCombat | ValidPlayer$ Player | Execute$ TrigSacrifice | TriggerDescription$ Sacrifice CARDNAME at end of combat.
SVar:TrigSacrifice:AB$ Sacrifice | Cost$ 0 | Defined$ Self
SVar:SacrificeEndCombat:True
SVar:Rarity:Uncommon
SVar:Picture:http://www.wizards.com/global/images/magic/general/crumbling_colossus.jpg
SetInfo:M12|Uncommon|http://magiccards.info/scans/en/m12/204.jpg

View File

@@ -8,6 +8,7 @@ T:Mode$ Attacks | ValidCard$ Card.Self | DelayedTrigger$ DelTrig | TriggerDescri
T:Mode$ Blocks | ValidCard$ Card.Self | DelayedTrigger$ DelTrig | Secondary$ True | TriggerDescription$ Whenever CARDNAME attacks or blocks, sacrifice it at end of combat.
SVar:DelTrig:Mode$ Phase | Phase$ EndCombat | ValidPlayer$ Player | Execute$ TrigSacrifice | TriggerDescription$ Sacrifice CARDNAME at end of combat.
SVar:TrigSacrifice:AB$Sacrifice | Cost$ 0 | Defined$ Self
SVar:SacrificeEndCombat:True
SVar:Rarity:Uncommon
SVar:Picture:http://www.wizards.com/global/images/magic/general/fog_elemental.jpg
SetInfo:WTH|Common|http://magiccards.info/scans/en/wl/40.jpg

View File

@@ -8,6 +8,7 @@ K:CARDNAME can't block.
T:Mode$ Attacks | ValidCard$ Card.Self | DelayedTrigger$ DelTrig | TriggerDescription$ When CARDNAME attacks, sacrifice it at end of combat.
SVar:DelTrig:Mode$ Phase | Phase$ EndCombat | ValidPlayer$ Player | Execute$ TrigSacrifice | TriggerDescription$ Sacrifice CARDNAME at end of combat.
SVar:TrigSacrifice:AB$Sacrifice | Cost$ 0 | Defined$ Self
SVar:SacrificeEndCombat:True
A:AB$ Pump | Cost$ tapXType<1/Creature> | NumAtt$ +X | References$ X | SpellDescription$ CARDNAME gets +X/+0 until end of turn, where X is the power of the creature tapped this way.
SVar:X:Tapped$CardPower
SVar:RemAIDeck:True

View File

@@ -8,6 +8,7 @@ K:Flying
T:Mode$ Blocks | ValidCard$ Card.Self | DelayedTrigger$ DelTrig | TriggerDescription$ When CARDNAME blocks, sacrifice it at end of combat.
SVar:DelTrig:Mode$ Phase | Phase$ EndCombat | ValidPlayer$ Opponent | Execute$ TrigSacrifice | TriggerDescription$ Sacrifice CARDNAME at end of combat.
SVar:TrigSacrifice:AB$Sacrifice | Cost$ 0 | Defined$ Self
SVar:SacrificeEndCombat:True
SVar:Rarity:Uncommon
SVar:Picture:http://www.wizards.com/global/images/magic/general/stoic_ephemera.jpg
SetInfo:DIS|Uncommon|http://magiccards.info/scans/en/di/19.jpg

View File

@@ -595,6 +595,10 @@ public class CardFactoryUtil {
if (c.getSVar("Targeting").equals("Dies")) {
value -= 25;
}
if (c.getSVar("SacrificeEndCombat").equals("True")) {
value -= 40;
}
for (final SpellAbility sa : c.getSpellAbilities()) {
if (sa.isAbility()) {

View File

@@ -0,0 +1,327 @@
package forge.game.limited;
import forge.AllZone;
import forge.Card;
import forge.CardList;
import forge.CardListFilter;
import forge.CardListUtil;
import forge.Constant;
import forge.card.CardColor;
import forge.card.CardManaCost;
import forge.card.mana.ManaCostShard;
import forge.deck.Deck;
import forge.util.MyRandom;
/**
* Deck built from a Booster Draft.
*
*/
public class BoosterDeck extends Deck {
private static final long serialVersionUID = -7818685851099321964L;
private int cardsNeeded = 22;
private int landsNeeded = 18;
private DeckColors colors;
private CardList draftedList;
private CardList aiPlayables;
private CardList deckList = new CardList();
public BoosterDeck(CardList dList, DeckColors pClrs) {
super("");
this.draftedList = dList;
this.colors = pClrs;
buildDeck();
}
/**
* <p>
* buildDeck.
* </p>
*
* @param draftedList
* a {@link forge.CardList} object.
* @param colors
* a {@link forge.game.limited.DeckColors} object.
* @return a {@link forge.deck.Deck} object.
*/
private void buildDeck() {
aiPlayables = draftedList.filter(new CardListFilter() {
@Override
public boolean addCard(final Card c) {
return !(c.getSVar("RemAIDeck").equals("True") || c.getSVar("RemRandomDeck").equals("True"));
}
});
for (int i = 0; i < aiPlayables.size(); i++) {
draftedList.remove(aiPlayables.get(i));
}
// 1. Add best 15 on-color creatures
addBestCreatures(15);
// 2.Try to fill up to 22 with on-color non-creature cards
addNonCreatures(cardsNeeded - deckList.size());
// 3.Try to fill up to 22 with on-color creatures cards (if more than 15
// are present)
addBestCreatures(cardsNeeded - deckList.size());
CardList nonLands = aiPlayables.getNotType("Land").getOnly2Colors(colors.getColor1(), colors.getColor2());
// 4. If there are still on-color cards and the average cmc is low add a
// 23rd card.
if (cardsNeeded == 0 && CardListUtil.getAverageCMC(deckList) < 3 && !nonLands.isEmpty()) {
Card c = nonLands.get(0);
deckList.add(c);
aiPlayables.remove(0);
landsNeeded--;
}
// 5. If there are still less than 22 non-land cards add off-color
// cards.
addRandomCards(cardsNeeded - deckList.size());
// 6. If it's not a mono color deck, add non-basic lands that were drafted.
addNonBasicLands();
final CCnt[] clrCnts = calculateLandNeeds();
if (landsNeeded > 0) {
addLands(clrCnts);
}
while (deckList.size() > 40) {
final Card c = deckList.get(MyRandom.getRandom().nextInt(deckList.size() - 1));
deckList.remove(c);
aiPlayables.add(c);
}
while (deckList.size() < 40) {
if (aiPlayables.size() > 1) {
final Card c = aiPlayables.get(MyRandom.getRandom().nextInt(aiPlayables.size() - 1));
deckList.add(c);
aiPlayables.remove(c);
} else if (aiPlayables.size() == 1) {
final Card c = aiPlayables.get(0);
deckList.add(c);
aiPlayables.remove(c);
} else {
// if no playable cards remain fill up with basic lands
for (int i = 0; i < 5; i++) {
if (clrCnts[i].getCount() > 0) {
final Card c = AllZone.getCardFactory().getCard(clrCnts[i].getColor(),
AllZone.getComputerPlayer());
c.setCurSetCode(IBoosterDraft.LAND_SET_CODE[0]);
deckList.add(c);
break;
}
}
}
}
if (deckList.size() == 40) {
this.getMain().add(deckList);
this.getSideboard().add(aiPlayables);
this.getSideboard().add(draftedList);
} else {
throw new RuntimeException("BoosterDraftAI : buildDeck() error, decksize not 40");
}
}
/**
* Add lands to fulfill the given color counts.
* @param clrCnts
*/
private void addLands(final CCnt[] clrCnts) {
// total of all ClrCnts
int totalColor = 0;
for (int i = 0; i < 5; i++) {
totalColor += clrCnts[i].getCount();
// tmpDeck += ClrCnts[i].Color + ":" + ClrCnts[i].Count + "\n";
}
// tmpDeck += "totalColor:" + totalColor + "\n";
for (int i = 0; i < 5; i++) {
if (clrCnts[i].getCount() > 0) { // calculate number of lands
// for
// each color
final float p = (float) clrCnts[i].getCount() / (float) totalColor;
final int nLand = (int) (landsNeeded * p) + 1;
// tmpDeck += "nLand-" + ClrCnts[i].Color + ":" + nLand +
// "\n";
if (Constant.Runtime.DEV_MODE[0]) {
System.out.println("Basics[" + clrCnts[i].getColor() + "]:" + nLand);
}
// just to prevent a null exception by the deck size fixing
// code
// CardCounts.put(ClrCnts[i].Color, nLand);
for (int j = 0; j <= nLand; j++) {
final Card c = AllZone.getCardFactory().getCard(clrCnts[i].getColor(),
AllZone.getComputerPlayer());
c.setCurSetCode(IBoosterDraft.LAND_SET_CODE[0]);
deckList.add(c);
landsNeeded--;
}
}
}
int n = 0;
while (landsNeeded > 0) {
if (clrCnts[n].getCount() > 0) {
final Card c = AllZone.getCardFactory().getCard(clrCnts[n].getColor(), AllZone.getComputerPlayer());
c.setCurSetCode(IBoosterDraft.LAND_SET_CODE[0]);
deckList.add(c);
landsNeeded--;
if (Constant.Runtime.DEV_MODE[0]) {
System.out.println("AddBasics: " + c.getName());
}
}
if (++n > 4) {
n = 0;
}
}
}
/**
* attempt to optimize basic land counts according to color representation
* @return CCnt
*/
private CCnt[] calculateLandNeeds() {
final CCnt[] clrCnts = { new CCnt("Plains", 0), new CCnt("Island", 0), new CCnt("Swamp", 0),
new CCnt("Mountain", 0), new CCnt("Forest", 0) };
// count each card color using mana costs
// TODO: count hybrid mana differently?
for (int i = 0; i < deckList.size(); i++) {
final CardManaCost mc = deckList.get(i).getManaCost();
// count each mana symbol in the mana cost
for (ManaCostShard shard : mc.getShards()) {
byte mask = shard.getColorMask();
if ((mask & CardColor.WHITE) > 0) {
clrCnts[0].setCount(clrCnts[0].getCount() + 1);
}
if ((mask & CardColor.BLUE) > 0) {
clrCnts[1].setCount(clrCnts[1].getCount() + 1);
}
if ((mask & CardColor.BLACK) > 0) {
clrCnts[2].setCount(clrCnts[2].getCount() + 1);
}
if ((mask & CardColor.RED) > 0) {
clrCnts[3].setCount(clrCnts[3].getCount() + 1);
}
if ((mask & CardColor.GREEN) > 0) {
clrCnts[4].setCount(clrCnts[4].getCount() + 1);
}
}
}
return clrCnts;
}
/**
* Add non-basic lands to the deck.
*/
private void addNonBasicLands() {
CardList lands = aiPlayables.getType("Land");
while (!colors.getColor1().equals(colors.getColor2()) && landsNeeded > 0 && lands.size() > 0) {
final Card c = lands.get(0);
deckList.add(c);
landsNeeded--;
aiPlayables.remove(c);
lands = aiPlayables.getType("Land");
if (Constant.Runtime.DEV_MODE[0]) {
System.out.println("Land:" + c.getName());
}
}
}
/**
* Add random cards to the deck.
* @param nCards
*/
private void addRandomCards(int nCards) {
CardList z = aiPlayables.getNotType("Land");
int ii = 0;
while ((nCards > 0) && (z.size() > 1)) {
final Card c = z.get(MyRandom.getRandom().nextInt(z.size() - 1));
deckList.add(c);
cardsNeeded--;
nCards--;
aiPlayables.remove(c);
z.remove(c);
if (Constant.Runtime.DEV_MODE[0]) {
System.out.println("NonLands[" + ii++ + "]:" + c.getName() + "(" + c.getManaCost() + ")");
}
}
}
/**
* Add non creatures to the deck.
* @param nCards
*/
private void addNonCreatures(int nCards) {
CardList others = aiPlayables.getNotType("Creature").getNotType("Land")
.getOnly2Colors(colors.getColor1(), colors.getColor2());
int ii = 0;
while (nCards > 0 && others.size() > 0) {
int index = 0;
if (others.size() > 1) {
index = MyRandom.getRandom().nextInt(others.size() - 1);
}
final Card c = others.get(index);
deckList.add(c);
cardsNeeded--;
nCards--;
aiPlayables.remove(c);
others.remove(c);
if (Constant.Runtime.DEV_MODE[0]) {
System.out.println("Others[" + ii++ + "]:" + c.getName() + " (" + c.getManaCost() + ")");
}
}
}
/**
* Add the best creatures to the deck.
*
* @param nCreatures
*/
private void addBestCreatures(int nCreatures) {
CardList creatures = aiPlayables.getType("Creature").getOnly2Colors(colors.getColor1(), colors.getColor2());
creatures.sort(new CreatureComparator());
int i = 0;
while (nCreatures > 0 && creatures.size() > 0) {
final Card c = creatures.get(0);
deckList.add(c);
cardsNeeded--;
nCreatures--;
aiPlayables.remove(c);
creatures.remove(c);
if (Constant.Runtime.DEV_MODE[0]) {
System.out.println("Creature[" + i + "]:" + c.getName() + " (" + c.getManaCost() + ")");
}
i++;
}
}
}

View File

@@ -18,23 +18,18 @@
package forge.game.limited;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import forge.AllZone;
import forge.Card;
import forge.CardList;
import forge.CardListFilter;
import forge.CardListUtil;
import forge.Constant;
import forge.card.CardColor;
import forge.card.CardManaCost;
import forge.card.cardfactory.CardFactoryUtil;
import forge.card.mana.ManaCostShard;
import forge.card.spellability.AbilityMana;
import forge.deck.Deck;
import forge.util.MyRandom;
@@ -116,7 +111,7 @@ public class BoosterDraftAI {
if (!hasPicked) {
final CardList creatures = aiPlayables.getType("Creature");
creatures.sort(this.bestCreature);
creatures.sort(new CreatureComparator());
debugCreatures(creatures);
if (creatures.size() > 0) {
@@ -156,7 +151,7 @@ public class BoosterDraftAI {
if (!hasPicked) {
final CardList creatures = aiPlayables.getType("Creature").getMonoColored(true);
creatures.sort(this.bestCreature);
creatures.sort(new CreatureComparator());
debugCreatures(creatures);
if (creatures.size() > 0) {
@@ -186,7 +181,7 @@ public class BoosterDraftAI {
// list, and 1 non-creature.
typeList = colorList.getType("Creature");
if (typeList.size() > 0) {
typeList.sort(this.bestCreature);
typeList.sort(new CreatureComparator());
wouldPick.add(typeList.get(0));
if (typeList.size() > 1) {
wouldPick.add(typeList.get(1));
@@ -353,328 +348,11 @@ public class BoosterDraftAI {
System.out.println("Deck[" + i + "]");
}
out[i] = this.buildDeck(this.deck[i], this.playerColors.get(i));
out[i] = new BoosterDeck(this.deck[i], this.playerColors.get(i));
}
return out;
} // getDecks()
/**
* <p>
* buildDeck.
* </p>
*
* @param dList
* a {@link forge.CardList} object.
* @param pClrs
* a {@link forge.game.limited.DeckColors} object.
* @return a {@link forge.deck.Deck} object.
*/
private Deck buildDeck(final CardList dList, final DeckColors pClrs) {
final CardList outList = new CardList();
int cardsNeeded = 22;
int landsNeeded = 18;
final CardList aiPlayables = dList.filter(new CardListFilter() {
@Override
public boolean addCard(final Card c) {
return !(c.getSVar("RemAIDeck").equals("True") || c.getSVar("RemRandomDeck").equals("True"));
}
});
for (int i = 0; i < aiPlayables.size(); i++) {
dList.remove(aiPlayables.get(i));
}
final CardList creatures = aiPlayables.getType("Creature").getOnly2Colors(pClrs.getColor1(), pClrs.getColor2());
int nCreatures = 15;
creatures.sort(this.bestCreature);
// 1.Add up to 15 on-color creatures
int i = 0;
while (nCreatures > 0 && creatures.size() > 0) {
final Card c = creatures.get(0);
outList.add(c);
cardsNeeded--;
nCreatures--;
aiPlayables.remove(c);
creatures.remove(c);
if (Constant.Runtime.DEV_MODE[0]) {
System.out.println("Creature[" + i + "]:" + c.getName() + " (" + c.getManaCost() + ")");
}
i++;
}
/*
* CardList otherCreatures = aiPlayables.getType("Creature"); while
* ((nCreatures > 1) && (otherCreatures.size() > 1)) { final Card c =
* otherCreatures.get(MyRandom.getRandom().nextInt(otherCreatures.size()
* - 1)); outList.add(c); cardsNeeded--; nCreatures--;
* aiPlayables.remove(c);
*
* otherCreatures = aiPlayables.getType("Creature");
*
* if (Constant.Runtime.DEV_MODE[0]) {
* System.out.println("AddCreature: " + c.getName() + " (" +
* c.getManaCost() + ")"); } }
*/
CardList others = aiPlayables.getNotType("Creature").getNotType("Land")
.getOnly2Colors(pClrs.getColor1(), pClrs.getColor2());
// 2.Try to fill up to 22 with on-color non-creature cards
int ii = 0;
while (cardsNeeded > 0 && others.size() > 0) {
int index = 0;
if (others.size() > 1) {
index = MyRandom.getRandom().nextInt(others.size() - 1);
}
final Card c = others.get(index);
// out.addMain(c.getName());
outList.add(c);
cardsNeeded--;
aiPlayables.remove(c);
others = aiPlayables.getNotType("Creature").getNotType("Land")
.getOnly2Colors(pClrs.getColor1(), pClrs.getColor2());
if (Constant.Runtime.DEV_MODE[0]) {
System.out.println("Others[" + ii++ + "]:" + c.getName() + " (" + c.getManaCost() + ")");
}
}
i = 0;
// 3.Try to fill up to 22 with on-color creatures cards (if more than 15
// are present)
while (cardsNeeded > 0 && (0 < creatures.size())) {
final Card c = creatures.get(0);
outList.add(c);
cardsNeeded--;
aiPlayables.remove(c);
creatures.remove(c);
if (Constant.Runtime.DEV_MODE[0]) {
System.out.println("Creature[" + i + "]:" + c.getName() + " (" + c.getManaCost() + ")");
}
i++;
}
CardList nonLands = aiPlayables.getNotType("Land").getOnly2Colors(pClrs.getColor1(), pClrs.getColor2());
// 4. If there are still on-color cards and the average cmc is low add a
// 23rd card.
if (cardsNeeded == 0 && CardListUtil.getAverageCMC(outList) < 3 && !nonLands.isEmpty()) {
Card c = nonLands.get(0);
outList.add(c);
aiPlayables.remove(0);
landsNeeded--;
}
// 5. If there are still less than 22 non-land cards add off-color
// cards.
ii = 0;
CardList z = aiPlayables.getNotType("Land");
while ((cardsNeeded > 0) && (z.size() > 1)) {
// if (z.size() < 1)
// throw new
// RuntimeException("BoosterDraftAI : buildDeck() error, deck does not have enough non-lands");
final Card c = z.get(MyRandom.getRandom().nextInt(z.size() - 1));
// out.addMain(c.getName());
outList.add(c);
cardsNeeded--;
aiPlayables.remove(c);
z = aiPlayables.getNotType("Land");
if (Constant.Runtime.DEV_MODE[0]) {
System.out.println("NonLands[" + ii++ + "]:" + c.getName() + "(" + c.getManaCost() + ")");
}
}
// 6. If it's not a mono color deck, add non-basic lands.
CardList lands = aiPlayables.getType("Land");
while (!pClrs.getColor1().equals(pClrs.getColor2()) && landsNeeded > 0 && lands.size() > 0) {
final Card c = lands.get(0);
outList.add(c);
landsNeeded--;
aiPlayables.remove(c);
lands = aiPlayables.getType("Land");
if (Constant.Runtime.DEV_MODE[0]) {
System.out.println("Land:" + c.getName());
}
}
// attempt to optimize basic land counts according
// to color representation
final CCnt[] clrCnts = { new CCnt("Plains", 0), new CCnt("Island", 0), new CCnt("Swamp", 0),
new CCnt("Mountain", 0), new CCnt("Forest", 0) };
// count each card color using mana costs
// TODO: count hybrid mana differently?
for (i = 0; i < outList.size(); i++) {
final CardManaCost mc = outList.get(i).getManaCost();
// count each mana symbol in the mana cost
for (ManaCostShard shard : mc.getShards()) {
byte mask = shard.getColorMask();
if ((mask & CardColor.WHITE) > 0) {
clrCnts[0].setCount(clrCnts[0].getCount() + 1);
}
if ((mask & CardColor.BLUE) > 0) {
clrCnts[1].setCount(clrCnts[1].getCount() + 1);
}
if ((mask & CardColor.BLACK) > 0) {
clrCnts[2].setCount(clrCnts[2].getCount() + 1);
}
if ((mask & CardColor.RED) > 0) {
clrCnts[3].setCount(clrCnts[3].getCount() + 1);
}
if ((mask & CardColor.GREEN) > 0) {
clrCnts[4].setCount(clrCnts[4].getCount() + 1);
}
}
}
if (landsNeeded > 0) {
// total of all ClrCnts
int totalColor = 0;
for (i = 0; i < 5; i++) {
totalColor += clrCnts[i].getCount();
// tmpDeck += ClrCnts[i].Color + ":" + ClrCnts[i].Count + "\n";
}
// tmpDeck += "totalColor:" + totalColor + "\n";
for (i = 0; i < 5; i++) {
if (clrCnts[i].getCount() > 0) { // calculate number of lands
// for
// each color
final float p = (float) clrCnts[i].getCount() / (float) totalColor;
final int nLand = (int) (landsNeeded * p) + 1;
// tmpDeck += "nLand-" + ClrCnts[i].Color + ":" + nLand +
// "\n";
if (Constant.Runtime.DEV_MODE[0]) {
System.out.println("Basics[" + clrCnts[i].getColor() + "]:" + nLand);
}
// just to prevent a null exception by the deck size fixing
// code
// CardCounts.put(ClrCnts[i].Color, nLand);
for (int j = 0; j <= nLand; j++) {
final Card c = AllZone.getCardFactory().getCard(clrCnts[i].getColor(),
AllZone.getComputerPlayer());
c.setCurSetCode(IBoosterDraft.LAND_SET_CODE[0]);
outList.add(c);
landsNeeded--;
}
}
}
int n = 0;
while (landsNeeded > 0) {
if (clrCnts[n].getCount() > 0) {
final Card c = AllZone.getCardFactory().getCard(clrCnts[n].getColor(), AllZone.getComputerPlayer());
c.setCurSetCode(IBoosterDraft.LAND_SET_CODE[0]);
outList.add(c);
landsNeeded--;
if (Constant.Runtime.DEV_MODE[0]) {
System.out.println("AddBasics: " + c.getName());
}
}
if (++n > 4) {
n = 0;
}
}
}
while (outList.size() > 40) {
final Card c = outList.get(MyRandom.getRandom().nextInt(outList.size() - 1));
outList.remove(c);
aiPlayables.add(c);
}
while (outList.size() < 40) {
if (aiPlayables.size() > 1) {
final Card c = aiPlayables.get(MyRandom.getRandom().nextInt(aiPlayables.size() - 1));
outList.add(c);
aiPlayables.remove(c);
} else if (aiPlayables.size() == 1) {
final Card c = aiPlayables.get(0);
outList.add(c);
aiPlayables.remove(c);
} else {
// if no playable cards remain fill up with basic lands
for (i = 0; i < 5; i++) {
if (clrCnts[i].getCount() > 0) {
final Card c = AllZone.getCardFactory().getCard(clrCnts[i].getColor(),
AllZone.getComputerPlayer());
c.setCurSetCode(IBoosterDraft.LAND_SET_CODE[0]);
outList.add(c);
break;
}
}
}
}
if (outList.size() == 40) {
final Deck out = new Deck();
out.getMain().add(outList);
out.getSideboard().add(aiPlayables);
out.getSideboard().add(dList);
return out;
}
throw new RuntimeException("BoosterDraftAI : buildDeck() error, decksize not 40");
}
/*
* private Deck getDeck(CardList list) { Deck out = new
* Deck(GameType.Draft); for(int i = 0; i < list.size(); i++)
* out.addMain(list.get(i).getName());
*
* return out; }//getDeck()
*
* //add Land to list argument private void addLand(CardList list, String[]
* color) { Card land; for(int i = 0; i < 9; i++) { land =
* AllZone.getCardFactory().getCard(colorToLand.get(color[0]).toString(),
* AllZone.getComputerPlayer());
*
* land.setCurSetCode(land.getMostRecentSet());
* land.setImageFilename(CardUtil.buildFilename(land));
*
* list.add(land);
*
* land =
* AllZone.getCardFactory().getCard(colorToLand.get(color[1]).toString(),
* AllZone.getComputerPlayer());
*
* land.setCurSetCode(land.getMostRecentSet());
* land.setImageFilename(CardUtil.buildFilename(land));
*
* list.add(land); }
*
* //if(list.getType("Land").size() != 18) //throw new RuntimeException(
* "BoosterDraftAI : addLand() error, deck does not have 18 lands - "
* +list.getType("Land").size());
*
* //if(list.size() != 40) //throw new
* RuntimeException("BoosterDraftAI : addLand() error, deck is not 40 cards - "
* +list.size()); }//addLand()
*/
// returns 7 different ints, within the range of 0-9
/**
@@ -758,48 +436,6 @@ public class BoosterDraftAI {
{ Constant.Color.RED, Constant.Color.WHITE } };
private final Comparator<Card> bestCreature = new Comparator<Card>() {
@Override
public int compare(final Card a, final Card b) {
int cmcA = a.getCMC();
cmcA *= 30; // average creature from evaluateCreature comes out to 30 * CMC
int cmcB = b.getCMC();
cmcB *= 30;
int evalA = CardFactoryUtil.evaluateCreature(a) - 100; // evaluateCreature starts at 100
int evalB = CardFactoryUtil.evaluateCreature(b) - 100;
int rarA = 0;
int rarB = 0;
if (a.getCurSetRarity().equals("Common")) {
rarA = 1;
} else if (a.getCurSetRarity().equals("Uncommon")) {
rarA = 2;
} else if (a.getCurSetRarity().equals("Rare")) {
rarA = 4;
} else if (a.getCurSetRarity().equals("Mythic")) {
rarA = 8;
}
if (b.getCurSetRarity().equals("Common")) {
rarB = 1;
} else if (b.getCurSetRarity().equals("Uncommon")) {
rarB = 2;
} else if (b.getCurSetRarity().equals("Rare")) {
rarB = 4;
} else if (b.getCurSetRarity().equals("Mythic")) {
rarB = 8;
}
final int scoreA = evalA - cmcA + rarA;
final int scoreB = evalB - cmcB + rarB;
return scoreB - scoreA;
}
};
private static void debugCreatures(CardList creatures) {
if (Constant.Runtime.DEV_MODE[0]) {
for (Card c : creatures) {

View File

@@ -0,0 +1,52 @@
package forge.game.limited;
import java.util.Comparator;
import forge.Card;
import forge.card.cardfactory.CardFactoryUtil;
/**
* Sorts creatures, best first.
*
*/
public class CreatureComparator implements Comparator<Card> {
public int compare(final Card a, final Card b) {
int cmcA = a.getCMC();
cmcA *= 30; // average creature from evaluateCreature is about 30 * CMC
int cmcB = b.getCMC();
cmcB *= 30;
// evaluateCreature starts at 100
int evalA = CardFactoryUtil.evaluateCreature(a) - 100;
int evalB = CardFactoryUtil.evaluateCreature(b) - 100;
int rarA = 0;
int rarB = 0;
if (a.getCurSetRarity().equals("Common")) {
rarA = 1;
} else if (a.getCurSetRarity().equals("Uncommon")) {
rarA = 2;
} else if (a.getCurSetRarity().equals("Rare")) {
rarA = 4;
} else if (a.getCurSetRarity().equals("Mythic")) {
rarA = 8;
}
if (b.getCurSetRarity().equals("Common")) {
rarB = 1;
} else if (b.getCurSetRarity().equals("Uncommon")) {
rarB = 2;
} else if (b.getCurSetRarity().equals("Rare")) {
rarB = 4;
} else if (b.getCurSetRarity().equals("Mythic")) {
rarB = 8;
}
final int scoreA = evalA - cmcA + rarA;
final int scoreB = evalB - cmcB + rarB;
return scoreB - scoreA;
}
}