mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 11:18:01 +00:00
Reduce some spam in simulation AI:
- Don't evaluate mana abilities. - Produce a diff of the game eval state instead of printing out two full sets. - Cut down on some extra evaluations.
This commit is contained in:
@@ -1,6 +1,9 @@
|
|||||||
package simulation;
|
package simulation;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import forge.ai.ComputerUtil;
|
import forge.ai.ComputerUtil;
|
||||||
@@ -15,37 +18,79 @@ import forge.game.spellability.TargetChoices;
|
|||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
|
|
||||||
public class GameSimulator {
|
public class GameSimulator {
|
||||||
private Game origGame;
|
|
||||||
private GameCopier copier;
|
private GameCopier copier;
|
||||||
private Game simGame;
|
private Game simGame;
|
||||||
private Player aiPlayer;
|
private Player aiPlayer;
|
||||||
private Player opponent;
|
private Player opponent;
|
||||||
private GameStateEvaluator eval;
|
private GameStateEvaluator eval;
|
||||||
|
private ArrayList<String> origLines;
|
||||||
|
private int origScore;
|
||||||
|
|
||||||
public GameSimulator(final Game origGame) {
|
public GameSimulator(final Game origGame) {
|
||||||
this.origGame = origGame;
|
|
||||||
copier = new GameCopier(origGame);
|
copier = new GameCopier(origGame);
|
||||||
simGame = copier.makeCopy();
|
simGame = copier.makeCopy();
|
||||||
// TODO:
|
// TODO:
|
||||||
aiPlayer = simGame.getPlayers().get(1);
|
aiPlayer = simGame.getPlayers().get(1);
|
||||||
opponent = simGame.getPlayers().get(0);
|
opponent = simGame.getPlayers().get(0);
|
||||||
eval = new GameStateEvaluator();
|
eval = new GameStateEvaluator();
|
||||||
|
|
||||||
|
origLines = new ArrayList<String>();
|
||||||
|
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<String> simLines = new ArrayList<String>();
|
||||||
|
debugLines = simLines;
|
||||||
int simScore = eval.getScoreForGameState(simGame, aiPlayer, opponent);
|
int simScore = eval.getScoreForGameState(simGame, aiPlayer, opponent);
|
||||||
int origScore = getScoreForOrigGame();
|
|
||||||
debugPrint = true;
|
|
||||||
if (simScore != origScore) {
|
if (simScore != origScore) {
|
||||||
// Print debug info.
|
// Print debug info.
|
||||||
eval.getScoreForGameState(simGame, aiPlayer, opponent);
|
printDiff(origLines, simLines);
|
||||||
getScoreForOrigGame();
|
|
||||||
throw new RuntimeException("Game copy error");
|
throw new RuntimeException("Game copy error");
|
||||||
}
|
}
|
||||||
|
debugPrint = true;
|
||||||
|
debugLines = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void printDiff(List<String> lines1, List<String> 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 boolean debugPrint;
|
||||||
|
public static ArrayList<String> debugLines;
|
||||||
public static void debugPrint(String str) {
|
public static void debugPrint(String str) {
|
||||||
if (debugPrint) {
|
if (debugPrint) {
|
||||||
System.out.println(str);
|
System.out.println(str);
|
||||||
}
|
}
|
||||||
|
if (debugLines!=null) {
|
||||||
|
debugLines.add(str);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private SpellAbility findSaInSimGame(SpellAbility sa) {
|
private SpellAbility findSaInSimGame(SpellAbility sa) {
|
||||||
@@ -133,18 +178,19 @@ public class GameSimulator {
|
|||||||
// we should simulate how combat will resolve and evaluate that
|
// we should simulate how combat will resolve and evaluate that
|
||||||
// state instead!
|
// state instead!
|
||||||
debugPrint("SimGame:");
|
debugPrint("SimGame:");
|
||||||
|
ArrayList<String> simLines = new ArrayList<String>();
|
||||||
|
debugLines = simLines;
|
||||||
|
debugPrint = false;
|
||||||
int score = eval.getScoreForGameState(simGame, aiPlayer, opponent);
|
int score = eval.getScoreForGameState(simGame, aiPlayer, opponent);
|
||||||
|
debugLines = null;
|
||||||
|
debugPrint = true;
|
||||||
|
printDiff(origLines, simLines);
|
||||||
sa.setActivatingPlayer(origActivatingPlayer);
|
sa.setActivatingPlayer(origActivatingPlayer);
|
||||||
|
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getScoreForOrigGame() {
|
public int getScoreForOrigGame() {
|
||||||
// TODO: Make this logic more bulletproof.
|
return origScore;
|
||||||
Player origAiPlayer = origGame.getPlayers().get(1);
|
|
||||||
Player origOpponent = origGame.getPlayers().get(0);
|
|
||||||
return eval.getScoreForGameState(origGame, origAiPlayer, origOpponent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ public class GameStateEvaluator {
|
|||||||
score += 3 * myCards - 3 * theirCards;
|
score += 3 * myCards - 3 * theirCards;
|
||||||
for (Card c : game.getCardsIn(ZoneType.Battlefield)) {
|
for (Card c : game.getCardsIn(ZoneType.Battlefield)) {
|
||||||
int value = evalCard(c);
|
int value = evalCard(c);
|
||||||
String str = c.toString();
|
String str = c.getName();
|
||||||
if (c.isCreature()) {
|
if (c.isCreature()) {
|
||||||
str += " " + c.getNetPower() + "/" + c.getNetToughness();
|
str += " " + c.getNetPower() + "/" + c.getNetToughness();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,8 +24,7 @@ public class SpellAbilityPicker {
|
|||||||
if (!USE_SIMULATION)
|
if (!USE_SIMULATION)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
System.out.println("----\nchooseSpellAbilityToPlay game " + game.toString());
|
System.out.println("---- choose ability (phase = " + game.getPhaseHandler().getPhase() + ")");
|
||||||
System.out.println("---- (phase = " + game.getPhaseHandler().getPhase() + ")");
|
|
||||||
|
|
||||||
ArrayList<SpellAbility> candidateSAs = new ArrayList<>();
|
ArrayList<SpellAbility> candidateSAs = new ArrayList<>();
|
||||||
for (final SpellAbility sa : originalAndAltCostAbilities) {
|
for (final SpellAbility sa : originalAndAltCostAbilities) {
|
||||||
@@ -33,6 +32,9 @@ public class SpellAbilityPicker {
|
|||||||
if (skipCounter && sa.getApi() == ApiType.Counter) {
|
if (skipCounter && sa.getApi() == ApiType.Counter) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (sa.isManaAbility()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
sa.setActivatingPlayer(player);
|
sa.setActivatingPlayer(player);
|
||||||
|
|
||||||
AiPlayDecision opinion = canPlayAndPayForSim(sa);
|
AiPlayDecision opinion = canPlayAndPayForSim(sa);
|
||||||
|
|||||||
Reference in New Issue
Block a user