In process of moving GameConfig into GameState (and making it an immutable singleton for the lifetime of the game).

Still does not understand when or how to resign, or how to play the oppoent's PASS.
This commit is contained in:
2012-09-26 07:50:20 -04:00
parent d6068c841a
commit f8f8214300
19 changed files with 171 additions and 73 deletions

View File

@@ -2,17 +2,34 @@ package net.woodyfolsom.msproj;
public class GameConfig { public class GameConfig {
private double komi; private double komi;
private int size;
private int timeLimit; private int timeLimit;
public GameConfig() { public GameConfig(int size) {
timeLimit = 0; timeLimit = 0;
komi = 0; this.size = size;
switch(size) {
case 9 :
komi = 6.5;
default :
komi = 5.5;
}
}
public GameConfig(GameConfig that) {
this.komi = that.komi;
this.size = that.size;
this.timeLimit = that.timeLimit;
} }
public double getKomi() { public double getKomi() {
return komi; return komi;
} }
public int getSize() {
return size;
}
public int getTimeLimit(){ public int getTimeLimit(){
return timeLimit; return timeLimit;
} }
@@ -21,6 +38,10 @@ public class GameConfig {
this.komi = komi; this.komi = komi;
} }
public void setSize(int size) {
this.size = size;
}
public void setTimeLimit(int timeLimit) { public void setTimeLimit(int timeLimit) {
this.timeLimit = timeLimit; this.timeLimit = timeLimit;
} }

View File

@@ -2,22 +2,28 @@ package net.woodyfolsom.msproj;
public class GameScore { public class GameScore {
public static final int NORMALIZED_ZERO_SCORE = 379;
private double komi; private double komi;
private int blackScore; private int blackScore;
private int whiteScore; private int whiteScore;
private int normalizedZeroScore;
public GameScore(int blackScore, int whiteScore, double komi) { public GameScore(int size) {
}
public GameScore(int blackScore, int whiteScore, int size, double komi) {
this.blackScore = blackScore; this.blackScore = blackScore;
this.komi = komi; this.komi = komi;
this.whiteScore = whiteScore; this.whiteScore = whiteScore;
this.normalizedZeroScore = size * size + ((int)(komi * 2));
} }
public double getBlackScore() { public double getBlackScore() {
return (double)blackScore - komi; return (double)blackScore - komi;
} }
public int getNormalizedZeroScore() {
return normalizedZeroScore;
}
/** /**
* Gets a representation for the game score as an integer. Lower numbers are better for white. * Gets a representation for the game score as an integer. Lower numbers are better for white.
* The minimum value is 0 (Chinese scoring - white owns every intersection on 19x19 and has 9 stone komi). * The minimum value is 0 (Chinese scoring - white owns every intersection on 19x19 and has 9 stone komi).
@@ -25,7 +31,7 @@ public class GameScore {
* @return * @return
*/ */
public int getAggregateScore() { public int getAggregateScore() {
return NORMALIZED_ZERO_SCORE + 2 * blackScore - ((int)(2 * (whiteScore + komi))); return normalizedZeroScore + 2 * blackScore - ((int)(2 * (whiteScore + komi)));
} }
public double getScore(Player color) { public double getScore(Player color) {
@@ -43,10 +49,19 @@ public class GameScore {
} }
public boolean isWinner(Player player) { public boolean isWinner(Player player) {
double blackScore = getBlackScore();
double whiteScore = getWhiteScore();
/* This should work but is currently bugged
if (Player.WHITE == player) { if (Player.WHITE == player) {
return getWhiteScore() < NORMALIZED_ZERO_SCORE; return getWhiteScore() < normalizedZeroScore;
} else { } else {
return getBlackScore() > NORMALIZED_ZERO_SCORE; return getBlackScore() > normalizedZeroScore;
}*/
if (Player.WHITE == player) {
return whiteScore > blackScore;
} else {
return blackScore > whiteScore;
} }
} }

View File

@@ -7,10 +7,13 @@ public class GameState {
private int blackPrisoners = 0; private int blackPrisoners = 0;
private int whitePrisoners = 0; private int whitePrisoners = 0;
private GameBoard gameBoard; private GameBoard gameBoard;
private GameConfig gameConfig;
private Player playerToMove; private Player playerToMove;
private List<Action> moveHistory = new ArrayList<Action>(); private List<Action> moveHistory = new ArrayList<Action>();
public GameState(int size) { public GameState(GameConfig gameConfig) {
this.gameConfig = gameConfig;
int size = gameConfig.getSize();
if (size < 1 || size > 19) { if (size < 1 || size > 19) {
throw new IllegalArgumentException("Invalid board size: " + size); throw new IllegalArgumentException("Invalid board size: " + size);
} }
@@ -24,6 +27,7 @@ public class GameState {
this.playerToMove = that.playerToMove; this.playerToMove = that.playerToMove;
gameBoard = new GameBoard(that.gameBoard); gameBoard = new GameBoard(that.gameBoard);
moveHistory = new ArrayList<Action>(that.moveHistory); moveHistory = new ArrayList<Action>(that.moveHistory);
this.gameConfig = new GameConfig(that.gameConfig);
} }
public void clearBoard() { public void clearBoard() {
@@ -55,6 +59,10 @@ public class GameState {
return gameBoard; return gameBoard;
} }
public GameConfig getGameConfig() {
return gameConfig;
}
public Player getPlayerToMove() { public Player getPlayerToMove() {
return playerToMove; return playerToMove;
} }

View File

@@ -30,8 +30,8 @@ public class GoGame implements Runnable {
.getName()); .getName());
private boolean shutDown = false; private boolean shutDown = false;
private GameConfig gameConfig = new GameConfig(); private GameConfig gameConfig = new GameConfig(9);
private GameState gameState = new GameState(9); private GameState gameState = new GameState(gameConfig);
private GtpClient client = null; private GtpClient client = null;
private Policy moveGenerator; private Policy moveGenerator;
private Properties properties; private Properties properties;
@@ -80,7 +80,7 @@ public class GoGame implements Runnable {
public static void main(String[] args) throws IOException { public static void main(String[] args) throws IOException {
configureLogging(); configureLogging();
if (args.length == 0) { if (args.length == 0) {
Policy defaultMoveGenerator = new MonteCarloUCT(new RandomMovePolicy(), 5000L); Policy defaultMoveGenerator = new MonteCarloUCT(new RandomMovePolicy(), 2000L);
LOGGER.info("No MoveGenerator specified. Using default: " + defaultMoveGenerator.toString()); LOGGER.info("No MoveGenerator specified. Using default: " + defaultMoveGenerator.toString());
GoGame goGame = new GoGame(defaultMoveGenerator, PROPS_FILE); GoGame goGame = new GoGame(defaultMoveGenerator, PROPS_FILE);
@@ -111,7 +111,7 @@ public class GoGame implements Runnable {
} else if ("alphabeta".equals(policyName)) { } else if ("alphabeta".equals(policyName)) {
return new AlphaBeta(); return new AlphaBeta();
} else if ("montecarlo".equals(policyName)) { } else if ("montecarlo".equals(policyName)) {
return new MonteCarloUCT(new RandomMovePolicy(), 3000L); return new MonteCarloUCT(new RandomMovePolicy(), 10000L);
} else { } else {
LOGGER.info("Unable to create Policy for unsupported name: " + policyName); LOGGER.info("Unable to create Policy for unsupported name: " + policyName);
System.exit(INVALID_MOVE_GENERATOR); System.exit(INVALID_MOVE_GENERATOR);
@@ -127,7 +127,8 @@ public class GoGame implements Runnable {
localOutput.println("? Invalid command: " + cmd.getText() + "\n"); localOutput.println("? Invalid command: " + cmd.getText() + "\n");
break; break;
case boardsize: case boardsize:
gameState = new GameState(cmd.getIntField(1)); gameConfig = new GameConfig(cmd.getIntField(1));
gameState = new GameState(gameConfig);
localOutput.println("=\n"); localOutput.println("=\n");
break; break;
case clear_board: case clear_board:

View File

@@ -22,6 +22,6 @@ public class StateEvaluator {
//TODO include komi from gameConfig //TODO include komi from gameConfig
return new GameScore(gameBoard.countSymbols(GameBoard.BLACK_STONE,GameBoard.BLACK_TERRITORY), return new GameScore(gameBoard.countSymbols(GameBoard.BLACK_STONE,GameBoard.BLACK_TERRITORY),
gameBoard.countSymbols(GameBoard.WHITE_STONE,GameBoard.WHITE_TERRITORY),gameConfig.getKomi()); gameBoard.countSymbols(GameBoard.WHITE_STONE,GameBoard.WHITE_TERRITORY),gameState.getGameBoard().getSize(),gameConfig.getKomi());
} }
} }

View File

@@ -6,7 +6,6 @@ import java.util.List;
import net.woodyfolsom.msproj.Action; import net.woodyfolsom.msproj.Action;
import net.woodyfolsom.msproj.GameConfig; import net.woodyfolsom.msproj.GameConfig;
import net.woodyfolsom.msproj.GameState; import net.woodyfolsom.msproj.GameState;
import net.woodyfolsom.msproj.GoGame;
import net.woodyfolsom.msproj.Player; import net.woodyfolsom.msproj.Player;
import net.woodyfolsom.msproj.StateEvaluator; import net.woodyfolsom.msproj.StateEvaluator;
import net.woodyfolsom.msproj.tree.GameTreeNode; import net.woodyfolsom.msproj.tree.GameTreeNode;

View File

@@ -7,6 +7,7 @@ import java.util.Set;
import net.woodyfolsom.msproj.Action; import net.woodyfolsom.msproj.Action;
import net.woodyfolsom.msproj.GameConfig; import net.woodyfolsom.msproj.GameConfig;
import net.woodyfolsom.msproj.GameScore;
import net.woodyfolsom.msproj.GameState; import net.woodyfolsom.msproj.GameState;
import net.woodyfolsom.msproj.GoGame; import net.woodyfolsom.msproj.GoGame;
import net.woodyfolsom.msproj.Player; import net.woodyfolsom.msproj.Player;
@@ -30,8 +31,14 @@ public class MonteCarloUCT extends MonteCarlo {
//From Kocsis and Szepesvari, the value of an actual terminal node is 0, so it will never be grown. //From Kocsis and Szepesvari, the value of an actual terminal node is 0, so it will never be grown.
double nodeVisits = node.getProperties().getVisits(); double nodeVisits = node.getProperties().getVisits();
Set<Action> actionsExplored = node.getActions();
GameState gameState = node.getGameState();
for (Action action : node.getActions()) { Action randomNewChildAction = new RandomMovePolicy().getAction(node.getGameState().getGameConfig(), gameState, actionsExplored, gameState.getPlayerToMove());
//only descend to the best child if no new actions are available at this node
if (randomNewChildAction == Action.NONE) {
for (Action action : actionsExplored) {
GameTreeNode<MonteCarloProperties> childNode = node.getChild(action); GameTreeNode<MonteCarloProperties> childNode = node.getChild(action);
double childScore; double childScore;
@@ -39,7 +46,7 @@ public class MonteCarloUCT extends MonteCarlo {
childScore = 0.0; childScore = 0.0;
} else { } else {
MonteCarloProperties properties = childNode.getProperties(); MonteCarloProperties properties = childNode.getProperties();
childScore = (double) (properties.getWins() / properties.getVisits()) + (2 * TUNING_CONSTANT * Math.sqrt(2 * Math.log(nodeVisits) / childNode.getProperties().getVisits())); childScore = (double) (properties.getWins() / properties.getVisits()) + (TUNING_CONSTANT * Math.sqrt(Math.log(nodeVisits) / childNode.getProperties().getVisits()));
} }
//TODO add random tie breaker? //TODO add random tie breaker?
//otherwise the child that is selected first will be biased //otherwise the child that is selected first will be biased
@@ -48,6 +55,7 @@ public class MonteCarloUCT extends MonteCarlo {
bestNode = childNode; bestNode = childNode;
} }
} }
}
if (bestNode == node) { if (bestNode == node) {
List<GameTreeNode<MonteCarloProperties>> bestNodeList = new ArrayList<GameTreeNode<MonteCarloProperties>>(); List<GameTreeNode<MonteCarloProperties>> bestNodeList = new ArrayList<GameTreeNode<MonteCarloProperties>>();
@@ -62,6 +70,7 @@ public class MonteCarloUCT extends MonteCarlo {
public Action getBestAction(GameTreeNode<MonteCarloProperties> node) { public Action getBestAction(GameTreeNode<MonteCarloProperties> node) {
Action bestAction = Action.NONE; Action bestAction = Action.NONE;
double bestScore = Double.NEGATIVE_INFINITY; double bestScore = Double.NEGATIVE_INFINITY;
GameTreeNode<MonteCarloProperties> bestChild = null;
for (Action action : node.getActions()) { for (Action action : node.getActions()) {
GameTreeNode<MonteCarloProperties> childNode = node.getChild(action); GameTreeNode<MonteCarloProperties> childNode = node.getChild(action);
@@ -72,9 +81,16 @@ public class MonteCarloUCT extends MonteCarlo {
if (childScore >= bestScore) { if (childScore >= bestScore) {
bestScore = childScore; bestScore = childScore;
bestAction = action; bestAction = action;
bestChild = childNode;
} }
} }
if (bestAction == Action.NONE) {
System.out.println("MonteCarloUCT failed - no actions were found for the current game staet (not even PASS).");
} else {
System.out.println("Action " + bestAction + " selected for " + node.getGameState().getPlayerToMove() + " with simulated win ratio of " + (bestScore*100.0 + "%"));
System.out.println("It was visited " + bestChild.getProperties().getVisits() + " times out of " + node.getProperties().getVisits() + " rollouts among " + node.getNumChildren() + " valid actions from the current state.");
}
return bestAction; return bestAction;
} }
@@ -123,9 +139,18 @@ public class MonteCarloUCT extends MonteCarlo {
numStateEvaluations++; numStateEvaluations++;
if (stateEvaluator.scoreGame(rolloutGameState).isWinner(player)) { GameScore gameScore = stateEvaluator.scoreGame(rolloutGameState);
if (gameScore.isWinner(player)) {
System.out.println();
System.out.println("Win for " + player + ":\n" + rolloutGameState);
System.out.println(gameScore.getScoreReport());
System.out.println();
return 1; return 1;
} else { } else {
System.out.println();
System.out.println("Loss for " + player + ":\n" + rolloutGameState);
System.out.println(gameScore.getScoreReport());
System.out.println();
return 0; return 0;
} }
} }

View File

@@ -9,7 +9,8 @@ import org.junit.Test;
public class CaptureTest { public class CaptureTest {
@Test @Test
public void testCapture() { public void testCapture() {
GameState gameState = new GameState(5); GameConfig gameConfig = new GameConfig(5);
GameState gameState = new GameState(gameConfig);
gameState.playStone(Player.BLACK, Action.getInstance("A2")); gameState.playStone(Player.BLACK, Action.getInstance("A2"));
gameState.playStone(Player.BLACK, Action.getInstance("B3")); gameState.playStone(Player.BLACK, Action.getInstance("B3"));
gameState.playStone(Player.BLACK, Action.getInstance("B1")); gameState.playStone(Player.BLACK, Action.getInstance("B1"));
@@ -28,8 +29,8 @@ public class CaptureTest {
@Test @Test
public void testMultiGroupCapture() { public void testMultiGroupCapture() {
GameConfig gameConfig = new GameConfig(); GameConfig gameConfig = new GameConfig(5);
GameState gameState = new GameState(5); GameState gameState = new GameState(gameConfig);
gameState.playStone(Player.BLACK, Action.getInstance("A2")); gameState.playStone(Player.BLACK, Action.getInstance("A2"));
gameState.playStone(Player.BLACK, Action.getInstance("B3")); gameState.playStone(Player.BLACK, Action.getInstance("B3"));
@@ -59,7 +60,8 @@ public class CaptureTest {
@Test @Test
public void testCaptureFromEye() { public void testCaptureFromEye() {
GameState gameState = new GameState(5); GameConfig gameConfig = new GameConfig(5);
GameState gameState = new GameState(gameConfig);
gameState.playStone(Player.BLACK, Action.getInstance("A1")); gameState.playStone(Player.BLACK, Action.getInstance("A1"));
gameState.playStone(Player.BLACK, Action.getInstance("B2")); gameState.playStone(Player.BLACK, Action.getInstance("B2"));

View File

@@ -10,19 +10,19 @@ public class GameScoreTest {
@Test @Test
public void testGetAggregateScoreZero() { public void testGetAggregateScoreZero() {
GameScore gameScore = new GameScore(0,0,0); GameScore gameScore = new GameScore(0,0,19,0);
assertEquals(GameScore.NORMALIZED_ZERO_SCORE, gameScore.getAggregateScore()); assertEquals(gameScore.getNormalizedZeroScore(), gameScore.getAggregateScore());
} }
@Test @Test
public void testGetAggregateScoreBlackWinsNoKomi() { public void testGetAggregateScoreBlackWinsNoKomi() {
GameScore gameScore = new GameScore(25,2,0); GameScore gameScore = new GameScore(25,2,19,0);
assertEquals(425, gameScore.getAggregateScore()); assertEquals(425, gameScore.getAggregateScore());
} }
@Test @Test
public void testGetAggregateScoreWhiteWinsWithKomi() { public void testGetAggregateScoreWhiteWinsWithKomi() {
GameScore gameScore = new GameScore(10,12,6.5); GameScore gameScore = new GameScore(10,12,19,6.5);
assertEquals(362, gameScore.getAggregateScore()); assertEquals(362, gameScore.getAggregateScore());
} }
} }

View File

@@ -10,7 +10,8 @@ public class GameStateTest {
@Test @Test
public void testGetEmptyCoords() { public void testGetEmptyCoords() {
GameState gameState = new GameState(3); GameConfig gameConfig = new GameConfig(3);
GameState gameState = new GameState(gameConfig);
gameState.playStone(Player.BLACK, "A1"); gameState.playStone(Player.BLACK, "A1");
gameState.playStone(Player.WHITE, "A2"); gameState.playStone(Player.WHITE, "A2");

View File

@@ -15,21 +15,24 @@ public class IllegalMoveTest {
@Test @Test
public void testIllegalMoveOnOwnStone() { public void testIllegalMoveOnOwnStone() {
GameState gameState = new GameState(5); GameConfig gameConfig = new GameConfig(5);
GameState gameState = new GameState(gameConfig);
gameState.playStone(Player.BLACK, Action.getInstance("B3")); gameState.playStone(Player.BLACK, Action.getInstance("B3"));
assertFalse(gameState.playStone(Player.BLACK, Action.getInstance("B3"))); assertFalse(gameState.playStone(Player.BLACK, Action.getInstance("B3")));
} }
@Test @Test
public void testIllegalMoveOnOtherStone() { public void testIllegalMoveOnOtherStone() {
GameState gameState = new GameState(5); GameConfig gameConfig = new GameConfig(5);
GameState gameState = new GameState(gameConfig);
gameState.playStone(Player.BLACK, Action.getInstance("B3")); gameState.playStone(Player.BLACK, Action.getInstance("B3"));
assertFalse(gameState.playStone(Player.WHITE, Action.getInstance("B3"))); assertFalse(gameState.playStone(Player.WHITE, Action.getInstance("B3")));
} }
@Test @Test
public void testIllegalMoveNoLiberties() { public void testIllegalMoveNoLiberties() {
GameState gameState = new GameState(5); GameConfig gameConfig = new GameConfig(5);
GameState gameState = new GameState(gameConfig);
gameState.playStone(Player.BLACK, Action.getInstance("A2")); gameState.playStone(Player.BLACK, Action.getInstance("A2"));
gameState.playStone(Player.BLACK, Action.getInstance("B1")); gameState.playStone(Player.BLACK, Action.getInstance("B1"));
gameState.playStone(Player.BLACK, Action.getInstance("B3")); gameState.playStone(Player.BLACK, Action.getInstance("B3"));
@@ -41,7 +44,8 @@ public class IllegalMoveTest {
@Test @Test
public void testIllegalMoveFormsTrappedGroup() { public void testIllegalMoveFormsTrappedGroup() {
GameState gameState = new GameState(9); GameConfig gameConfig = new GameConfig(9);
GameState gameState = new GameState(gameConfig);
gameState.playStone(Player.BLACK, Action.getInstance("A5")); gameState.playStone(Player.BLACK, Action.getInstance("A5"));
gameState.playStone(Player.BLACK, Action.getInstance("B6")); gameState.playStone(Player.BLACK, Action.getInstance("B6"));
gameState.playStone(Player.BLACK, Action.getInstance("B7")); gameState.playStone(Player.BLACK, Action.getInstance("B7"));
@@ -53,7 +57,8 @@ public class IllegalMoveTest {
@Test @Test
public void testIllegalMoveFormsTrappedGroup2() { public void testIllegalMoveFormsTrappedGroup2() {
GameState gameState = new GameState(9); GameConfig gameConfig = new GameConfig(9);
GameState gameState = new GameState(gameConfig);
gameState.playStone(Player.BLACK, Action.getInstance("G1")); gameState.playStone(Player.BLACK, Action.getInstance("G1"));
gameState.playStone(Player.BLACK, Action.getInstance("H2")); gameState.playStone(Player.BLACK, Action.getInstance("H2"));
gameState.playStone(Player.BLACK, Action.getInstance("H3")); gameState.playStone(Player.BLACK, Action.getInstance("H3"));
@@ -72,7 +77,8 @@ public class IllegalMoveTest {
@Test @Test
public void testIllegalMoveSuicide() { public void testIllegalMoveSuicide() {
GameState gameState = new GameState(3); GameConfig gameConfig = new GameConfig(3);
GameState gameState = new GameState(gameConfig);
gameState.playStone(Player.WHITE, Action.getInstance("A1")); gameState.playStone(Player.WHITE, Action.getInstance("A1"));
gameState.playStone(Player.WHITE, Action.getInstance("B1")); gameState.playStone(Player.WHITE, Action.getInstance("B1"));
@@ -83,7 +89,7 @@ public class IllegalMoveTest {
System.out.println("State before move: "); System.out.println("State before move: ");
System.out.println(gameState); System.out.println(gameState);
assertFalse("Play by BLACK at A2 should have failed.",gameState.playStone(Player.BLACK, Action.getInstance("A2"))); assertFalse("Play by BLACK at A2 should have failed.",gameState.playStone(Player.BLACK, Action.getInstance("A2")));
List<Action> validMoves = new ValidMoveGenerator().getActions(new GameConfig(), gameState, Player.BLACK, ActionGenerator.ALL_ACTIONS); List<Action> validMoves = new ValidMoveGenerator().getActions(gameConfig, gameState, Player.BLACK, ActionGenerator.ALL_ACTIONS);
assertEquals(4, validMoves.size()); assertEquals(4, validMoves.size());
assertTrue(validMoves.contains(Action.PASS)); assertTrue(validMoves.contains(Action.PASS));
assertTrue(validMoves.contains(Action.getInstance("C1"))); assertTrue(validMoves.contains(Action.getInstance("C1")));

View File

@@ -8,7 +8,8 @@ import org.junit.Test;
public class LegalMoveTest { public class LegalMoveTest {
@Test @Test
public void testLegalMove1Liberty() { public void testLegalMove1Liberty() {
GameState gameState = new GameState(5); GameConfig gameConfig = new GameConfig(5);
GameState gameState = new GameState(gameConfig);
gameState.playStone(Player.BLACK, Action.getInstance("A2")); gameState.playStone(Player.BLACK, Action.getInstance("A2"));
assertEquals(Player.WHITE, gameState.getPlayerToMove()); assertEquals(Player.WHITE, gameState.getPlayerToMove());
gameState.playStone(Player.WHITE, Action.PASS); gameState.playStone(Player.WHITE, Action.PASS);
@@ -26,7 +27,8 @@ public class LegalMoveTest {
public void testLegalMove2Liberties() { public void testLegalMove2Liberties() {
//Unit test based on illegal move from 9x9 game using MonteCarloUCT //Unit test based on illegal move from 9x9 game using MonteCarloUCT
//Illegal move detected by gokgs.com server //Illegal move detected by gokgs.com server
GameState gameState = new GameState(9); GameConfig gameConfig = new GameConfig(9);
GameState gameState = new GameState(gameConfig);
gameState.playStone(Player.BLACK, Action.getInstance("G5")); gameState.playStone(Player.BLACK, Action.getInstance("G5"));
gameState.playStone(Player.BLACK, Action.getInstance("G7")); gameState.playStone(Player.BLACK, Action.getInstance("G7"));
gameState.playStone(Player.BLACK, Action.getInstance("F6")); gameState.playStone(Player.BLACK, Action.getInstance("F6"));

View File

@@ -6,11 +6,11 @@ import static org.junit.Assert.assertTrue;
import org.junit.Test; import org.junit.Test;
public class StateEvaluatorTest { public class StateEvaluatorTest {
GameConfig gameConfig = new GameConfig();
@Test @Test
public void testScoreEmptyBoard() { public void testScoreEmptyBoard() {
GameState gameState = new GameState(5); GameConfig gameConfig = new GameConfig(5);
GameState gameState = new GameState(gameConfig);
GameScore gameScore = new StateEvaluator(gameConfig) GameScore gameScore = new StateEvaluator(gameConfig)
.scoreGame(gameState); .scoreGame(gameState);
@@ -20,7 +20,8 @@ public class StateEvaluatorTest {
@Test @Test
public void testScoreFirstMove() { public void testScoreFirstMove() {
GameState gameState = new GameState(5); GameConfig gameConfig = new GameConfig(5);
GameState gameState = new GameState(gameConfig);
gameState.playStone(Player.BLACK, Action.getInstance("B3")); gameState.playStone(Player.BLACK, Action.getInstance("B3"));
GameScore gameScore = new StateEvaluator(gameConfig) GameScore gameScore = new StateEvaluator(gameConfig)
@@ -34,7 +35,8 @@ public class StateEvaluatorTest {
@Test @Test
public void testScoreTiedAtMove2() { public void testScoreTiedAtMove2() {
GameState gameState = new GameState(5); GameConfig gameConfig = new GameConfig(5);
GameState gameState = new GameState(gameConfig);
gameState.playStone(Player.BLACK, Action.getInstance("B3")); gameState.playStone(Player.BLACK, Action.getInstance("B3"));
gameState.playStone(Player.WHITE, Action.getInstance("A1")); gameState.playStone(Player.WHITE, Action.getInstance("A1"));
@@ -49,7 +51,8 @@ public class StateEvaluatorTest {
@Test @Test
public void testScoreTerritory() { public void testScoreTerritory() {
GameState gameState = new GameState(5); GameConfig gameConfig = new GameConfig(5);
GameState gameState = new GameState(gameConfig);
gameState.playStone(Player.BLACK, Action.getInstance("A2")); gameState.playStone(Player.BLACK, Action.getInstance("A2"));
gameState.playStone(Player.BLACK, Action.getInstance("B3")); gameState.playStone(Player.BLACK, Action.getInstance("B3"));
@@ -71,7 +74,8 @@ public class StateEvaluatorTest {
@Test @Test
public void testCaptureAggScore() { public void testCaptureAggScore() {
GameState gameState = new GameState(9); GameConfig gameConfig = new GameConfig(9);
GameState gameState = new GameState(gameConfig);
gameState.playStone(Player.WHITE, Action.getInstance("A2")); gameState.playStone(Player.WHITE, Action.getInstance("A2"));
gameState.playStone(Player.WHITE, Action.getInstance("B1")); gameState.playStone(Player.WHITE, Action.getInstance("B1"));
gameState.playStone(Player.WHITE, Action.getInstance("C2")); gameState.playStone(Player.WHITE, Action.getInstance("C2"));
@@ -86,7 +90,7 @@ public class StateEvaluatorTest {
System.out.println(moveToA1); System.out.println(moveToA1);
System.out.println(capAtB3); System.out.println(capAtB3);
StateEvaluator eval = new StateEvaluator(new GameConfig()); StateEvaluator eval = new StateEvaluator(gameConfig);
int scoreA1 = eval.scoreGame(moveToA1).getAggregateScore(); int scoreA1 = eval.scoreGame(moveToA1).getAggregateScore();
int scoreB3 = eval.scoreGame(capAtB3).getAggregateScore(); int scoreB3 = eval.scoreGame(capAtB3).getAggregateScore();

View File

@@ -5,7 +5,8 @@ import org.junit.Test;
public class TerritoryFinderTest { public class TerritoryFinderTest {
@Test @Test
public void testMarkTerritory() { public void testMarkTerritory() {
GameState gameState = new GameState(5); GameConfig gameConfig = new GameConfig(5);
GameState gameState = new GameState(gameConfig);
gameState.playStone(Player.BLACK, Action.getInstance("A2")); gameState.playStone(Player.BLACK, Action.getInstance("A2"));
gameState.playStone(Player.BLACK, Action.getInstance("B3")); gameState.playStone(Player.BLACK, Action.getInstance("B3"));

View File

@@ -12,13 +12,14 @@ public class AlphaBetaTest {
@Test @Test
public void testGenmoveAsW() { public void testGenmoveAsW() {
Policy treeSearch = new AlphaBeta(); Policy treeSearch = new AlphaBeta();
GameState gameState = new GameState(6); GameConfig gameConfig = new GameConfig(6);
GameState gameState = new GameState(gameConfig);
gameState.playStone(Player.WHITE, Action.getInstance("A2")); gameState.playStone(Player.WHITE, Action.getInstance("A2"));
gameState.playStone(Player.WHITE, Action.getInstance("B1")); gameState.playStone(Player.WHITE, Action.getInstance("B1"));
gameState.playStone(Player.WHITE, Action.getInstance("C2")); gameState.playStone(Player.WHITE, Action.getInstance("C2"));
gameState.playStone(Player.BLACK, Action.getInstance("B2")); gameState.playStone(Player.BLACK, Action.getInstance("B2"));
Action move = treeSearch.getAction(new GameConfig(), gameState, Player.WHITE); Action move = treeSearch.getAction(gameConfig, gameState, Player.WHITE);
System.out.println(gameState); System.out.println(gameState);
@@ -34,13 +35,14 @@ public class AlphaBetaTest {
@Test @Test
public void testGenmoveAsB() { public void testGenmoveAsB() {
Policy treeSearch = new AlphaBeta(); Policy treeSearch = new AlphaBeta();
GameState gameState = new GameState(6); GameConfig gameConfig = new GameConfig(6);
GameState gameState = new GameState(gameConfig);
gameState.playStone(Player.BLACK, Action.getInstance("A2")); gameState.playStone(Player.BLACK, Action.getInstance("A2"));
gameState.playStone(Player.BLACK, Action.getInstance("B1")); gameState.playStone(Player.BLACK, Action.getInstance("B1"));
gameState.playStone(Player.BLACK, Action.getInstance("C2")); gameState.playStone(Player.BLACK, Action.getInstance("C2"));
gameState.playStone(Player.WHITE, Action.getInstance("B2")); gameState.playStone(Player.WHITE, Action.getInstance("B2"));
Action move = treeSearch.getAction(new GameConfig(), gameState, Player.BLACK); Action move = treeSearch.getAction(gameConfig, gameState, Player.BLACK);
System.out.println(gameState); System.out.println(gameState);

View File

@@ -12,13 +12,14 @@ public class MinimaxTest {
@Test @Test
public void testGenmoveAsW() { public void testGenmoveAsW() {
Policy treeSearch = new Minimax(); Policy treeSearch = new Minimax();
GameState gameState = new GameState(6); GameConfig gameConfig = new GameConfig(6);
GameState gameState = new GameState(gameConfig);
gameState.playStone(Player.WHITE, Action.getInstance("A2")); gameState.playStone(Player.WHITE, Action.getInstance("A2"));
gameState.playStone(Player.WHITE, Action.getInstance("B1")); gameState.playStone(Player.WHITE, Action.getInstance("B1"));
gameState.playStone(Player.WHITE, Action.getInstance("C2")); gameState.playStone(Player.WHITE, Action.getInstance("C2"));
gameState.playStone(Player.BLACK, Action.getInstance("B2")); gameState.playStone(Player.BLACK, Action.getInstance("B2"));
Action move = treeSearch.getAction(new GameConfig(), gameState, Action move = treeSearch.getAction(gameConfig, gameState,
Player.WHITE); Player.WHITE);
System.out.println(gameState); System.out.println(gameState);
@@ -35,13 +36,14 @@ public class MinimaxTest {
@Test @Test
public void testGenmoveAsB() { public void testGenmoveAsB() {
Policy treeSearch = new Minimax(); Policy treeSearch = new Minimax();
GameState gameState = new GameState(6); GameConfig gameConfig = new GameConfig(6);
GameState gameState = new GameState(gameConfig);
gameState.playStone(Player.BLACK, Action.getInstance("A2")); gameState.playStone(Player.BLACK, Action.getInstance("A2"));
gameState.playStone(Player.BLACK, Action.getInstance("B1")); gameState.playStone(Player.BLACK, Action.getInstance("B1"));
gameState.playStone(Player.BLACK, Action.getInstance("C2")); gameState.playStone(Player.BLACK, Action.getInstance("C2"));
gameState.playStone(Player.WHITE, Action.getInstance("B2")); gameState.playStone(Player.WHITE, Action.getInstance("B2"));
Action move = treeSearch.getAction(new GameConfig(), gameState, Action move = treeSearch.getAction(gameConfig, gameState,
Player.BLACK); Player.BLACK);
System.out.println(gameState); System.out.println(gameState);

View File

@@ -15,13 +15,14 @@ public class MonteCarloUCTTest {
@Test @Test
public void testGenmoveAsW() { public void testGenmoveAsW() {
Policy treeSearch = new MonteCarloUCT(new RandomMovePolicy(),10000L); Policy treeSearch = new MonteCarloUCT(new RandomMovePolicy(),10000L);
GameState gameState = new GameState(6); GameConfig gameConfig = new GameConfig(6);
GameState gameState = new GameState(gameConfig);
gameState.playStone(Player.WHITE, Action.getInstance("A2")); gameState.playStone(Player.WHITE, Action.getInstance("A2"));
gameState.playStone(Player.WHITE, Action.getInstance("B1")); gameState.playStone(Player.WHITE, Action.getInstance("B1"));
gameState.playStone(Player.WHITE, Action.getInstance("C2")); gameState.playStone(Player.WHITE, Action.getInstance("C2"));
gameState.playStone(Player.BLACK, Action.getInstance("B2")); gameState.playStone(Player.BLACK, Action.getInstance("B2"));
Action move = treeSearch.getAction(new GameConfig(), gameState, Player.WHITE); Action move = treeSearch.getAction(gameConfig, gameState, Player.WHITE);
System.out.println(gameState); System.out.println(gameState);
@@ -37,13 +38,14 @@ public class MonteCarloUCTTest {
@Test @Test
public void testGenmoveAsB() { public void testGenmoveAsB() {
Policy treeSearch = new MonteCarloUCT(new RandomMovePolicy(),10000L); Policy treeSearch = new MonteCarloUCT(new RandomMovePolicy(),10000L);
GameState gameState = new GameState(6); GameConfig gameConfig = new GameConfig(5);
GameState gameState = new GameState(gameConfig);
gameState.playStone(Player.BLACK, Action.getInstance("A2")); gameState.playStone(Player.BLACK, Action.getInstance("A2"));
gameState.playStone(Player.BLACK, Action.getInstance("B1")); gameState.playStone(Player.BLACK, Action.getInstance("B1"));
gameState.playStone(Player.BLACK, Action.getInstance("C2")); gameState.playStone(Player.BLACK, Action.getInstance("C2"));
gameState.playStone(Player.WHITE, Action.getInstance("B2")); gameState.playStone(Player.WHITE, Action.getInstance("B2"));
Action move = treeSearch.getAction(new GameConfig(), gameState, Player.BLACK); Action move = treeSearch.getAction(gameConfig, gameState, Player.BLACK);
System.out.println(gameState); System.out.println(gameState);
@@ -59,7 +61,8 @@ public class MonteCarloUCTTest {
@Test @Test
public void testIllegalMoveRejection() { public void testIllegalMoveRejection() {
Policy treeSearch = new MonteCarloUCT(new RandomMovePolicy(),2000L); Policy treeSearch = new MonteCarloUCT(new RandomMovePolicy(),2000L);
GameState gameState = new GameState(4); GameConfig gameConfig = new GameConfig(5);
GameState gameState = new GameState(gameConfig);
gameState.playStone(Player.WHITE, Action.getInstance("A2")); gameState.playStone(Player.WHITE, Action.getInstance("A2"));
gameState.playStone(Player.WHITE, Action.getInstance("B1")); gameState.playStone(Player.WHITE, Action.getInstance("B1"));
gameState.playStone(Player.WHITE, Action.getInstance("C2")); gameState.playStone(Player.WHITE, Action.getInstance("C2"));
@@ -68,7 +71,7 @@ public class MonteCarloUCTTest {
Action move; Action move;
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
move = treeSearch.getAction(new GameConfig(), gameState, Player.BLACK); move = treeSearch.getAction(gameConfig, gameState, Player.BLACK);
System.out.println("Generated move: " + move); System.out.println("Generated move: " + move);
GameState stateCopy = new GameState(gameState); GameState stateCopy = new GameState(gameState);
stateCopy.playStone(Player.BLACK, move); stateCopy.playStone(Player.BLACK, move);

View File

@@ -20,17 +20,20 @@ public class RandomTest {
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
public void testGenmoveForNone() { public void testGenmoveForNone() {
Policy moveGenerator = new RandomMovePolicy(); Policy moveGenerator = new RandomMovePolicy();
GameState gameState = new GameState(5); GameConfig gameConfig = new GameConfig(5);
moveGenerator.getAction(new GameConfig(), gameState, Player.BLACK); GameState gameState = new GameState(gameConfig);
gameState = new GameState(5); moveGenerator.getAction(gameConfig, gameState, Player.BLACK);
moveGenerator.getAction(new GameConfig(), gameState, Player.WHITE); gameConfig = new GameConfig(5);
gameState = new GameState(gameConfig);
moveGenerator.getAction(gameConfig, gameState, Player.WHITE);
assertEquals(Action.PASS, moveGenerator.getAction(new GameConfig(), gameState, Player.NONE)); assertEquals(Action.PASS, moveGenerator.getAction(gameConfig, gameState, Player.NONE));
} }
@Test @Test
public void testAlternativeToIllegalMove() { public void testAlternativeToIllegalMove() {
GameState gameState = new GameState(4); GameConfig gameConfig = new GameConfig(4);
GameState gameState = new GameState(gameConfig);
gameState.playStone(Player.BLACK, Action.getInstance("A1")); gameState.playStone(Player.BLACK, Action.getInstance("A1"));
gameState.playStone(Player.BLACK, Action.getInstance("A2")); gameState.playStone(Player.BLACK, Action.getInstance("A2"));
gameState.playStone(Player.BLACK, Action.getInstance("A3")); gameState.playStone(Player.BLACK, Action.getInstance("A3"));
@@ -52,14 +55,15 @@ public class RandomTest {
List<Action> prohibitedMoves = new ArrayList<Action>(); List<Action> prohibitedMoves = new ArrayList<Action>();
prohibitedMoves.add(Action.PASS); prohibitedMoves.add(Action.PASS);
assertEquals(Action.getInstance("B3"), new RandomMovePolicy().getAction(new GameConfig(), gameState, prohibitedMoves, Player.WHITE)); assertEquals(Action.getInstance("B3"), new RandomMovePolicy().getAction(gameConfig, gameState, prohibitedMoves, Player.WHITE));
System.out.println(gameState); System.out.println(gameState);
} }
@Test @Test
public void testIllegalMoveSuicide() { public void testIllegalMoveSuicide() {
GameState gameState = new GameState(3); GameConfig gameConfig = new GameConfig(3);
GameState gameState = new GameState(gameConfig);
gameState.playStone(Player.WHITE, Action.getInstance("A1")); gameState.playStone(Player.WHITE, Action.getInstance("A1"));
gameState.playStone(Player.WHITE, Action.getInstance("B1")); gameState.playStone(Player.WHITE, Action.getInstance("B1"));
@@ -74,7 +78,7 @@ public class RandomTest {
//There is only a minute chance (5E-7) that RandomMoveGenerator fails to return an invalid move with probability 1/4 //There is only a minute chance (5E-7) that RandomMoveGenerator fails to return an invalid move with probability 1/4
//after 50 calls, if this bug recurs. //after 50 calls, if this bug recurs.
for (int i = 0; i < 50; i++) { for (int i = 0; i < 50; i++) {
Action action = randomMovePolicy.getAction(new GameConfig(),gameState,Player.BLACK); Action action = randomMovePolicy.getAction(gameConfig,gameState,Player.BLACK);
//System.out.println(action); //System.out.println(action);
assertFalse("RandomMovePolicy returned illegal suicide move A2",action.equals(Action.getInstance("A2"))); assertFalse("RandomMovePolicy returned illegal suicide move A2",action.equals(Action.getInstance("A2")));
} }
@@ -82,7 +86,8 @@ public class RandomTest {
@Test @Test
public void testIllegalMoveKo() { public void testIllegalMoveKo() {
GameState gameState = new GameState(4); GameConfig gameConfig = new GameConfig(4);
GameState gameState = new GameState(gameConfig);
gameState.playStone(Player.WHITE, Action.getInstance("B1")); gameState.playStone(Player.WHITE, Action.getInstance("B1"));
gameState.playStone(Player.WHITE, Action.getInstance("A2")); gameState.playStone(Player.WHITE, Action.getInstance("A2"));
@@ -101,7 +106,7 @@ public class RandomTest {
RandomMovePolicy randomMovePolicy = new RandomMovePolicy(); RandomMovePolicy randomMovePolicy = new RandomMovePolicy();
//Test that after 50 moves, the policy never returns B3, which would be a Ko violation //Test that after 50 moves, the policy never returns B3, which would be a Ko violation
for (int i = 0; i < 50; i++) { for (int i = 0; i < 50; i++) {
Action action = randomMovePolicy.getAction(new GameConfig(),gameState,Player.WHITE); Action action = randomMovePolicy.getAction(gameConfig,gameState,Player.WHITE);
//System.out.println(action); //System.out.println(action);
assertFalse(action.equals(Action.NONE)); assertFalse(action.equals(Action.NONE));
assertFalse("RandomMovePolicy returned Ko violation move B3",action.equals(Action.getInstance("B3"))); assertFalse("RandomMovePolicy returned Ko violation move B3",action.equals(Action.getInstance("B3")));

View File

@@ -26,7 +26,8 @@ public class ValidMoveGeneratorTest {
1 . O . . . 1 1 . O . . . 1
A B C D E A B C D E
*/ */
GameState gameState = new GameState(5); GameConfig gameConfig = new GameConfig(5);
GameState gameState = new GameState(gameConfig);
gameState.playStone(Player.WHITE, Action.getInstance("A2")); gameState.playStone(Player.WHITE, Action.getInstance("A2"));
gameState.playStone(Player.WHITE, Action.getInstance("B1")); gameState.playStone(Player.WHITE, Action.getInstance("B1"));
gameState.playStone(Player.WHITE, Action.getInstance("B4")); gameState.playStone(Player.WHITE, Action.getInstance("B4"));
@@ -34,7 +35,7 @@ public class ValidMoveGeneratorTest {
assertFalse(gameState.playStone(Player.BLACK, Action.getInstance("A1"))); assertFalse(gameState.playStone(Player.BLACK, Action.getInstance("A1")));
List<Action> validMoves = new ValidMoveGenerator().getActions(new GameConfig(), gameState, Player.BLACK,0); List<Action> validMoves = new ValidMoveGenerator().getActions(gameConfig, gameState, Player.BLACK,0);
assertTrue(validMoves.size() > 0); assertTrue(validMoves.size() > 0);