diff --git a/forge-ai/src/main/java/simulation/GameSimulator.java b/forge-ai/src/main/java/simulation/GameSimulator.java index 2dbd34e8d99..27e641a5f11 100644 --- a/forge-ai/src/main/java/simulation/GameSimulator.java +++ b/forge-ai/src/main/java/simulation/GameSimulator.java @@ -1,6 +1,9 @@ package simulation; +import java.util.ArrayList; +import java.util.Collections; import java.util.HashSet; +import java.util.List; import java.util.Set; import forge.ai.ComputerUtil; @@ -15,37 +18,79 @@ import forge.game.spellability.TargetChoices; import forge.game.zone.ZoneType; public class GameSimulator { - private Game origGame; private GameCopier copier; private Game simGame; private Player aiPlayer; private Player opponent; private GameStateEvaluator eval; - + private ArrayList origLines; + private int origScore; + public GameSimulator(final Game origGame) { - this.origGame = origGame; copier = new GameCopier(origGame); simGame = copier.makeCopy(); // TODO: aiPlayer = simGame.getPlayers().get(1); opponent = simGame.getPlayers().get(0); eval = new GameStateEvaluator(); + + origLines = new ArrayList(); + debugLines = origLines; + + debugPrint = false; + // TODO: Make this logic more bulletproof. + Player origAiPlayer = origGame.getPlayers().get(1); + Player origOpponent = origGame.getPlayers().get(0); + origScore = eval.getScoreForGameState(origGame, origAiPlayer, origOpponent); + + ArrayList simLines = new ArrayList(); + debugLines = simLines; int simScore = eval.getScoreForGameState(simGame, aiPlayer, opponent); - int origScore = getScoreForOrigGame(); - debugPrint = true; if (simScore != origScore) { // Print debug info. - eval.getScoreForGameState(simGame, aiPlayer, opponent); - getScoreForOrigGame(); + printDiff(origLines, simLines); throw new RuntimeException("Game copy error"); } + debugPrint = true; + debugLines = null; + } + + private void printDiff(List lines1, List lines2) { + int i = 0; + int j = 0; + Collections.sort(lines1); + Collections.sort(lines2); + while (i < lines1.size() && j < lines2.size()) { + String left = lines1.get(i); + String right = lines2.get(j); + int cmp = left.compareTo(right); + if (cmp == 0) { + i++; j++; + } else if (cmp < 0) { + System.out.println("-" + left); + i++; + } else { + System.out.println("+" + right); + j++; + } + } + while (i < lines1.size()) { + System.out.println("-" + lines1.get(i++)); + } + while (j < lines2.size()) { + System.out.println("+" + lines2.get(j++)); + } } public static boolean debugPrint; + public static ArrayList debugLines; public static void debugPrint(String str) { if (debugPrint) { System.out.println(str); } + if (debugLines!=null) { + debugLines.add(str); + } } private SpellAbility findSaInSimGame(SpellAbility sa) { @@ -133,18 +178,19 @@ public class GameSimulator { // we should simulate how combat will resolve and evaluate that // state instead! debugPrint("SimGame:"); + ArrayList simLines = new ArrayList(); + debugLines = simLines; + debugPrint = false; int score = eval.getScoreForGameState(simGame, aiPlayer, opponent); - + debugLines = null; + debugPrint = true; + printDiff(origLines, simLines); sa.setActivatingPlayer(origActivatingPlayer); return score; } public int getScoreForOrigGame() { - // TODO: Make this logic more bulletproof. - Player origAiPlayer = origGame.getPlayers().get(1); - Player origOpponent = origGame.getPlayers().get(0); - return eval.getScoreForGameState(origGame, origAiPlayer, origOpponent); + return origScore; } - } diff --git a/forge-ai/src/main/java/simulation/GameStateEvaluator.java b/forge-ai/src/main/java/simulation/GameStateEvaluator.java index cc9fae93a57..972f033eaa4 100644 --- a/forge-ai/src/main/java/simulation/GameStateEvaluator.java +++ b/forge-ai/src/main/java/simulation/GameStateEvaluator.java @@ -28,7 +28,7 @@ public class GameStateEvaluator { score += 3 * myCards - 3 * theirCards; for (Card c : game.getCardsIn(ZoneType.Battlefield)) { int value = evalCard(c); - String str = c.toString(); + String str = c.getName(); if (c.isCreature()) { str += " " + c.getNetPower() + "/" + c.getNetToughness(); } diff --git a/forge-ai/src/main/java/simulation/SpellAbilityPicker.java b/forge-ai/src/main/java/simulation/SpellAbilityPicker.java index 77ba1e59509..1dec0845a9f 100644 --- a/forge-ai/src/main/java/simulation/SpellAbilityPicker.java +++ b/forge-ai/src/main/java/simulation/SpellAbilityPicker.java @@ -24,8 +24,7 @@ public class SpellAbilityPicker { if (!USE_SIMULATION) return null; - System.out.println("----\nchooseSpellAbilityToPlay game " + game.toString()); - System.out.println("---- (phase = " + game.getPhaseHandler().getPhase() + ")"); + System.out.println("---- choose ability (phase = " + game.getPhaseHandler().getPhase() + ")"); ArrayList candidateSAs = new ArrayList<>(); for (final SpellAbility sa : originalAndAltCostAbilities) { @@ -33,6 +32,9 @@ public class SpellAbilityPicker { if (skipCounter && sa.getApi() == ApiType.Counter) { continue; } + if (sa.isManaAbility()) { + continue; + } sa.setActivatingPlayer(player); AiPlayDecision opinion = canPlayAndPayForSim(sa);