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 class GameResult {
|
||||||
public static final GameResult BLACK_BY_RESIGNATION = new GameResult(RESULT_TYPE.BLACK_BY_RESIGNATION);
|
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);
|
public static final GameResult WHITE_BY_RESIGNATION = new GameResult(RESULT_TYPE.WHITE_BY_RESIGNATION);
|
||||||
|
|
||||||
private double komi;
|
private double komi;
|
||||||
@@ -10,7 +11,7 @@ public class GameResult {
|
|||||||
private int whiteScore;
|
private int whiteScore;
|
||||||
private int normalizedZeroScore;
|
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;
|
private RESULT_TYPE resultType;
|
||||||
|
|
||||||
@@ -92,6 +93,7 @@ public class GameResult {
|
|||||||
case WHITE_BY_RESIGNATION :
|
case WHITE_BY_RESIGNATION :
|
||||||
return "W+R";
|
return "W+R";
|
||||||
case IN_PROGRESS :
|
case IN_PROGRESS :
|
||||||
|
case VOID : // intentional fall-through
|
||||||
return "Void";
|
return "Void";
|
||||||
default :
|
default :
|
||||||
return "?";
|
return "?";
|
||||||
|
|||||||
@@ -10,8 +10,6 @@ import java.util.Date;
|
|||||||
import net.woodyfolsom.msproj.policy.Policy;
|
import net.woodyfolsom.msproj.policy.Policy;
|
||||||
|
|
||||||
public class Referee {
|
public class Referee {
|
||||||
private GameConfig gameConfig = new GameConfig(9);
|
|
||||||
private GameState gameState = new GameState(gameConfig);
|
|
||||||
private Policy blackPolicy;
|
private Policy blackPolicy;
|
||||||
private Policy whitePolicy;
|
private Policy whitePolicy;
|
||||||
|
|
||||||
@@ -37,10 +35,10 @@ public class Referee {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void play() {
|
public GameResult play(GameConfig gameConfig) {
|
||||||
System.out.println("Game started.");
|
GameState gameState = new GameState(gameConfig);
|
||||||
|
|
||||||
// Player currentPlayer = Player.BLACK;
|
System.out.println("Game started.");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
while (!gameState.isTerminal()) {
|
while (!gameState.isTerminal()) {
|
||||||
@@ -55,9 +53,12 @@ public class Referee {
|
|||||||
System.out
|
System.out
|
||||||
.println("Game halted early due to the following Exception:");
|
.println("Game halted early due to the following Exception:");
|
||||||
ex.printStackTrace();
|
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");
|
DateFormat dateFormat = new SimpleDateFormat("yyMMddHHmmssZ");
|
||||||
|
|
||||||
@@ -83,5 +84,7 @@ public class Referee {
|
|||||||
}
|
}
|
||||||
|
|
||||||
System.out.println("Game finished.");
|
System.out.println("Game finished.");
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +1,67 @@
|
|||||||
package net.woodyfolsom.msproj;
|
package net.woodyfolsom.msproj;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import net.woodyfolsom.msproj.policy.HumanKeyboardInput;
|
import net.woodyfolsom.msproj.policy.HumanKeyboardInput;
|
||||||
import net.woodyfolsom.msproj.policy.MonteCarloUCT;
|
import net.woodyfolsom.msproj.policy.MonteCarloUCT;
|
||||||
import net.woodyfolsom.msproj.policy.Policy;
|
import net.woodyfolsom.msproj.policy.Policy;
|
||||||
import net.woodyfolsom.msproj.policy.RandomMovePolicy;
|
import net.woodyfolsom.msproj.policy.RandomMovePolicy;
|
||||||
|
|
||||||
public class StandAloneGame {
|
public class StandAloneGame {
|
||||||
|
enum PLAYER_TYPE { HUMAN, UCT_FAST, UCT_SLOW };
|
||||||
|
|
||||||
/**
|
|
||||||
* @param args
|
|
||||||
*/
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
Policy player1 = new HumanKeyboardInput();
|
if (args.length != 3) {
|
||||||
Policy player2 = new MonteCarloUCT(new RandomMovePolicy(), 10000L);
|
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 referee = new Referee();
|
||||||
referee.setPolicy(Player.BLACK, player1);
|
referee.setPolicy(Player.BLACK, player1);
|
||||||
referee.setPolicy(Player.WHITE, player2);
|
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