mirror of
https://github.com/correl/mage.git
synced 2025-03-13 09:19:53 -09:00
Random generated decks improvements and fixes for AI:
* added generation of only basic lands decks; * fixed wrong color cards selection;
This commit is contained in:
parent
2870c3ab2a
commit
9d131f6bde
2 changed files with 116 additions and 12 deletions
|
@ -1633,7 +1633,42 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
}
|
||||
|
||||
public static Deck buildDeck(List<Card> cardPool, final List<ColoredManaSymbol> colors) {
|
||||
return buildDeck(cardPool, colors, false);
|
||||
}
|
||||
|
||||
public static Deck buildDeck(List<Card> cardPool, final List<ColoredManaSymbol> colors, boolean onlyBasicLands) {
|
||||
if (onlyBasicLands) {
|
||||
return buildDeckWithOnlyBasicLands(cardPool);
|
||||
} else {
|
||||
return buildDeckWithNormalCards(cardPool, colors);
|
||||
}
|
||||
}
|
||||
|
||||
public static Deck buildDeckWithOnlyBasicLands(List<Card> cardPool) {
|
||||
// random cards from card pool
|
||||
Deck deck = new Deck();
|
||||
final int DECK_SIZE = 40;
|
||||
|
||||
List<Card> sortedCards = new ArrayList<>(cardPool);
|
||||
if (sortedCards.size() > 0) {
|
||||
while (deck.getCards().size() < DECK_SIZE) {
|
||||
deck.getCards().add(sortedCards.get(RandomUtil.nextInt(sortedCards.size())));
|
||||
}
|
||||
return deck;
|
||||
} else {
|
||||
addBasicLands(deck, "Forest", DECK_SIZE);
|
||||
return deck;
|
||||
}
|
||||
}
|
||||
|
||||
public static Deck buildDeckWithNormalCards(List<Card> cardPool, final List<ColoredManaSymbol> colors) {
|
||||
// top 23 cards plus basic lands until 40 deck size
|
||||
Deck deck = new Deck();
|
||||
final int DECK_SIZE = 40;
|
||||
final int DECK_CARDS_COUNT = 23;
|
||||
final int DECK_LANDS_COUNT = DECK_SIZE - DECK_CARDS_COUNT;
|
||||
|
||||
// sort card pool by top score
|
||||
List<Card> sortedCards = new ArrayList<>(cardPool);
|
||||
Collections.sort(sortedCards, new Comparator<Card>() {
|
||||
@Override
|
||||
|
@ -1643,8 +1678,10 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
return score2.compareTo(score1);
|
||||
}
|
||||
});
|
||||
|
||||
// get top cards
|
||||
int cardNum = 0;
|
||||
while (deck.getCards().size() < 23 && sortedCards.size() > cardNum) {
|
||||
while (deck.getCards().size() < DECK_CARDS_COUNT && sortedCards.size() > cardNum) {
|
||||
Card card = sortedCards.get(cardNum);
|
||||
if (!card.isBasic()) {
|
||||
deck.getCards().add(card);
|
||||
|
@ -1652,53 +1689,61 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
}
|
||||
cardNum++;
|
||||
}
|
||||
// add basic lands
|
||||
|
||||
// add basic lands by color percent
|
||||
// TODO: compensate for non basic lands
|
||||
Mana mana = new Mana();
|
||||
for (Card card : deck.getCards()) {
|
||||
mana.add(card.getManaCost().getMana());
|
||||
}
|
||||
double total = mana.getBlack() + mana.getBlue() + mana.getGreen() + mana.getRed() + mana.getWhite();
|
||||
|
||||
// most frequent land is forest by defalt
|
||||
int mostLand = 0;
|
||||
String mostLandName = "Forest";
|
||||
if (mana.getGreen() > 0) {
|
||||
int number = (int) Math.round(mana.getGreen() / total * 17);
|
||||
int number = (int) Math.round(mana.getGreen() / total * DECK_LANDS_COUNT);
|
||||
addBasicLands(deck, "Forest", number);
|
||||
mostLand = number;
|
||||
}
|
||||
|
||||
if (mana.getBlack() > 0) {
|
||||
int number = (int) Math.round(mana.getBlack() / total * 17);
|
||||
int number = (int) Math.round(mana.getBlack() / total * DECK_LANDS_COUNT);
|
||||
addBasicLands(deck, "Swamp", number);
|
||||
if (number > mostLand) {
|
||||
mostLand = number;
|
||||
mostLandName = "Swamp";
|
||||
}
|
||||
}
|
||||
|
||||
if (mana.getBlue() > 0) {
|
||||
int number = (int) Math.round(mana.getBlue() / total * 17);
|
||||
int number = (int) Math.round(mana.getBlue() / total * DECK_LANDS_COUNT);
|
||||
addBasicLands(deck, "Island", number);
|
||||
if (number > mostLand) {
|
||||
mostLand = number;
|
||||
mostLandName = "Island";
|
||||
}
|
||||
}
|
||||
|
||||
if (mana.getWhite() > 0) {
|
||||
int number = (int) Math.round(mana.getWhite() / total * 17);
|
||||
int number = (int) Math.round(mana.getWhite() / total * DECK_LANDS_COUNT);
|
||||
addBasicLands(deck, "Plains", number);
|
||||
if (number > mostLand) {
|
||||
mostLand = number;
|
||||
mostLandName = "Plains";
|
||||
}
|
||||
}
|
||||
|
||||
if (mana.getRed() > 0) {
|
||||
int number = (int) Math.round(mana.getRed() / total * 17);
|
||||
int number = (int) Math.round(mana.getRed() / total * DECK_LANDS_COUNT);
|
||||
addBasicLands(deck, "Mountain", number);
|
||||
if (number > mostLand) {
|
||||
mostLandName = "Plains";
|
||||
}
|
||||
}
|
||||
|
||||
addBasicLands(deck, mostLandName, 40 - deck.getCards().size());
|
||||
// adds remaining lands (most popular name)
|
||||
addBasicLands(deck, mostLandName, DECK_SIZE - deck.getCards().size());
|
||||
|
||||
return deck;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
*/
|
||||
package mage.cards;
|
||||
|
||||
import mage.Mana;
|
||||
import mage.cards.decks.DeckCardInfo;
|
||||
import mage.cards.decks.DeckCardLayout;
|
||||
import mage.cards.decks.DeckCardLists;
|
||||
|
@ -35,9 +36,12 @@ import mage.cards.repository.CardInfo;
|
|||
import mage.cards.repository.CardRepository;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.ColoredManaSymbol;
|
||||
import mage.constants.Rarity;
|
||||
import mage.filter.FilterMana;
|
||||
import mage.util.ClassScanner;
|
||||
import mage.util.RandomUtil;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.junit.Assert;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.PrintWriter;
|
||||
|
@ -45,7 +49,7 @@ import java.util.*;
|
|||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
* @author BetaSteward_at_googlemail.com, JayDi85
|
||||
*/
|
||||
public class Sets extends HashMap<String, ExpansionSet> {
|
||||
|
||||
|
@ -93,23 +97,50 @@ public class Sets extends HashMap<String, ExpansionSet> {
|
|||
* @return
|
||||
*/
|
||||
public static List<Card> generateRandomCardPool(int cardsCount, List<ColoredManaSymbol> allowedColors) {
|
||||
return generateRandomCardPool(cardsCount, allowedColors, false);
|
||||
}
|
||||
|
||||
public static List<Card> generateRandomCardPool(int cardsCount, List<ColoredManaSymbol> allowedColors, boolean onlyBasicLands) {
|
||||
CardCriteria criteria = new CardCriteria();
|
||||
criteria.notTypes(CardType.LAND);
|
||||
|
||||
if (onlyBasicLands) {
|
||||
// only lands
|
||||
criteria.rarities(Rarity.LAND);
|
||||
criteria.colorless(true); // basic lands is colorless
|
||||
} else {
|
||||
// any card, but not basic lands
|
||||
criteria.notTypes(CardType.LAND);
|
||||
|
||||
// clear colors
|
||||
criteria.white(false);
|
||||
criteria.blue(false);
|
||||
criteria.black(false);
|
||||
criteria.red(false);
|
||||
criteria.green(false);
|
||||
criteria.colorless(false); // colorless is not allowed for gen
|
||||
}
|
||||
|
||||
FilterMana manaNeed = new FilterMana();
|
||||
for (ColoredManaSymbol color : allowedColors) {
|
||||
switch (color) {
|
||||
case W:
|
||||
manaNeed.setWhite(true);
|
||||
criteria.white(true);
|
||||
break;
|
||||
case U:
|
||||
manaNeed.setBlue(true);
|
||||
criteria.blue(true);
|
||||
break;
|
||||
case B:
|
||||
manaNeed.setBlack(true);
|
||||
criteria.black(true);
|
||||
break;
|
||||
case R:
|
||||
manaNeed.setRed(true);
|
||||
criteria.red(true);
|
||||
break;
|
||||
case G:
|
||||
manaNeed.setGreen(true);
|
||||
criteria.green(true);
|
||||
break;
|
||||
}
|
||||
|
@ -123,9 +154,37 @@ public class Sets extends HashMap<String, ExpansionSet> {
|
|||
CardInfo cardInfo = cards.get(RandomUtil.nextInt(cards.size()));
|
||||
Card card = cardInfo != null ? cardInfo.getCard() : null;
|
||||
if (card != null) {
|
||||
cardPool.add(card);
|
||||
count++;
|
||||
|
||||
FilterMana manaCard = card.getColorIdentity();
|
||||
boolean cardManaOK = true;
|
||||
|
||||
if (onlyBasicLands) {
|
||||
// lands is colorless
|
||||
// discard not needed color by mana produce
|
||||
Assert.assertEquals("only basic lands allow", 1, card.getMana().size());
|
||||
for (Mana manaLand : card.getMana()) {
|
||||
if (manaLand.getWhite() > 0 && !manaNeed.isWhite()) { cardManaOK = false; }
|
||||
if (manaLand.getBlue() > 0 && !manaNeed.isBlue()) { cardManaOK = false; }
|
||||
if (manaLand.getBlack() > 0 && !manaNeed.isBlack()) { cardManaOK = false; }
|
||||
if (manaLand.getRed() > 0 && !manaNeed.isRed()) { cardManaOK = false; }
|
||||
if (manaLand.getGreen() > 0 && !manaNeed.isGreen()) { cardManaOK = false; }
|
||||
}
|
||||
} else {
|
||||
// cards
|
||||
// discard any card that have not needed color
|
||||
if (manaCard.isWhite() && !manaNeed.isWhite()) { cardManaOK = false; }
|
||||
if (manaCard.isBlue() && !manaNeed.isBlue()) { cardManaOK = false; }
|
||||
if (manaCard.isBlack() && !manaNeed.isBlack()) { cardManaOK = false; }
|
||||
if (manaCard.isRed() && !manaNeed.isRed()) { cardManaOK = false; }
|
||||
if (manaCard.isGreen() && !manaNeed.isGreen()) { cardManaOK = false; }
|
||||
}
|
||||
|
||||
if (cardManaOK) {
|
||||
cardPool.add(card);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
tries++;
|
||||
if (tries > 4096) { // to avoid infinite loop
|
||||
throw new IllegalStateException("Not enough cards for chosen colors to generate deck: " + allowedColors);
|
||||
|
|
Loading…
Add table
Reference in a new issue