Incremental update to allow running a battery of AI vs AI games, with some very basic reporting.
This commit is contained in:
@@ -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 "?";
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 <Player1Type> <Player2Type> <# 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<GameResult> results = new ArrayList<GameResult>();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user