From 3f28c3c3d6ca08d066d1de77c00ac00f4e1dba6c Mon Sep 17 00:00:00 2001 From: Agetian Date: Mon, 23 Jan 2017 17:52:06 +0000 Subject: [PATCH] - Better castable material detection in ManaRitual AI, now accounts for non-permanents that the AI is willing to cast. --- .../src/main/java/forge/ai/SpecialCardAi.java | 42 ++++++++++++------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/SpecialCardAi.java b/forge-ai/src/main/java/forge/ai/SpecialCardAi.java index d4ac6a1b1a2..702e2663ef9 100644 --- a/forge-ai/src/main/java/forge/ai/SpecialCardAi.java +++ b/forge-ai/src/main/java/forge/ai/SpecialCardAi.java @@ -206,25 +206,35 @@ public class SpecialCardAi { String restrictValid = sa.hasParam("RestrictValid") ? sa.getParam("RestrictValid") : "Card"; - CardCollection castablePerms = CardLists.filter(ai.getCardsIn(ZoneType.Hand), - Predicates.and(CardPredicates.Presets.NONLAND_PERMANENTS, CardPredicates.restriction(restrictValid.split(","), ai, sa.getHostCard(), sa), + CardCollection cardList = new CardCollection(); + List all = ComputerUtilAbility.getSpellAbilities(ai.getCardsIn(ZoneType.Hand), ai); + for (final SpellAbility testSa : ComputerUtilAbility.getOriginalAndAltCostAbilities(all, ai)) { + ManaCost cost = testSa.getPayCosts().getTotalMana(); + if (cost.getCMC() == 0 && cost.countX() == 0) { + // no mana cost, no need to activate this SA then (additional mana not needed) + continue; + } + + if (testSa.getHostCard().getName().equals(sa.getHostCard().getName())) { + // prevent infinitely recursing own ability when testing AI play decision + continue; + } + + SpellAbility testSaNoCost = testSa.copyWithNoManaCost(); + testSaNoCost.setActivatingPlayer(ai); + if (((PlayerControllerAi)ai.getController()).getAi().canPlaySa(testSaNoCost) == AiPlayDecision.WillPlay) { + // the AI is willing to play the spell + if (!cardList.contains(testSa.getHostCard())) { + cardList.add(testSa.getHostCard()); + } + } + } + + CardCollection castableSpells = CardLists.filter(cardList, Predicates.and(CardPredicates.restriction(restrictValid.split(","), ai, sa.getHostCard(), sa), CardPredicates.lessCMC(searchCMC), Predicates.or(CardPredicates.isColorless(), CardPredicates.isColor(producedColor)))); - // make sure we don't try for a legendary permanent we already have - castablePerms = CardLists.filter(castablePerms, new Predicate() { - @Override - public boolean apply(final Card c) { - if (c.getType().isLegendary()) { - if (ai.isCardInPlay(c.getName())) { - return false; - } - } - return true; - } - }); - // TODO: this will probably still waste the card from time to time. Somehow improve detection of castable material. - return castablePerms.size() > 0; + return castableSpells.size() > 0; } }