mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 04:38:00 +00:00
- Updated AI in BoosterDraftAI
This commit is contained in:
@@ -6,7 +6,6 @@ PT:6/6
|
|||||||
K:Flying
|
K:Flying
|
||||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.Self | Execute$ TrigChange | OptionalDecider$ You | TriggerDescription$ When CARDNAME enters the battlefield, you may search your library for a card, put it into your hand, then shuffle your library.
|
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.Self | Execute$ TrigChange | OptionalDecider$ You | TriggerDescription$ When CARDNAME enters the battlefield, you may search your library for a card, put it into your hand, then shuffle your library.
|
||||||
SVar:TrigChange:AB$ChangeZone | Cost$ 0 | Origin$ Library | Destination$ Hand | ChangeType$ Card | ChangeNum$ 1
|
SVar:TrigChange:AB$ChangeZone | Cost$ 0 | Origin$ Library | Destination$ Hand | ChangeType$ Card | ChangeNum$ 1
|
||||||
SVar:RemRandomDeck:True
|
|
||||||
SVar:Rarity:Rare
|
SVar:Rarity:Rare
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/rune_scarred_demon.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/rune_scarred_demon.jpg
|
||||||
SetInfo:M12|Rare|http://magiccards.info/scans/en/m12/106.jpg
|
SetInfo:M12|Rare|http://magiccards.info/scans/en/m12/106.jpg
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ Types:Artifact
|
|||||||
Text:no text
|
Text:no text
|
||||||
A:AB$ Token | Cost$ 1 T | TokenAmount$ X | References$ X | TokenName$ Soldier | TokenTypes$ Creature,Soldier | TokenOwner$ You | TokenColors$ White | TokenPower$ 1 | TokenToughness$ 1 | SpellDescription$ Put a 1/1 white Soldier creature token onto the battlefield. Put five of those tokens onto the battlefield instead if you control artifacts named Crown of Empires and Scepter of Empires.
|
A:AB$ Token | Cost$ 1 T | TokenAmount$ X | References$ X | TokenName$ Soldier | TokenTypes$ Creature,Soldier | TokenOwner$ You | TokenColors$ White | TokenPower$ 1 | TokenToughness$ 1 | SpellDescription$ Put a 1/1 white Soldier creature token onto the battlefield. Put five of those tokens onto the battlefield instead if you control artifacts named Crown of Empires and Scepter of Empires.
|
||||||
SVar:X:Count$AllM12Empires.5.1
|
SVar:X:Count$AllM12Empires.5.1
|
||||||
|
SVar:RemRandomDeck:True
|
||||||
SVar:Rarity:Rare
|
SVar:Rarity:Rare
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/throne_of_empires.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/throne_of_empires.jpg
|
||||||
SetInfo:M12|Rare|http://magiccards.info/scans/en/m12/221.jpg
|
SetInfo:M12|Rare|http://magiccards.info/scans/en/m12/221.jpg
|
||||||
|
|||||||
@@ -938,14 +938,15 @@ public class CardList implements Iterable<Card> {
|
|||||||
* <p>
|
* <p>
|
||||||
* getMonoColored.
|
* getMonoColored.
|
||||||
* </p>
|
* </p>
|
||||||
|
* @param includeColorless should colorless cards be included?
|
||||||
*
|
*
|
||||||
* @return a {@link forge.CardList} object.
|
* @return a {@link forge.CardList} object.
|
||||||
*/
|
*/
|
||||||
public final CardList getMonoColored() {
|
public final CardList getMonoColored(final boolean includeColorless) {
|
||||||
return this.filter(new CardListFilter() {
|
return this.filter(new CardListFilter() {
|
||||||
@Override
|
@Override
|
||||||
public boolean addCard(final Card c) {
|
public boolean addCard(final Card c) {
|
||||||
return (CardUtil.getColors(c).size() == 1 && !c.isColorless());
|
return (CardUtil.getColors(c).size() == 1 && (includeColorless || !c.isColorless()));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -592,6 +592,9 @@ public class CardFactoryUtil {
|
|||||||
if (c.hasStartOfKeyword("Vanishing")) {
|
if (c.hasStartOfKeyword("Vanishing")) {
|
||||||
value -= 20; // not used atm
|
value -= 20; // not used atm
|
||||||
}
|
}
|
||||||
|
if (c.getSVar("Targeting").equals("Dies")) {
|
||||||
|
value -= 25;
|
||||||
|
}
|
||||||
|
|
||||||
for (final SpellAbility sa : c.getSpellAbilities()) {
|
for (final SpellAbility sa : c.getSpellAbilities()) {
|
||||||
if (sa.isAbility()) {
|
if (sa.isAbility()) {
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import forge.CardListUtil;
|
|||||||
import forge.Constant;
|
import forge.Constant;
|
||||||
import forge.card.CardColor;
|
import forge.card.CardColor;
|
||||||
import forge.card.CardManaCost;
|
import forge.card.CardManaCost;
|
||||||
|
import forge.card.cardfactory.CardFactoryUtil;
|
||||||
import forge.card.mana.ManaCostShard;
|
import forge.card.mana.ManaCostShard;
|
||||||
import forge.card.spellability.AbilityMana;
|
import forge.card.spellability.AbilityMana;
|
||||||
import forge.deck.Deck;
|
import forge.deck.Deck;
|
||||||
@@ -106,20 +107,28 @@ public class BoosterDraftAI {
|
|||||||
|
|
||||||
if (this.playerColors.get(player).getColor1().equals("none")
|
if (this.playerColors.get(player).getColor1().equals("none")
|
||||||
&& this.playerColors.get(player).getColor2().equals("none")) {
|
&& this.playerColors.get(player).getColor2().equals("none")) {
|
||||||
//
|
|
||||||
final CardList creatures = aiPlayables.getType("Creature").getColored();
|
|
||||||
creatures.sort(this.bestCreature);
|
|
||||||
// for (int i=0; i<creatures.size(); i++)
|
|
||||||
// System.out.println("creature[" + i + "]: " +
|
|
||||||
// creatures.get(i).getName());
|
|
||||||
|
|
||||||
if (creatures.size() > 0) {
|
CardList walkers = aiPlayables.getType("Planeswalker");
|
||||||
pickedCard = creatures.get(creatures.size() - 1);
|
if (walkers.size() > 0) {
|
||||||
|
pickedCard = walkers.get(0);
|
||||||
|
hasPicked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasPicked) {
|
||||||
|
final CardList creatures = aiPlayables.getType("Creature");
|
||||||
|
creatures.sort(this.bestCreature);
|
||||||
|
debugCreatures(creatures);
|
||||||
|
|
||||||
|
if (creatures.size() > 0) {
|
||||||
|
pickedCard = creatures.get(0);
|
||||||
|
hasPicked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hasPicked && !pickedCard.isColorless()) {
|
||||||
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());
|
||||||
}
|
}
|
||||||
|
|
||||||
this.playerColors.get(player).setMana1(
|
this.playerColors.get(player).setMana1(
|
||||||
this.playerColors.get(player).colorToMana(this.playerColors.get(player).getColor1()));
|
this.playerColors.get(player).colorToMana(this.playerColors.get(player).getColor1()));
|
||||||
|
|
||||||
@@ -135,19 +144,27 @@ public class BoosterDraftAI {
|
|||||||
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()));
|
||||||
}
|
}
|
||||||
|
|
||||||
hasPicked = true;
|
|
||||||
}
|
}
|
||||||
} else if (!this.playerColors.get(player).getColor1().equals("none")
|
} else if (!this.playerColors.get(player).getColor1().equals("none")
|
||||||
&& this.playerColors.get(player).getColor2().equals("none")) {
|
&& this.playerColors.get(player).getColor2().equals("none")) {
|
||||||
final CardList creatures = aiPlayables.getType("Creature").getMonoColored();
|
|
||||||
creatures.sort(this.bestCreature);
|
|
||||||
// for (int i=0; i<creatures.size(); i++)
|
|
||||||
// System.out.println("creature[" + i + "]: " +
|
|
||||||
// creatures.get(i).getName());
|
|
||||||
|
|
||||||
if (creatures.size() > 0) {
|
CardList walkers = aiPlayables.getType("Planeswalker");
|
||||||
pickedCard = creatures.get(creatures.size() - 1);
|
if (walkers.size() > 0) {
|
||||||
|
pickedCard = walkers.get(0);
|
||||||
|
hasPicked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasPicked) {
|
||||||
|
final CardList creatures = aiPlayables.getType("Creature").getMonoColored(true);
|
||||||
|
creatures.sort(this.bestCreature);
|
||||||
|
debugCreatures(creatures);
|
||||||
|
|
||||||
|
if (creatures.size() > 0) {
|
||||||
|
pickedCard = creatures.get(0);
|
||||||
|
hasPicked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hasPicked && !pickedCard.isColorless()) {
|
||||||
this.playerColors.get(player).setColor2(pickedCard.getColor().get(0).toStringArray().get(0));
|
this.playerColors.get(player).setColor2(pickedCard.getColor().get(0).toStringArray().get(0));
|
||||||
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());
|
||||||
@@ -155,7 +172,6 @@ public class BoosterDraftAI {
|
|||||||
|
|
||||||
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()));
|
||||||
hasPicked = true;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
CardList typeList;
|
CardList typeList;
|
||||||
@@ -165,10 +181,12 @@ public class BoosterDraftAI {
|
|||||||
this.playerColors.get(player).getColor2());
|
this.playerColors.get(player).getColor2());
|
||||||
|
|
||||||
if (colorList.size() > 0) {
|
if (colorList.size() > 0) {
|
||||||
|
// Since we want about 15 creatures and 7 non-creatures in our deck, we want to pick
|
||||||
|
// about 2 creatures for every 1 non-creature. So put 2 creatures in our wouldPick
|
||||||
|
// list, and 1 non-creature.
|
||||||
typeList = colorList.getType("Creature");
|
typeList = colorList.getType("Creature");
|
||||||
if (typeList.size() > 0) {
|
if (typeList.size() > 0) {
|
||||||
typeList.sort(this.bestCreature);
|
typeList.sort(this.bestCreature);
|
||||||
typeList.reverse();
|
|
||||||
wouldPick.add(typeList.get(0));
|
wouldPick.add(typeList.get(0));
|
||||||
if (typeList.size() > 1) {
|
if (typeList.size() > 1) {
|
||||||
wouldPick.add(typeList.get(1));
|
wouldPick.add(typeList.get(1));
|
||||||
@@ -177,12 +195,8 @@ public class BoosterDraftAI {
|
|||||||
|
|
||||||
typeList = colorList.getType("Instant");
|
typeList = colorList.getType("Instant");
|
||||||
typeList.addAll(colorList.getType("Sorcery"));
|
typeList.addAll(colorList.getType("Sorcery"));
|
||||||
if (typeList.size() > 0) {
|
typeList.addAll(colorList.getType("Enchantment"));
|
||||||
CardListUtil.sortCMC(typeList);
|
typeList.addAll(colorList.getType("Artifact"));
|
||||||
wouldPick.add(typeList.get(typeList.size() / 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
typeList = colorList.getType("Enchantment");
|
|
||||||
if (typeList.size() > 0) {
|
if (typeList.size() > 0) {
|
||||||
CardListUtil.sortCMC(typeList);
|
CardListUtil.sortCMC(typeList);
|
||||||
wouldPick.add(typeList.get(0));
|
wouldPick.add(typeList.get(0));
|
||||||
@@ -190,13 +204,9 @@ public class BoosterDraftAI {
|
|||||||
|
|
||||||
typeList = colorList.getType("Planeswalker");
|
typeList = colorList.getType("Planeswalker");
|
||||||
if (typeList.size() > 0) {
|
if (typeList.size() > 0) {
|
||||||
wouldPick.add(typeList.get(0));
|
// just take it...
|
||||||
}
|
pickedCard = typeList.get(0);
|
||||||
|
hasPicked = true;
|
||||||
typeList = colorList.getType("Artifact");
|
|
||||||
if (typeList.size() > 0) {
|
|
||||||
CardListUtil.sortCMC(typeList);
|
|
||||||
wouldPick.add(typeList.get(0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -240,16 +250,14 @@ public class BoosterDraftAI {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hasPicked) {
|
if (!hasPicked) {
|
||||||
final Random r = new Random();
|
final Random r = new Random();
|
||||||
|
|
||||||
if (wouldPick.size() > 0) {
|
if (wouldPick.size() > 0) {
|
||||||
wouldPick.shuffle();
|
|
||||||
pickedCard = wouldPick.get(r.nextInt(wouldPick.size()));
|
pickedCard = wouldPick.get(r.nextInt(wouldPick.size()));
|
||||||
} else {
|
} else {
|
||||||
chooseFrom.shuffle();
|
|
||||||
pickedCard = chooseFrom.get(r.nextInt(chooseFrom.size()));
|
pickedCard = chooseFrom.get(r.nextInt(chooseFrom.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -382,7 +390,6 @@ public class BoosterDraftAI {
|
|||||||
int nCreatures = 15;
|
int nCreatures = 15;
|
||||||
|
|
||||||
creatures.sort(this.bestCreature);
|
creatures.sort(this.bestCreature);
|
||||||
creatures.reverse();
|
|
||||||
|
|
||||||
// 1.Add up to 15 on-color creatures
|
// 1.Add up to 15 on-color creatures
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@@ -402,20 +409,19 @@ public class BoosterDraftAI {
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*CardList otherCreatures = aiPlayables.getType("Creature");
|
/*
|
||||||
while ((nCreatures > 1) && (otherCreatures.size() > 1)) {
|
* CardList otherCreatures = aiPlayables.getType("Creature"); while
|
||||||
final Card c = otherCreatures.get(MyRandom.getRandom().nextInt(otherCreatures.size() - 1));
|
* ((nCreatures > 1) && (otherCreatures.size() > 1)) { final Card c =
|
||||||
outList.add(c);
|
* otherCreatures.get(MyRandom.getRandom().nextInt(otherCreatures.size()
|
||||||
cardsNeeded--;
|
* - 1)); outList.add(c); cardsNeeded--; nCreatures--;
|
||||||
nCreatures--;
|
* aiPlayables.remove(c);
|
||||||
aiPlayables.remove(c);
|
*
|
||||||
|
* otherCreatures = aiPlayables.getType("Creature");
|
||||||
otherCreatures = aiPlayables.getType("Creature");
|
*
|
||||||
|
* if (Constant.Runtime.DEV_MODE[0]) {
|
||||||
if (Constant.Runtime.DEV_MODE[0]) {
|
* System.out.println("AddCreature: " + c.getName() + " (" +
|
||||||
System.out.println("AddCreature: " + c.getName() + " (" + c.getManaCost() + ")");
|
* c.getManaCost() + ")"); } }
|
||||||
}
|
*/
|
||||||
}*/
|
|
||||||
|
|
||||||
CardList others = aiPlayables.getNotType("Creature").getNotType("Land")
|
CardList others = aiPlayables.getNotType("Creature").getNotType("Land")
|
||||||
.getOnly2Colors(pClrs.getColor1(), pClrs.getColor2());
|
.getOnly2Colors(pClrs.getColor1(), pClrs.getColor2());
|
||||||
@@ -443,7 +449,8 @@ public class BoosterDraftAI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
// 3.Try to fill up to 22 with on-color creatures cards (if more than 15 are present)
|
// 3.Try to fill up to 22 with on-color creatures cards (if more than 15
|
||||||
|
// are present)
|
||||||
while (cardsNeeded > 0 && (0 < creatures.size())) {
|
while (cardsNeeded > 0 && (0 < creatures.size())) {
|
||||||
final Card c = creatures.get(0);
|
final Card c = creatures.get(0);
|
||||||
|
|
||||||
@@ -459,10 +466,10 @@ public class BoosterDraftAI {
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
CardList nonLands = aiPlayables.getNotType("Land")
|
CardList nonLands = aiPlayables.getNotType("Land").getOnly2Colors(pClrs.getColor1(), pClrs.getColor2());
|
||||||
.getOnly2Colors(pClrs.getColor1(), pClrs.getColor2());
|
|
||||||
|
|
||||||
// 4. If there are still on-color cards and the average cmc is low add a 23rd card.
|
// 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()) {
|
if (cardsNeeded == 0 && CardListUtil.getAverageCMC(outList) < 3 && !nonLands.isEmpty()) {
|
||||||
Card c = nonLands.get(0);
|
Card c = nonLands.get(0);
|
||||||
outList.add(c);
|
outList.add(c);
|
||||||
@@ -470,7 +477,8 @@ public class BoosterDraftAI {
|
|||||||
landsNeeded--;
|
landsNeeded--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. If there are still less than 22 non-land cards add off-color cards.
|
// 5. If there are still less than 22 non-land cards add off-color
|
||||||
|
// cards.
|
||||||
ii = 0;
|
ii = 0;
|
||||||
CardList z = aiPlayables.getNotType("Land");
|
CardList z = aiPlayables.getNotType("Land");
|
||||||
while ((cardsNeeded > 0) && (z.size() > 1)) {
|
while ((cardsNeeded > 0) && (z.size() > 1)) {
|
||||||
@@ -610,7 +618,7 @@ public class BoosterDraftAI {
|
|||||||
outList.add(c);
|
outList.add(c);
|
||||||
aiPlayables.remove(c);
|
aiPlayables.remove(c);
|
||||||
} else {
|
} else {
|
||||||
//if no playable cards remain fill up with basic lands
|
// if no playable cards remain fill up with basic lands
|
||||||
for (i = 0; i < 5; i++) {
|
for (i = 0; i < 5; i++) {
|
||||||
if (clrCnts[i].getCount() > 0) {
|
if (clrCnts[i].getCount() > 0) {
|
||||||
final Card c = AllZone.getCardFactory().getCard(clrCnts[i].getColor(),
|
final Card c = AllZone.getCardFactory().getCard(clrCnts[i].getColor(),
|
||||||
@@ -754,31 +762,13 @@ public class BoosterDraftAI {
|
|||||||
@Override
|
@Override
|
||||||
public int compare(final Card a, final Card b) {
|
public int compare(final Card a, final Card b) {
|
||||||
int cmcA = a.getCMC();
|
int cmcA = a.getCMC();
|
||||||
if (cmcA == 0) {
|
cmcA *= 30; // average creature from evaluateCreature comes out to 30 * CMC
|
||||||
cmcA = 1;
|
|
||||||
}
|
|
||||||
cmcA *= 10;
|
|
||||||
|
|
||||||
int cmcB = b.getCMC();
|
int cmcB = b.getCMC();
|
||||||
if (cmcB == 0) {
|
cmcB *= 30;
|
||||||
cmcB = 1;
|
|
||||||
}
|
|
||||||
cmcB *= 10;
|
|
||||||
|
|
||||||
final int attA = a.getBaseAttack() * 10;
|
int evalA = CardFactoryUtil.evaluateCreature(a) - 100; // evaluateCreature starts at 100
|
||||||
final int attB = b.getBaseAttack() * 10;
|
int evalB = CardFactoryUtil.evaluateCreature(b) - 100;
|
||||||
|
|
||||||
final int defA = a.getBaseDefense() * 10;
|
|
||||||
final int defB = b.getBaseDefense() * 10;
|
|
||||||
|
|
||||||
final int keyA = a.getKeyword().size() * 10;
|
|
||||||
final int keyB = b.getKeyword().size() * 10;
|
|
||||||
|
|
||||||
final int abA = a.getSpellAbility().length * 10;
|
|
||||||
final int abB = b.getSpellAbility().length * 10;
|
|
||||||
|
|
||||||
final int trgA = a.getTriggers().size() * 10;
|
|
||||||
final int trgB = b.getTriggers().size() * 10;
|
|
||||||
|
|
||||||
int rarA = 0;
|
int rarA = 0;
|
||||||
int rarB = 0;
|
int rarB = 0;
|
||||||
@@ -803,11 +793,19 @@ public class BoosterDraftAI {
|
|||||||
rarB = 8;
|
rarB = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
final int scoreA = ((attA + defA) / cmcA) + keyA + abA + trgA + rarA;
|
final int scoreA = evalA - cmcA + rarA;
|
||||||
final int scoreB = ((attB + defB) / cmcB) + keyB + abB + trgB + rarB;
|
final int scoreB = evalB - cmcB + rarB;
|
||||||
|
|
||||||
return scoreA - scoreB;
|
return scoreB - scoreA;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private static void debugCreatures(CardList creatures) {
|
||||||
|
if (Constant.Runtime.DEV_MODE[0]) {
|
||||||
|
for (Card c : creatures) {
|
||||||
|
System.out.println(c.toString() + ": Cost " + c.getCMC() + ", Eval " + CardFactoryUtil.evaluateCreature(c));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} // BoosterDraftAI()
|
} // BoosterDraftAI()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user