From 1a76a7e81f3eaac25cf69bc2e1caf2d29a4722dd Mon Sep 17 00:00:00 2001 From: Agetian Date: Thu, 18 May 2023 16:19:14 +0300 Subject: [PATCH] AI: Evaluate creature spells when deciding between two spells with the same CMC (#3133) * - Fix the name of the swamp tribal town. * - Update deck conversion toolchain to the one that was used for the May 2023 MTGDecks.net archive update. * - Evaluate creature spells when deciding priority for two spells with the same CMC * - Evaluate the card based on its state. * - Evaluate the card based on its state, wrapper approach. --- .../src/main/java/forge/ai/AiController.java | 11 ++++++++++ .../main/java/forge/ai/ComputerUtilCard.java | 21 +++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/forge-ai/src/main/java/forge/ai/AiController.java b/forge-ai/src/main/java/forge/ai/AiController.java index bfb9f737cea..04d69d7ad41 100644 --- a/forge-ai/src/main/java/forge/ai/AiController.java +++ b/forge-ai/src/main/java/forge/ai/AiController.java @@ -1082,6 +1082,17 @@ public class AiController { } } + // If both are permanent creature spells, prefer the one that evaluates higher + if (a1 == b1 && a.getApi() == ApiType.PermanentCreature && b.getApi() == ApiType.PermanentCreature) { + int evalA = ComputerUtilCard.evaluateCreature(a); + int evalB = ComputerUtilCard.evaluateCreature(b); + if (evalA > evalB) { + a1++; + } else if (evalB > evalA) { + b1++; + } + } + a1 += getSpellAbilityPriority(a); b1 += getSpellAbilityPriority(b); diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java b/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java index a1f0ffd1fcc..464909d9148 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java @@ -582,7 +582,28 @@ public class ComputerUtilCard { public static int evaluateCreature(final Card c) { return creatureEvaluator.evaluateCreature(c); } + public static int evaluateCreature(final SpellAbility sa) { + final Card host = sa.getHostCard(); + if (sa.getApi() != ApiType.PermanentCreature) { + System.err.println("Warning: tried to evaluate a non-creature spell with evaluateCreature for card " + host + " via SA " + sa); + return 0; + } + + // switch to the needed card face + CardStateName currentState = sa.getCardState() != null && host.getCurrentStateName() != sa.getCardStateName() && !host.isInPlay() ? host.getCurrentStateName() : null; + if (currentState != null) { + host.setState(sa.getCardStateName(), false); + } + + int eval = creatureEvaluator.evaluateCreature(host); + + if (currentState != null) { + host.setState(currentState, false); + } + + return eval; + } public static int evaluateCreature(final Card c, final boolean considerPT, final boolean considerCMC) { return creatureEvaluator.evaluateCreature(c, considerPT, considerCMC); }