From 33f50fb85194379d33afd382b1d4a4f7f6c4f8e0 Mon Sep 17 00:00:00 2001 From: Woody Folsom Date: Tue, 30 Oct 2012 15:41:57 -0400 Subject: [PATCH] Incremental update to allow running a battery of AI vs AI games, with some very basic reporting. --- src/net/woodyfolsom/msproj/GameResult.java | 4 +- src/net/woodyfolsom/msproj/Referee.java | 19 +++--- .../woodyfolsom/msproj/StandAloneGame.java | 59 ++++++++++++++++--- 3 files changed, 65 insertions(+), 17 deletions(-) diff --git a/src/net/woodyfolsom/msproj/GameResult.java b/src/net/woodyfolsom/msproj/GameResult.java index 64506d5..3bbeb28 100644 --- a/src/net/woodyfolsom/msproj/GameResult.java +++ b/src/net/woodyfolsom/msproj/GameResult.java @@ -3,6 +3,7 @@ package net.woodyfolsom.msproj; public class GameResult { public static final GameResult BLACK_BY_RESIGNATION = new GameResult(RESULT_TYPE.BLACK_BY_RESIGNATION); + public static final GameResult VOID = new GameResult(RESULT_TYPE.VOID); public static final GameResult WHITE_BY_RESIGNATION = new GameResult(RESULT_TYPE.WHITE_BY_RESIGNATION); private double komi; @@ -10,7 +11,7 @@ public class GameResult { private int whiteScore; private int normalizedZeroScore; - public enum RESULT_TYPE { BLACK_BY_RESIGNATION, WHITE_BY_RESIGNATION, IN_PROGRESS, SCORED} + public enum RESULT_TYPE { BLACK_BY_RESIGNATION, WHITE_BY_RESIGNATION, IN_PROGRESS, SCORED, VOID} private RESULT_TYPE resultType; @@ -92,6 +93,7 @@ public class GameResult { case WHITE_BY_RESIGNATION : return "W+R"; case IN_PROGRESS : + case VOID : // intentional fall-through return "Void"; default : return "?"; diff --git a/src/net/woodyfolsom/msproj/Referee.java b/src/net/woodyfolsom/msproj/Referee.java index 90369f1..e94490f 100644 --- a/src/net/woodyfolsom/msproj/Referee.java +++ b/src/net/woodyfolsom/msproj/Referee.java @@ -10,11 +10,9 @@ import java.util.Date; import net.woodyfolsom.msproj.policy.Policy; public class Referee { - private GameConfig gameConfig = new GameConfig(9); - private GameState gameState = new GameState(gameConfig); private Policy blackPolicy; private Policy whitePolicy; - + public Policy getPolicy(Player player) { if (Player.BLACK.equals(player)) { return blackPolicy; @@ -37,11 +35,11 @@ public class Referee { } } - public void play() { + public GameResult play(GameConfig gameConfig) { + GameState gameState = new GameState(gameConfig); + System.out.println("Game started."); - // Player currentPlayer = Player.BLACK; - try { while (!gameState.isTerminal()) { System.out.println(gameState); @@ -55,9 +53,12 @@ public class Referee { System.out .println("Game halted early due to the following Exception:"); ex.printStackTrace(); - return; + return GameResult.VOID; } - System.out.println("Game over. Result: " + gameState.getResult()); + + GameResult result = gameState.getResult(); + + System.out.println("Game over. Result: " + result); DateFormat dateFormat = new SimpleDateFormat("yyMMddHHmmssZ"); @@ -83,5 +84,7 @@ public class Referee { } System.out.println("Game finished."); + + return result; } } diff --git a/src/net/woodyfolsom/msproj/StandAloneGame.java b/src/net/woodyfolsom/msproj/StandAloneGame.java index d94f531..ea7d740 100644 --- a/src/net/woodyfolsom/msproj/StandAloneGame.java +++ b/src/net/woodyfolsom/msproj/StandAloneGame.java @@ -1,24 +1,67 @@ package net.woodyfolsom.msproj; +import java.util.ArrayList; +import java.util.List; + import net.woodyfolsom.msproj.policy.HumanKeyboardInput; import net.woodyfolsom.msproj.policy.MonteCarloUCT; import net.woodyfolsom.msproj.policy.Policy; import net.woodyfolsom.msproj.policy.RandomMovePolicy; public class StandAloneGame { - - /** - * @param args - */ + enum PLAYER_TYPE { HUMAN, UCT_FAST, UCT_SLOW }; + public static void main(String[] args) { - Policy player1 = new HumanKeyboardInput(); - Policy player2 = new MonteCarloUCT(new RandomMovePolicy(), 10000L); + if (args.length != 3) { + System.out.println("Incorrect # of arguments: use StandAloneGame <# rounds>"); + System.out.println("For example to play 10 games against MC UCT w/ slow moves: StandAloneGame UCT_SLOW HUMAN 10"); + } + new StandAloneGame().playGame(parsePlayerType(args[0]), parsePlayerType(args[1]), Integer.valueOf(args[2])); + } + + private static PLAYER_TYPE parsePlayerType(String playerTypeStr) { + if ("UCT_FAST".equalsIgnoreCase(playerTypeStr)) { + return PLAYER_TYPE.UCT_FAST; + } else if ("UCT_SLOW".equalsIgnoreCase(playerTypeStr) || "UCT".equalsIgnoreCase(playerTypeStr)) { + return PLAYER_TYPE.UCT_SLOW; + } else if ("HUMAN".equalsIgnoreCase(playerTypeStr)) { + return PLAYER_TYPE.HUMAN; + } else { + throw new RuntimeException("Unknown player type: " + playerTypeStr); + } + } + + public void playGame(PLAYER_TYPE playerType1, PLAYER_TYPE playerType2, int rounds) { + + Policy player1 = getPolicy(playerType1); + Policy player2 = getPolicy(playerType2); Referee referee = new Referee(); referee.setPolicy(Player.BLACK, player1); referee.setPolicy(Player.WHITE, player2); - referee.play(); + List results = new ArrayList(); + GameConfig gameConfig = new GameConfig(5); + for (int round = 0; round < rounds; ) { + results.add(referee.play(gameConfig)); + } + + System.out.println("Cumulative results for 10 games (BLACK=" + playerType1 + ", WHITE=" + playerType2 + ")"); + for (int i = 0; i < rounds; i ++) { + System.out.println(i +". " + results.get(i)); + } + } + + private Policy getPolicy(PLAYER_TYPE playerType) { + switch (playerType) { + case HUMAN : + return new HumanKeyboardInput(); + case UCT_SLOW : + return new MonteCarloUCT(new RandomMovePolicy(), 3000L); + case UCT_FAST : + return new MonteCarloUCT(new RandomMovePolicy(), 1000L); + default : + throw new IllegalArgumentException("Invalid PLAYER_TYPE: " + playerType); + } } - }