From ab287858b38e3c3a0e67532f21593b68fb946993 Mon Sep 17 00:00:00 2001 From: Adam Pantel <> Date: Thu, 8 Apr 2021 15:51:55 -0400 Subject: [PATCH] Improve land handling --- .../src/main/java/forge/card/CardRules.java | 27 ++++++++++++++++++- .../deck/generation/DeckGeneratorBase.java | 9 ------- .../forge/gamemodes/limited/CardRanker.java | 2 +- .../limited/CardThemedDeckBuilder.java | 21 +++------------ .../forge/gamemodes/limited/DeckColors.java | 2 +- .../gamemodes/limited/LimitedDeckBuilder.java | 10 +++---- 6 files changed, 35 insertions(+), 36 deletions(-) diff --git a/forge-core/src/main/java/forge/card/CardRules.java b/forge-core/src/main/java/forge/card/CardRules.java index 5b5f77c33d6..4e80fe8bc1a 100644 --- a/forge-core/src/main/java/forge/card/CardRules.java +++ b/forge-core/src/main/java/forge/card/CardRules.java @@ -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; + } } diff --git a/forge-core/src/main/java/forge/deck/generation/DeckGeneratorBase.java b/forge-core/src/main/java/forge/deck/generation/DeckGeneratorBase.java index b5caab29cd6..a326b3c9a3b 100644 --- a/forge-core/src/main/java/forge/deck/generation/DeckGeneratorBase.java +++ b/forge-core/src/main/java/forge/deck/generation/DeckGeneratorBase.java @@ -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 getInverseDualLandList() { - return inverseDLands; - } - private void addCardNameToList(String cardName, List cardNameList) { if (pool.contains(cardName)) { //avoid adding card if it's not in pool cardNameList.add(cardName); diff --git a/forge-gui/src/main/java/forge/gamemodes/limited/CardRanker.java b/forge-gui/src/main/java/forge/gamemodes/limited/CardRanker.java index d53918b1dee..052efb0d311 100644 --- a/forge-gui/src/main/java/forge/gamemodes/limited/CardRanker.java +++ b/forge-gui/src/main/java/forge/gamemodes/limited/CardRanker.java @@ -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; } diff --git a/forge-gui/src/main/java/forge/gamemodes/limited/CardThemedDeckBuilder.java b/forge-gui/src/main/java/forge/gamemodes/limited/CardThemedDeckBuilder.java index eeb3f194b94..f5f31c87892 100644 --- a/forge-gui/src/main/java/forge/gamemodes/limited/CardThemedDeckBuilder.java +++ b/forge-gui/src/main/java/forge/gamemodes/limited/CardThemedDeckBuilder.java @@ -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()); } } } diff --git a/forge-gui/src/main/java/forge/gamemodes/limited/DeckColors.java b/forge-gui/src/main/java/forge/gamemodes/limited/DeckColors.java index 86f641093a1..d831b1ee7e9 100644 --- a/forge-gui/src/main/java/forge/gamemodes/limited/DeckColors.java +++ b/forge-gui/src/main/java/forge/gamemodes/limited/DeckColors.java @@ -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; diff --git a/forge-gui/src/main/java/forge/gamemodes/limited/LimitedDeckBuilder.java b/forge-gui/src/main/java/forge/gamemodes/limited/LimitedDeckBuilder.java index dcf291b248c..7fbc1ff36f9 100644 --- a/forge-gui/src/main/java/forge/gamemodes/limited/LimitedDeckBuilder.java +++ b/forge-gui/src/main/java/forge/gamemodes/limited/LimitedDeckBuilder.java @@ -460,18 +460,14 @@ public class LimitedDeckBuilder extends DeckGeneratorBase { * Add non-basic lands to the deck. */ private void addNonBasicLands() { - final List inverseDuals = getInverseDualLandList(); final Iterable lands = Iterables.filter(aiPlayables, Predicates.compose(CardRulesPredicates.Presets.IS_NONBASIC_LAND, PaperCard.FN_GET_RULES)); List 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) {