Refactor logic for continuing simulation to SimulationController class.

This commit is contained in:
Myrd
2015-03-08 17:13:43 +00:00
parent aed4b5cdfa
commit 219eae0a00
6 changed files with 78 additions and 49 deletions

View File

@@ -1173,7 +1173,7 @@ public class AiController {
return null;
if (useSimulation) {
return simPicker.chooseSpellAbilityToPlay(all, skipCounter);
return simPicker.chooseSpellAbilityToPlay(null, all, skipCounter);
}
Collections.sort(all, saComparator); // put best spells first

View File

@@ -21,18 +21,17 @@ import forge.game.spellability.TargetChoices;
import forge.game.spellability.TargetRestrictions;
public class GameSimulator {
private static int MAX_DEPTH = 5;
public static boolean COPY_STACK = false;
final private SimulationController controller;
private GameCopier copier;
private Game simGame;
private Player aiPlayer;
private GameStateEvaluator eval;
private int recursionDepth;
private ArrayList<String> origLines;
private Score origScore;
public GameSimulator(final Game origGame, final Player origAiPlayer) {
public GameSimulator(final SimulationController controller, final Game origGame, final Player origAiPlayer) {
this.controller = controller;
copier = new GameCopier(origGame);
simGame = copier.makeCopy();
@@ -76,10 +75,6 @@ public class GameSimulator {
debugLines = null;
}
public void setRecursionDepth(int depth) {
this.recursionDepth = depth;
}
private void printDiff(List<String> lines1, List<String> lines2) {
int i = 0;
int j = 0;
@@ -191,21 +186,17 @@ public class GameSimulator {
debugPrint = true;
printDiff(origLines, simLines);
}
for (int i = 0; i < recursionDepth; i++)
System.err.print(" ");
System.err.println(recursionDepth + ": [" + score.value + "] " + SpellAbilityPicker.abilityToString(origSa));
if (recursionDepth < MAX_DEPTH && !simGame.isGameOver()) {
debugPrint("Recursing DEPTH=" + recursionDepth);
debugPrint(" With: " + sa);
controller.printState(score, origSa);
if (controller.shouldRecurse() && !simGame.isGameOver()) {
controller.push(sa);
SpellAbilityPicker sim = new SpellAbilityPicker(simGame, aiPlayer);
sim.setRecursionDepth(recursionDepth + 1);
CardCollection cards = ComputerUtilAbility.getAvailableCards(simGame, aiPlayer);
ArrayList<SpellAbility> all = ComputerUtilAbility.getSpellAbilities(cards, aiPlayer);
SpellAbility nextSa = sim.chooseSpellAbilityToPlay(all, true);
SpellAbility nextSa = sim.chooseSpellAbilityToPlay(controller, all, true);
if (nextSa != null) {
score = sim.getScoreForChosenAbility();
}
debugPrint("DEPTH"+recursionDepth+" best score " + score + " " + nextSa);
controller.pop(score, nextSa);
}
return score;

View File

@@ -0,0 +1,34 @@
package forge.ai.simulation;
import forge.ai.simulation.GameStateEvaluator.Score;
import forge.game.spellability.SpellAbility;
public class SimulationController {
private static int MAX_DEPTH = 5;
private int recursionDepth;
public SimulationController() {
}
public boolean shouldRecurse() {
return recursionDepth < MAX_DEPTH;
}
public void push(SpellAbility sa) {
GameSimulator.debugPrint("Recursing DEPTH=" + recursionDepth);
GameSimulator.debugPrint(" With: " + sa);
recursionDepth++;
}
public void pop(Score score, SpellAbility nextSa) {
recursionDepth--;
GameSimulator.debugPrint("DEPTH"+recursionDepth+" best score " + score + " " + nextSa);
}
public void printState(Score score, SpellAbility origSa) {
for (int i = 0; i < recursionDepth; i++)
System.err.print(" ");
System.err.println(recursionDepth + ": [" + score.value + "] " + SpellAbilityPicker.abilityToString(origSa));
}
}

View File

@@ -18,27 +18,28 @@ import forge.game.spellability.TargetChoices;
public class SpellAbilityPicker {
private Game game;
private Player player;
private int recursionDepth;
private Score bestScore;
private boolean printOutput;
public SpellAbilityPicker(Game game, Player player) {
this.game = game;
this.player = player;
}
public void setRecursionDepth(int depth) {
recursionDepth = depth;
}
private void print(String str) {
if (recursionDepth == 0) {
if (printOutput) {
System.out.println(str);
}
}
public SpellAbility chooseSpellAbilityToPlay(final ArrayList<SpellAbility> all, boolean skipCounter) {
public SpellAbility chooseSpellAbilityToPlay(SimulationController controller, final ArrayList<SpellAbility> all, boolean skipCounter) {
printOutput = false;
if (controller == null) {
controller = new SimulationController();
printOutput = true;
}
print("---- choose ability (phase = " + game.getPhaseHandler().getPhase() + ")");
ArrayList<SpellAbility> candidateSAs = new ArrayList<>();
for (final SpellAbility sa : ComputerUtilAbility.getOriginalAndAltCostAbilities(all, player)) {
// Don't add Counterspells to the "normal" playcard lookups
@@ -64,13 +65,13 @@ public class SpellAbilityPicker {
}
SpellAbility bestSa = null;
print("Evaluating...");
GameSimulator simulator = new GameSimulator(game, player);
GameSimulator simulator = new GameSimulator(controller, game, player);
// FIXME: This is wasteful, we should re-use the same simulator...
Score origGameScore = simulator.getScoreForOrigGame();
Score bestSaValue = origGameScore;
for (final SpellAbility sa : candidateSAs) {
print(abilityToString(sa));;
Score value = evaluateSa(sa);
Score value = evaluateSa(controller, sa);
if (value.value > bestSaValue.value) {
bestSaValue = value;
bestSa = sa;
@@ -148,11 +149,10 @@ public class SpellAbilityPicker {
return AiPlayDecision.WillPlay;
}
private Score evaluateSa(SpellAbility sa) {
private Score evaluateSa(SimulationController controller, SpellAbility sa) {
GameSimulator.debugPrint("Evaluate SA: " + sa);
if (!sa.usesTargeting()) {
GameSimulator simulator = new GameSimulator(game, player);
simulator.setRecursionDepth(recursionDepth);
GameSimulator simulator = new GameSimulator(controller, game, player);
return simulator.simulateSpellAbility(sa);
}
GameSimulator.debugPrint("Checking out targets");
@@ -161,8 +161,7 @@ public class SpellAbilityPicker {
TargetChoices tgt = null;
while (selector.selectNextTargets()) {
GameSimulator.debugPrint("Trying targets: " + sa.getTargets().getTargetedString());
GameSimulator simulator = new GameSimulator(game, player);
simulator.setRecursionDepth(recursionDepth);
GameSimulator simulator = new GameSimulator(controller, game, player);
Score score = simulator.simulateSpellAbility(sa);
if (score.value > bestScore.value) {
bestScore = score;