Merge branch 'lands' into 'master'

Improve AI land handling

See merge request core-developers/forge!4435
This commit is contained in:
Michael Kamensky
2021-04-09 07:13:19 +00:00
6 changed files with 35 additions and 36 deletions

View File

@@ -17,7 +17,7 @@
*/
package forge.card;
import java.util.StringTokenizer;
import java.util.*;
import org.apache.commons.lang3.StringUtils;
@@ -28,6 +28,9 @@ import forge.card.mana.ManaCost;
import forge.card.mana.ManaCostShard;
import forge.util.TextUtil;
import static forge.card.MagicColor.Constant.*;
import static org.apache.commons.lang3.StringUtils.containsIgnoreCase;
/**
* A collection of methods containing full
* meta and gameplay properties of a card.
@@ -42,6 +45,7 @@ public final class CardRules implements ICardCharacteristics {
private ICardFace otherPart;
private CardAiHints aiHints;
private ColorSet colorIdentity;
private ColorSet deckbuildingColors;
private String meldWith;
private String partnerWith;
@@ -581,4 +585,25 @@ public final class CardRules implements ICardCharacteristics {
}
return null;
}
public ColorSet getDeckbuildingColors() {
if (deckbuildingColors == null) {
byte colors = 0;
if (mainPart.getType().isLand()) {
colors = getColorIdentity().getColor();
for (int i = 0; i < 5; i++) {
if (containsIgnoreCase(mainPart.getOracleText(), BASIC_LANDS.get(i))) {
colors |= 1 << i;
}
}
} else {
colors = getColor().getColor();
if (getOtherPart() != null) {
colors |= getOtherPart().getManaCost().getColorProfile();
}
}
deckbuildingColors = ColorSet.fromMask(colors);
}
return deckbuildingColors;
}
}

View File

@@ -489,15 +489,6 @@ public abstract class DeckGeneratorBase {
return dLands;
}
/**
* Get all dual lands that do not match this color combo.
*
* @return dual land names
*/
protected List<String> getInverseDualLandList() {
return inverseDLands;
}
private void addCardNameToList(String cardName, List<String> cardNameList) {
if (pool.contains(cardName)) { //avoid adding card if it's not in pool
cardNameList.add(cardName);

View File

@@ -96,7 +96,7 @@ public class CardRanker {
if (card.getRules().getAiHints().getRemAIDecks()) {
score -= 20.0;
}
if( !canAddMoreColors && !card.getRules().getManaCost().canBePaidWithAvaliable(chosenColors.getColor())) {
if( !canAddMoreColors && !card.getRules().getDeckbuildingColors().hasNoColorsExcept(chosenColors)) {
score -= 50.0;
}

View File

@@ -844,25 +844,12 @@ public class CardThemedDeckBuilder extends DeckGeneratorBase {
for (final PaperCard card : lands) {
if (landsNeeded > minBasics) {
// Throw out any dual-lands for the wrong colors. Assume
// everything else is either
// (a) dual-land of the correct two colors, or
// (b) a land that generates colorless mana and has some other
// beneficial effect.
if (!card.getRules().getColorIdentity().isColorless() && card.getRules().getColorIdentity().getSharedColors(colors).countColors()==0
|| card.getRules().getColorIdentity().isMulticolor()&&colors.isMonoColor()){//remove dual lands from mono coloured decks
//skip as does not match colours
if (logToConsole) {
System.out.println("Excluding NonBasicLand: " + card.getName());
}
continue;
}
if (!inverseDLands.contains(card.getName())&&!dLands.contains(card.getName())&&MyRandom.getRandom().nextInt(100)<90) {
// Use only lands that are within our colors
if (card.getRules().getDeckbuildingColors().hasNoColorsExcept(colors)) {
landsToAdd.add(card);
landsNeeded--;
if (logToConsole) {
System.out.println("NonBasicLand[" + landsNeeded + "]:" + card.getName());
}
} else if (logToConsole) {
System.out.println("Excluding NonBasicLand: " + card.getName());
}
}
}

View File

@@ -39,7 +39,7 @@ public class DeckColors {
public void addColorsOf(final IPaperCard pickedCard) {
final ColorSet colorsCanAdd = chosen.inverse();
final ColorSet toAdd = colorsCanAdd.getSharedColors(pickedCard.getRules().getColor());
final ColorSet toAdd = colorsCanAdd.getSharedColors(pickedCard.getRules().getDeckbuildingColors());
int cntColorsAssigned = getChosenColors().countColors();
final boolean haveSpace = cntColorsAssigned < MAX_COLORS;

View File

@@ -460,18 +460,14 @@ public class LimitedDeckBuilder extends DeckGeneratorBase {
* Add non-basic lands to the deck.
*/
private void addNonBasicLands() {
final List<String> inverseDuals = getInverseDualLandList();
final Iterable<PaperCard> lands = Iterables.filter(aiPlayables,
Predicates.compose(CardRulesPredicates.Presets.IS_NONBASIC_LAND, PaperCard.FN_GET_RULES));
List<PaperCard> landsToAdd = new ArrayList<>();
for (final PaperCard card : lands) {
if (landsNeeded > 0) {
// Throw out any dual-lands for the wrong colors. Assume
// everything else is either
// (a) dual-land of the correct two colors, or
// (b) a land that generates colorless mana and has some other
// beneficial effect.
if (!inverseDuals.contains(card.getName())) {
// Use only lands that are within our colors
// TODO: Use off-color fetchlands that get an on-color dual land
if (card.getRules().getDeckbuildingColors().hasNoColorsExcept(colors)) {
landsToAdd.add(card);
landsNeeded--;
if (logToConsole) {