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:
Myrd
2015-01-29 03:35:24 +00:00
parent 4e7565dd2a
commit e332b383e9
3 changed files with 64 additions and 16 deletions

View File

@@ -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<String> 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<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 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<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 ArrayList<String> 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<String> simLines = new ArrayList<String>();
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;
}
}

View File

@@ -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();
}

View File

@@ -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<SpellAbility> 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);