Refactoring in progress.
Player and Action classes are now singletons (factory pattern) rather than String values. Implementing more general treesearch code for minimax, alpha-beta, monte carlo using simplified backup logic.
This commit is contained in:
73
src/net/woodyfolsom/msproj/Action.java
Normal file
73
src/net/woodyfolsom/msproj/Action.java
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
package net.woodyfolsom.msproj;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class Action {
|
||||||
|
private static final Map<String, Action> actionMap = new HashMap<String,Action>();
|
||||||
|
|
||||||
|
private char column = 'x';
|
||||||
|
private int row = 0;
|
||||||
|
|
||||||
|
//private Player player;
|
||||||
|
private String move;
|
||||||
|
|
||||||
|
public static final Action NONE = new Action("NONE", /*Player.NONE,*/ 'x', 0);
|
||||||
|
public static final Action PASS = new Action("PASS", /*Player.NONE,*/ 'x', 0);
|
||||||
|
|
||||||
|
private Action(String move, /*Player player,*/ char column, int row) {
|
||||||
|
this.move = move;
|
||||||
|
//this.player = player;
|
||||||
|
this.column = column;
|
||||||
|
this.row = row;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Action getInstance(/*String playerName,*/ String move) {
|
||||||
|
if (move == null || "NONE".equals(move) || "PASS".equals(move)) {
|
||||||
|
throw new IllegalArgumentException("Illegal move: " + move);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (actionMap.containsKey(move)) {
|
||||||
|
return actionMap.get(move);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Player player;
|
||||||
|
if ("b".equals(playerName)) {
|
||||||
|
player = Player.BLACK;
|
||||||
|
} else if ("w".equals(playerName)) {
|
||||||
|
player = Player.WHITE;
|
||||||
|
} else {
|
||||||
|
return Action.NONE;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
char col = move.charAt(0);
|
||||||
|
int row = Integer.valueOf(move.substring(1));
|
||||||
|
|
||||||
|
Action action = new Action(move, col, row);
|
||||||
|
actionMap.put(move, action);
|
||||||
|
|
||||||
|
return action;
|
||||||
|
}
|
||||||
|
|
||||||
|
public char getColumn() {
|
||||||
|
return column;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRow() {
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isNone() {
|
||||||
|
return this == Action.NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isPass() {
|
||||||
|
return this == Action.PASS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return move;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -28,11 +28,11 @@ public class GameScore {
|
|||||||
return NORMALIZED_ZERO_SCORE + 2 * blackScore - ((int)(2 * (whiteScore + komi)));
|
return NORMALIZED_ZERO_SCORE + 2 * blackScore - ((int)(2 * (whiteScore + komi)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getScore(String color) {
|
public double getScore(Player color) {
|
||||||
if ("w".equals(color)) {
|
if (color == Player.BLACK) {
|
||||||
return getWhiteScore();
|
|
||||||
} else if ("b".equals(color)) {
|
|
||||||
return getBlackScore();
|
return getBlackScore();
|
||||||
|
} else if (color == Player.WHITE) {
|
||||||
|
return getWhiteScore();
|
||||||
} else {
|
} else {
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
@@ -42,6 +42,14 @@ public class GameScore {
|
|||||||
return (double)whiteScore + komi;
|
return (double)whiteScore + komi;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isWinner(String color) {
|
||||||
|
if ("w".equals(color)) {
|
||||||
|
return getWhiteScore() < NORMALIZED_ZERO_SCORE;
|
||||||
|
} else {
|
||||||
|
return getBlackScore() > NORMALIZED_ZERO_SCORE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "B: " + blackScore + "W: "+ whiteScore+"K:" + komi;
|
return "B: " + blackScore + "W: "+ whiteScore+"K:" + komi;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,6 @@ package net.woodyfolsom.msproj;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import net.woodyfolsom.msproj.policy.Policy;
|
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
|
||||||
@@ -14,7 +12,7 @@ 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;
|
||||||
|
|
||||||
public GameState(int size) {
|
public GameState(int size) {
|
||||||
if (size < 1 || size > 19) {
|
if (size < 1 || size > 19) {
|
||||||
throw new IllegalArgumentException("Invalid board size: " + size);
|
throw new IllegalArgumentException("Invalid board size: " + size);
|
||||||
@@ -60,28 +58,19 @@ public class GameState {
|
|||||||
return whitePrisoners;
|
return whitePrisoners;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean playStone(String player, String coord) {
|
public boolean playStone(Player player, String move) {
|
||||||
//Opponent passes? Just ignore it.
|
//Opponent passes? Just ignore it.
|
||||||
if (Policy.PASS.equalsIgnoreCase(coord)) {
|
Action action = Action.getInstance(move);
|
||||||
|
|
||||||
|
if (action.isPass()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//LOGGER.info("Playing " + player + " at " + coord);
|
if (action.isNone()) {
|
||||||
|
|
||||||
char stoneColor;
|
|
||||||
if ("b".equals(player)) {
|
|
||||||
stoneColor = GameBoard.BLACK_STONE;
|
|
||||||
} else if ("w".equals(player)) {
|
|
||||||
stoneColor = GameBoard.WHITE_STONE;
|
|
||||||
} else {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
char col = coord.charAt(0);
|
return playStone(player, action);
|
||||||
int row = Integer.valueOf(coord.substring(1));
|
|
||||||
|
|
||||||
//LOGGER.info("Playing " + stoneColor + " at " + col + row);
|
|
||||||
return playStone(col,row, stoneColor);
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Places a stone at the requested coordinate. Placement is legal if the
|
* Places a stone at the requested coordinate. Placement is legal if the
|
||||||
@@ -97,20 +86,22 @@ public class GameState {
|
|||||||
* @param stone
|
* @param stone
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public boolean playStone(char colLabel, int rowNum, char stoneSymbol) {
|
public boolean playStone(Player player, Action action) {
|
||||||
char currentStone = gameBoard.getSymbolAt(colLabel, rowNum);
|
char currentStone = gameBoard.getSymbolAt(action.getColumn(), action.getRow());
|
||||||
|
|
||||||
if (currentStone != GameBoard.EMPTY_INTERSECTION) {
|
if (currentStone != GameBoard.EMPTY_INTERSECTION) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Place stone as requested, then check for (1) captured neighbors and (2) illegal move due to 0 liberties.
|
//Place stone as requested, then check for (1) captured neighbors and (2) illegal move due to 0 liberties.
|
||||||
gameBoard.setSymbolAt(colLabel, rowNum, stoneSymbol);
|
char stoneSymbol = player.getStoneSymbol();
|
||||||
|
gameBoard.setSymbolAt(action.getColumn(), action.getRow(), stoneSymbol);
|
||||||
|
|
||||||
//look for captured adjacent groups and increment the prisoner counter
|
//look for captured adjacent groups and increment the prisoner counter
|
||||||
char opponentSymbol = GameBoard.getOpponentSymbol(stoneSymbol);
|
char opponentSymbol = GameBoard.getOpponentSymbol(player.getStoneSymbol());
|
||||||
|
|
||||||
int col = GameBoard.getColumnIndex(colLabel);
|
int col = GameBoard.getColumnIndex(action.getColumn());
|
||||||
int row = rowNum - 1;
|
int row = action.getRow() - 1;
|
||||||
|
|
||||||
int prisonerCount = 0;
|
int prisonerCount = 0;
|
||||||
if (col > 0 && gameBoard.getSymbolAt(col-1, row) == opponentSymbol) {
|
if (col > 0 && gameBoard.getSymbolAt(col-1, row) == opponentSymbol) {
|
||||||
@@ -153,8 +144,8 @@ public class GameState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Moved test for 0 liberties until after attempting to capture neighboring groups.
|
//Moved test for 0 liberties until after attempting to capture neighboring groups.
|
||||||
if (0 == LibertyCounter.countLiberties(gameBoard, colLabel, rowNum, stoneSymbol)) {
|
if (0 == LibertyCounter.countLiberties(gameBoard, action.getColumn(), action.getRow(), stoneSymbol)) {
|
||||||
gameBoard.removeStone(colLabel,rowNum);
|
gameBoard.removeStone(action.getColumn(),action.getRow());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -77,14 +77,24 @@ public class GoGame {
|
|||||||
case genmove:
|
case genmove:
|
||||||
LOGGER.info("Generating move for:\n" + gameState);
|
LOGGER.info("Generating move for:\n" + gameState);
|
||||||
|
|
||||||
String player = cmd.getStringField(1);
|
String playerName = cmd.getStringField(1);
|
||||||
String nextMove = moveGenerator.getAction(gameConfig, gameState,
|
|
||||||
|
Player player;
|
||||||
|
if ("b".equals(playerName)) {
|
||||||
|
player = Player.BLACK;
|
||||||
|
} else if ("w".equals(playerName)) {
|
||||||
|
player = Player.WHITE;
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("Invalid player name - cannot generator move for:" + cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
Action nextMove = moveGenerator.getAction(gameConfig, gameState,
|
||||||
player);
|
player);
|
||||||
|
|
||||||
gameState.playStone(player, nextMove);
|
gameState.playStone(player, nextMove);
|
||||||
LOGGER.info(new StateEvaluator(gameConfig).scoreGame(gameState));
|
LOGGER.info(new StateEvaluator(gameConfig).scoreGame(gameState));
|
||||||
System.out.println("="
|
System.out.println("="
|
||||||
+ nextMove.toLowerCase() + "\n");
|
+ nextMove.toString() + "\n");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case komi:
|
case komi:
|
||||||
@@ -109,7 +119,7 @@ public class GoGame {
|
|||||||
shutDown = true;
|
shutDown = true;
|
||||||
break;
|
break;
|
||||||
case play:
|
case play:
|
||||||
if (gameState.playStone(cmd.getStringField(1), cmd
|
if (gameState.playStone(Player.getInstance(cmd.getStringField(1)), cmd
|
||||||
.getStringField(2).toUpperCase())) {
|
.getStringField(2).toUpperCase())) {
|
||||||
System.out.println("=\n");
|
System.out.println("=\n");
|
||||||
} else {
|
} else {
|
||||||
@@ -147,4 +157,18 @@ public class GoGame {
|
|||||||
private static void configureLogging() {
|
private static void configureLogging() {
|
||||||
DOMConfigurator.configure("log4j.xml");
|
DOMConfigurator.configure("log4j.xml");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Player getColorToPlay(Player player, boolean playAsOpponent) {
|
||||||
|
if (playAsOpponent) {
|
||||||
|
if (player == Player.WHITE) {
|
||||||
|
return Player.BLACK;
|
||||||
|
} else if (player == Player.BLACK) {
|
||||||
|
return Player.WHITE;
|
||||||
|
} else {
|
||||||
|
return Player.NONE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
38
src/net/woodyfolsom/msproj/Player.java
Normal file
38
src/net/woodyfolsom/msproj/Player.java
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
package net.woodyfolsom.msproj;
|
||||||
|
|
||||||
|
public class Player {
|
||||||
|
public static final Player BLACK = new Player("BLACK", GameBoard.BLACK_STONE);
|
||||||
|
public static final Player NONE = new Player("NONE", GameBoard.EMPTY_INTERSECTION);
|
||||||
|
public static final Player WHITE = new Player("WHITE", GameBoard.WHITE_STONE);
|
||||||
|
|
||||||
|
private char stoneSymbol;
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private Player(String name, char stoneSymbol) {
|
||||||
|
this.name = name;
|
||||||
|
this.stoneSymbol = stoneSymbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Player getInstance(String stoneSymbol) {
|
||||||
|
if ("b".equals(stoneSymbol)) {
|
||||||
|
return Player.BLACK;
|
||||||
|
} else if ("w".equals(stoneSymbol)) {
|
||||||
|
return Player.WHITE;
|
||||||
|
} else {
|
||||||
|
return Player.NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public char getStoneSymbol() {
|
||||||
|
return stoneSymbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isNone() {
|
||||||
|
return "NONE".equals(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,12 +2,14 @@ package net.woodyfolsom.msproj.policy;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
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.Player;
|
||||||
|
|
||||||
public interface ActionGenerator {
|
public interface ActionGenerator {
|
||||||
public static final int ALL_ACTIONS = 0;
|
public static final int ALL_ACTIONS = 0;
|
||||||
|
|
||||||
public List<String> getActions(GameConfig gameConfig, GameState gameState,
|
public List<Action> getActions(GameConfig gameConfig, GameState gameState,
|
||||||
String color, int numActions);
|
Player color, int numActions);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,55 +2,55 @@ package net.woodyfolsom.msproj.policy;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
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.StateEvaluator;
|
import net.woodyfolsom.msproj.StateEvaluator;
|
||||||
|
|
||||||
//import org.apache.log4j.Logger;
|
|
||||||
|
|
||||||
public class AlphaBeta implements Policy {
|
public class AlphaBeta implements Policy {
|
||||||
//private static final Logger LOGGER = Logger.getLogger(AlphaBeta.class
|
private static final int DEFAULT_RECURSIVE_PLAYS = 1;
|
||||||
// .getName());
|
|
||||||
private static final int DEFAULT_RECURSIVE_PLAYS = 3;
|
|
||||||
private final ValidMoveGenerator validMoveGenerator = new ValidMoveGenerator();
|
private final ValidMoveGenerator validMoveGenerator = new ValidMoveGenerator();
|
||||||
|
|
||||||
private String bestPick = Policy.PASS;
|
private Action bestPick = Action.PASS;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getAction(GameConfig gameConfig, GameState gameState,
|
public Action getAction(GameConfig gameConfig, GameState gameState,
|
||||||
String initialColor) {
|
Player player) {
|
||||||
|
|
||||||
int alpha = Integer.MIN_VALUE;
|
int alpha = Integer.MIN_VALUE;
|
||||||
int beta = Integer.MAX_VALUE;
|
int beta = Integer.MAX_VALUE;
|
||||||
|
|
||||||
if ("b".equals(initialColor)) {
|
if (player == Player.BLACK) {
|
||||||
getMaxValue(gameConfig, gameState, initialColor, false,
|
getMaxValue(gameConfig, gameState, player, false,
|
||||||
DEFAULT_RECURSIVE_PLAYS * 2, alpha, beta);
|
DEFAULT_RECURSIVE_PLAYS * 2, alpha, beta);
|
||||||
return bestPick;
|
return bestPick;
|
||||||
} else if ("w".equals(initialColor)) {
|
} else if (player == Player.WHITE) {
|
||||||
getMinValue(gameConfig, gameState, initialColor, false,
|
getMinValue(gameConfig, gameState, player, false,
|
||||||
DEFAULT_RECURSIVE_PLAYS * 2, alpha, beta);
|
DEFAULT_RECURSIVE_PLAYS * 2, alpha, beta);
|
||||||
return bestPick;
|
return bestPick;
|
||||||
} else {
|
} else {
|
||||||
return Policy.PASS;
|
return Action.PASS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getMaxValue(GameConfig gameConfig, GameState gameState,
|
private int getMaxValue(GameConfig gameConfig, GameState gameState,
|
||||||
String initialColor, boolean playAsOpponent, int recursionLevel,
|
Player initialColor, boolean playAsOpponent, int recursionLevel,
|
||||||
int alpha, int beta) {
|
int alpha, int beta) {
|
||||||
if (terminalTest(recursionLevel)) {
|
if (terminalTest(recursionLevel)) {
|
||||||
return getUtility(gameConfig, gameState);
|
return getUtility(gameConfig, gameState);
|
||||||
}
|
}
|
||||||
|
|
||||||
String colorPlaying = getColorToPlay(initialColor, playAsOpponent);
|
Player colorPlaying = GoGame.getColorToPlay(initialColor, playAsOpponent);
|
||||||
|
|
||||||
List<String> validMoves = validMoveGenerator.getActions(gameConfig,
|
List<Action> validMoves = validMoveGenerator.getActions(gameConfig,
|
||||||
gameState, colorPlaying, ActionGenerator.ALL_ACTIONS);
|
gameState, colorPlaying, ActionGenerator.ALL_ACTIONS);
|
||||||
|
|
||||||
int value = Integer.MIN_VALUE;
|
int value = Integer.MIN_VALUE;
|
||||||
|
|
||||||
for (String nextMove : validMoves) {
|
for (Action nextMove : validMoves) {
|
||||||
GameState nextState = new GameState(gameState);
|
GameState nextState = new GameState(gameState);
|
||||||
|
|
||||||
if (!nextState.playStone(colorPlaying, nextMove)) {
|
if (!nextState.playStone(colorPlaying, nextMove)) {
|
||||||
@@ -78,20 +78,20 @@ public class AlphaBeta implements Policy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private int getMinValue(GameConfig gameConfig, GameState gameState,
|
private int getMinValue(GameConfig gameConfig, GameState gameState,
|
||||||
String initialColor, boolean playAsOpponent, int recursionLevel,
|
Player initialColor, boolean playAsOpponent, int recursionLevel,
|
||||||
int alpha, int beta) {
|
int alpha, int beta) {
|
||||||
if (terminalTest(recursionLevel)) {
|
if (terminalTest(recursionLevel)) {
|
||||||
return getUtility(gameConfig, gameState);
|
return getUtility(gameConfig, gameState);
|
||||||
}
|
}
|
||||||
|
|
||||||
String colorPlaying = getColorToPlay(initialColor, playAsOpponent);
|
Player colorPlaying = GoGame.getColorToPlay(initialColor, playAsOpponent);
|
||||||
|
|
||||||
List<String> validMoves = validMoveGenerator.getActions(gameConfig,
|
List<Action> validMoves = validMoveGenerator.getActions(gameConfig,
|
||||||
gameState, colorPlaying, ActionGenerator.ALL_ACTIONS);
|
gameState, colorPlaying, ActionGenerator.ALL_ACTIONS);
|
||||||
|
|
||||||
int value = Integer.MAX_VALUE;
|
int value = Integer.MAX_VALUE;
|
||||||
|
|
||||||
for (String nextMove : validMoves) {
|
for (Action nextMove : validMoves) {
|
||||||
GameState nextState = new GameState(gameState);
|
GameState nextState = new GameState(gameState);
|
||||||
|
|
||||||
if (!nextState.playStone(colorPlaying, nextMove)) {
|
if (!nextState.playStone(colorPlaying, nextMove)) {
|
||||||
@@ -126,19 +126,4 @@ public class AlphaBeta implements Policy {
|
|||||||
StateEvaluator stateEvaluator = new StateEvaluator(gameConfig);
|
StateEvaluator stateEvaluator = new StateEvaluator(gameConfig);
|
||||||
return stateEvaluator.scoreGame(gameState).getAggregateScore();
|
return stateEvaluator.scoreGame(gameState).getAggregateScore();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getColorToPlay(String color, boolean playAsOpponent) {
|
|
||||||
if (playAsOpponent) {
|
|
||||||
if ("w".equals(color)) {
|
|
||||||
return "b";
|
|
||||||
} else if ("b".equals(color)) {
|
|
||||||
return "w";
|
|
||||||
} else {
|
|
||||||
return "?"; // invalid color will cause randomMoveGenerator to
|
|
||||||
// PASS
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -4,57 +4,66 @@ import java.util.HashMap;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import net.woodyfolsom.msproj.GameConfig;
|
import net.woodyfolsom.msproj.Action;
|
||||||
import net.woodyfolsom.msproj.GameState;
|
import net.woodyfolsom.msproj.GameState;
|
||||||
|
|
||||||
public abstract class GameTreeNode {
|
public class GameTreeNode {
|
||||||
private GameConfig gameConfig;
|
|
||||||
private GameState gameState;
|
private GameState gameState;
|
||||||
private GameTreeNode parent;
|
private GameTreeNode parent;
|
||||||
private Map<String, GameTreeNode> children = new HashMap<String, GameTreeNode>();
|
private int numVisits;
|
||||||
private String player;
|
private int numWins;
|
||||||
|
private Map<Action, GameTreeNode> children = new HashMap<Action, GameTreeNode>();
|
||||||
|
|
||||||
public GameTreeNode(GameConfig gameConfig, GameState gameState,
|
public GameTreeNode(GameState gameState) {
|
||||||
String player) {
|
|
||||||
this.gameConfig = gameConfig;
|
|
||||||
this.gameState = gameState;
|
this.gameState = gameState;
|
||||||
this.player = player;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addChild(String action, GameTreeNode child) {
|
public void addChild(Action action, GameTreeNode child) {
|
||||||
children.put(action, child);
|
children.put(action, child);
|
||||||
child.parent = this;
|
child.parent = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<String> getActions() {
|
public Set<Action> getActions() {
|
||||||
return children.keySet();
|
return children.keySet();
|
||||||
}
|
}
|
||||||
|
|
||||||
public GameTreeNode getChild(String action) {
|
public GameTreeNode getChild(Action action) {
|
||||||
return children.get(action);
|
return children.get(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getChildrenSize() {
|
public int getNumChildren() {
|
||||||
return children.size();
|
return children.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public GameConfig getGameConfig() {
|
|
||||||
return gameConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
public GameState getGameState() {
|
public GameState getGameState() {
|
||||||
return gameState;
|
return gameState;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GameTreeNode getParent() {
|
public int getNumVisits() {
|
||||||
return parent;
|
return numVisits;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPlayer() {
|
public int getNumWins() {
|
||||||
return player;
|
return numWins;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GameTreeNode getParent() {
|
||||||
|
return parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isRoot() {
|
public boolean isRoot() {
|
||||||
return parent == null;
|
return parent == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isTerminal() {
|
||||||
|
return children.size() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void incrementVisits() {
|
||||||
|
numVisits++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void incrementWins() {
|
||||||
|
numWins++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,47 +1,44 @@
|
|||||||
package net.woodyfolsom.msproj.policy;
|
package net.woodyfolsom.msproj.policy;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
//import java.util.Arrays;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.woodyfolsom.msproj.Action;
|
||||||
import net.woodyfolsom.msproj.GameConfig;
|
import net.woodyfolsom.msproj.GameConfig;
|
||||||
import net.woodyfolsom.msproj.GameScore;
|
import net.woodyfolsom.msproj.GameScore;
|
||||||
import net.woodyfolsom.msproj.GameState;
|
import net.woodyfolsom.msproj.GameState;
|
||||||
|
import net.woodyfolsom.msproj.GoGame;
|
||||||
|
import net.woodyfolsom.msproj.Player;
|
||||||
import net.woodyfolsom.msproj.StateEvaluator;
|
import net.woodyfolsom.msproj.StateEvaluator;
|
||||||
|
|
||||||
//import org.apache.log4j.Logger;
|
|
||||||
|
|
||||||
|
|
||||||
public class Minimax implements Policy {
|
public class Minimax implements Policy {
|
||||||
//private static final Logger LOGGER = Logger.getLogger(Minimax.class.getName());
|
|
||||||
|
|
||||||
private static final int DEFAULT_RECURSIVE_PLAYS = 1;
|
private static final int DEFAULT_RECURSIVE_PLAYS = 1;
|
||||||
|
|
||||||
private final ValidMoveGenerator validMoveGenerator = new ValidMoveGenerator();
|
private final ValidMoveGenerator validMoveGenerator = new ValidMoveGenerator();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getAction(GameConfig gameConfig, GameState gameState,
|
public Action getAction(GameConfig gameConfig, GameState gameState,
|
||||||
String color) {
|
Player color) {
|
||||||
MoveCandidate moveCandidate = findBestMinimaxResult(
|
MoveCandidate moveCandidate = findBestMinimaxResult(
|
||||||
DEFAULT_RECURSIVE_PLAYS * 2,
|
DEFAULT_RECURSIVE_PLAYS * 2,
|
||||||
gameConfig, gameState, color, false, Policy.PASS);
|
gameConfig, gameState, color, false, Action.PASS);
|
||||||
|
|
||||||
return moveCandidate.move;
|
return moveCandidate.move;
|
||||||
}
|
}
|
||||||
|
|
||||||
private MoveCandidate findBestMinimaxResult(int recursionLevels,
|
private MoveCandidate findBestMinimaxResult(int recursionLevels,
|
||||||
GameConfig gameConfig, GameState gameState,
|
GameConfig gameConfig, GameState gameState,
|
||||||
String initialColor, boolean playAsOpponent, String bestPrevMove) {
|
Player initialColor, boolean playAsOpponent, Action bestPrevMove) {
|
||||||
|
|
||||||
StateEvaluator stateEvaluator = new StateEvaluator(gameConfig);
|
StateEvaluator stateEvaluator = new StateEvaluator(gameConfig);
|
||||||
List<MoveCandidate> randomMoveCandidates = new ArrayList<MoveCandidate>();
|
List<MoveCandidate> randomMoveCandidates = new ArrayList<MoveCandidate>();
|
||||||
|
|
||||||
String colorPlaying = getColorToPlay(initialColor, playAsOpponent);
|
Player colorPlaying = GoGame.getColorToPlay(initialColor, playAsOpponent);
|
||||||
|
|
||||||
List<String> validMoves = validMoveGenerator.getActions(gameConfig,
|
List<Action> validMoves = validMoveGenerator.getActions(gameConfig,
|
||||||
gameState, colorPlaying, ActionGenerator.ALL_ACTIONS);
|
gameState, colorPlaying, ActionGenerator.ALL_ACTIONS);
|
||||||
|
|
||||||
for (String randomMove : validMoves) {
|
for (Action randomMove : validMoves) {
|
||||||
GameState stateCopy = new GameState(gameState);
|
GameState stateCopy = new GameState(gameState);
|
||||||
stateCopy.playStone(colorPlaying, randomMove);
|
stateCopy.playStone(colorPlaying, randomMove);
|
||||||
if (recursionLevels > 1) {
|
if (recursionLevels > 1) {
|
||||||
@@ -77,19 +74,4 @@ public class Minimax implements Policy {
|
|||||||
return bestMove;
|
return bestMove;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getColorToPlay(String color, boolean playAsOpponent) {
|
|
||||||
if (playAsOpponent) {
|
|
||||||
if ("w".equals(color)) {
|
|
||||||
return "b";
|
|
||||||
} else if ("b".equals(color)) {
|
|
||||||
return "w";
|
|
||||||
} else {
|
|
||||||
return "?"; // invalid color will cause randomMoveGenerator to
|
|
||||||
// PASS
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,61 +1,81 @@
|
|||||||
package net.woodyfolsom.msproj.policy;
|
package net.woodyfolsom.msproj.policy;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
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.Player;
|
||||||
|
|
||||||
public abstract class MonteCarlo implements Policy {
|
public abstract class MonteCarlo implements Policy {
|
||||||
protected Policy movePolicy;
|
protected Policy movePolicy;
|
||||||
protected long searchTimeLimit;
|
protected long searchTimeLimit;
|
||||||
|
protected volatile long elapsedTime = 0L;
|
||||||
|
|
||||||
public MonteCarlo(Policy movePolicy, long searchTimeLimit) {
|
public MonteCarlo(Policy movePolicy, long searchTimeLimit) {
|
||||||
this.movePolicy = movePolicy;
|
this.movePolicy = movePolicy;
|
||||||
this.searchTimeLimit = searchTimeLimit;
|
this.searchTimeLimit = searchTimeLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract MonteCarloTreeNode descend(MonteCarloTreeNode node);
|
/**
|
||||||
|
* Descend the tree from the specified node and return a list of nodes to grow.
|
||||||
|
*
|
||||||
|
* @param node
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public abstract List<GameTreeNode> descend(GameTreeNode node);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getAction(GameConfig gameConfig, GameState gameState,
|
public Action getAction(GameConfig gameConfig, GameState gameState,
|
||||||
String initialColor) {
|
Player initialColor) {
|
||||||
long initialTime = System.currentTimeMillis();
|
long startTime = System.currentTimeMillis();
|
||||||
|
|
||||||
//If for some reason no moves are evaluated within the time limit, pass.
|
//If for some reason no moves are evaluated within the time limit, pass.
|
||||||
//Note that this may lose the game by forfeit even when picking any random move could
|
//Note that this may lose the game by forfeit even when picking any random move could
|
||||||
//result in a win.
|
//result in a win.
|
||||||
|
|
||||||
String bestMove = Policy.PASS;
|
GameTreeNode rootNode = new GameTreeNode(gameState);
|
||||||
|
|
||||||
MonteCarloTreeNode rootNode = new MonteCarloTreeNode(gameConfig, gameState, initialColor);
|
do {
|
||||||
MonteCarloTreeNode selectedNode;
|
|
||||||
while (System.currentTimeMillis() - initialTime < searchTimeLimit) {
|
|
||||||
//TODO these return types may need to be lists for some MC methods
|
//TODO these return types may need to be lists for some MC methods
|
||||||
selectedNode = descend(rootNode);
|
List<GameTreeNode> selectedNodes = descend(rootNode);
|
||||||
selectedNode = grow(selectedNode);
|
List<GameTreeNode> newLeaves = new ArrayList<GameTreeNode>();
|
||||||
int reward = rollout(selectedNode);
|
|
||||||
update(selectedNode, reward);
|
for (GameTreeNode selectedNode: selectedNodes) {
|
||||||
}
|
for (GameTreeNode newLeaf : grow(selectedNode)) {
|
||||||
|
newLeaves.add(newLeaf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (GameTreeNode newLeaf : newLeaves) {
|
||||||
|
int reward = rollout(newLeaf);
|
||||||
|
update(newLeaf, reward);
|
||||||
|
}
|
||||||
|
|
||||||
|
elapsedTime = System.currentTimeMillis() - startTime;
|
||||||
|
} while (elapsedTime < searchTimeLimit);
|
||||||
|
|
||||||
return bestMove;
|
return getBestAction(rootNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract MonteCarloTreeNode grow(MonteCarloTreeNode node);
|
public long getElapsedTime() {
|
||||||
|
return elapsedTime;
|
||||||
|
}
|
||||||
|
|
||||||
public abstract int rollout(MonteCarloTreeNode node);
|
public abstract Action getBestAction(GameTreeNode node);
|
||||||
|
|
||||||
public abstract void update(MonteCarloTreeNode node, int reward);
|
public abstract List<GameTreeNode> grow(GameTreeNode node);
|
||||||
|
|
||||||
static String getColorToPlay(String color, boolean playAsOpponent) {
|
public abstract int rollout(GameTreeNode node);
|
||||||
if (playAsOpponent) {
|
|
||||||
if ("w".equals(color)) {
|
public abstract void update(GameTreeNode node, int reward);
|
||||||
return "b";
|
|
||||||
} else if ("b".equals(color)) {
|
public long getSearchTimeLimit() {
|
||||||
return "w";
|
return searchTimeLimit;
|
||||||
} else {
|
}
|
||||||
return "?"; // invalid color will cause randomMoveGenerator to
|
|
||||||
// PASS
|
public int doRollout() {
|
||||||
}
|
return 0;
|
||||||
} else {
|
|
||||||
return color;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
package net.woodyfolsom.msproj.policy;
|
|
||||||
|
|
||||||
import net.woodyfolsom.msproj.GameConfig;
|
|
||||||
import net.woodyfolsom.msproj.GameState;
|
|
||||||
|
|
||||||
public class MonteCarloTreeNode extends GameTreeNode {
|
|
||||||
private int numVisits;
|
|
||||||
private int numWins;
|
|
||||||
|
|
||||||
public MonteCarloTreeNode(GameConfig gameConfig, GameState gameState,
|
|
||||||
String player) {
|
|
||||||
super(gameConfig, gameState, player);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getNumVisits() {
|
|
||||||
return numVisits;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setNumVisits(int numVisits) {
|
|
||||||
this.numVisits = numVisits;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getNumWins() {
|
|
||||||
return numWins;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setNumWins(int numWins) {
|
|
||||||
this.numWins = numWins;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,9 @@
|
|||||||
package net.woodyfolsom.msproj.policy;
|
package net.woodyfolsom.msproj.policy;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.woodyfolsom.msproj.Action;
|
||||||
|
|
||||||
public class MonteCarloUCT extends MonteCarlo {
|
public class MonteCarloUCT extends MonteCarlo {
|
||||||
|
|
||||||
@@ -8,27 +12,65 @@ public class MonteCarloUCT extends MonteCarlo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MonteCarloTreeNode descend(MonteCarloTreeNode node) {
|
public List<GameTreeNode> descend(GameTreeNode node) {
|
||||||
|
double bestScore = (double) node.getNumWins() / node.getNumVisits();
|
||||||
|
GameTreeNode bestNode = node;
|
||||||
|
|
||||||
|
//This appears slightly redundant with getBestAction() but it is not -
|
||||||
|
//descend() may pick the current node rather than a child to expand (if a child has a good score but high/low uncertainty)
|
||||||
|
//but getBestAction specifically asks for the optimum action to take from the current node,
|
||||||
|
//even if it results in a worse next state.
|
||||||
|
for (Action action : node.getActions()) {
|
||||||
|
GameTreeNode childNode = node.getChild(action);
|
||||||
|
double childScore = (double) childNode.getNumWins() / childNode.getNumVisits();
|
||||||
|
if (childScore >= bestScore) {
|
||||||
|
bestScore = childScore;
|
||||||
|
bestNode = childNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bestNode == node) {
|
||||||
|
List<GameTreeNode> bestNodeList = new ArrayList<GameTreeNode>();
|
||||||
|
bestNodeList.add(bestNode);
|
||||||
|
return bestNodeList;
|
||||||
|
} else {
|
||||||
|
return descend(bestNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Action getBestAction(GameTreeNode node) {
|
||||||
|
Action bestAction = Action.NONE;
|
||||||
|
double bestScore = Double.NEGATIVE_INFINITY;
|
||||||
|
|
||||||
|
for (Action action : node.getActions()) {
|
||||||
|
GameTreeNode childNode = node.getChild(action);
|
||||||
|
double childScore = (double) childNode.getNumWins() / childNode.getNumVisits();
|
||||||
|
if (childScore >= bestScore) {
|
||||||
|
bestScore = childScore;
|
||||||
|
bestAction = action;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bestAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<GameTreeNode> grow(GameTreeNode node) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MonteCarloTreeNode grow(MonteCarloTreeNode node) {
|
public int rollout(GameTreeNode node) {
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int rollout(MonteCarloTreeNode node) {
|
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(MonteCarloTreeNode node, int reward) {
|
public void update(GameTreeNode node, int reward) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,13 @@
|
|||||||
package net.woodyfolsom.msproj.policy;
|
package net.woodyfolsom.msproj.policy;
|
||||||
|
|
||||||
|
import net.woodyfolsom.msproj.Action;
|
||||||
import net.woodyfolsom.msproj.GameScore;
|
import net.woodyfolsom.msproj.GameScore;
|
||||||
|
|
||||||
public class MoveCandidate {
|
public class MoveCandidate {
|
||||||
public final String move;
|
public final Action move;
|
||||||
public final GameScore score;
|
public final GameScore score;
|
||||||
|
|
||||||
public MoveCandidate(String move, GameScore score) {
|
public MoveCandidate(Action move, GameScore score) {
|
||||||
this.move = move;
|
this.move = move;
|
||||||
this.score = score;
|
this.score = score;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
package net.woodyfolsom.msproj.policy;
|
package net.woodyfolsom.msproj.policy;
|
||||||
|
|
||||||
|
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.Player;
|
||||||
|
|
||||||
|
|
||||||
public interface Policy {
|
public interface Policy {
|
||||||
static final String PASS = "PASS";
|
public Action getAction(GameConfig gameConfig, GameState gameState, Player player);
|
||||||
public String getAction(GameConfig gameConfig, GameState gameState, String color);
|
|
||||||
}
|
}
|
||||||
@@ -3,8 +3,10 @@ package net.woodyfolsom.msproj.policy;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
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.Player;
|
||||||
|
|
||||||
|
|
||||||
public class RandomMovePolicy implements Policy {
|
public class RandomMovePolicy implements Policy {
|
||||||
@@ -12,14 +14,15 @@ public class RandomMovePolicy implements Policy {
|
|||||||
/**
|
/**
|
||||||
* Does NOT modify the gameState.
|
* Does NOT modify the gameState.
|
||||||
*/
|
*/
|
||||||
public String getAction(GameConfig gameConfig, GameState gameState,
|
public Action getAction(GameConfig gameConfig, GameState gameState,
|
||||||
String color) {
|
Player color) {
|
||||||
GameState gameStateCopy = new GameState(gameState);
|
GameState gameStateCopy = new GameState(gameState);
|
||||||
List<String> emptyCoordinates = gameStateCopy.getEmptyCoords();
|
List<String> emptyCoordinates = gameStateCopy.getEmptyCoords();
|
||||||
|
|
||||||
while (emptyCoordinates.size() > 0) {
|
while (emptyCoordinates.size() > 0) {
|
||||||
String randomMove = emptyCoordinates
|
Action randomMove = Action.getInstance(emptyCoordinates
|
||||||
.get((int) (Math.random() * emptyCoordinates.size()));
|
.get((int) (Math.random() * emptyCoordinates.size())));
|
||||||
|
|
||||||
if (gameStateCopy.playStone(color, randomMove)) {
|
if (gameStateCopy.playStone(color, randomMove)) {
|
||||||
return randomMove;
|
return randomMove;
|
||||||
} else {
|
} else {
|
||||||
@@ -27,7 +30,7 @@ public class RandomMovePolicy implements Policy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return PASS;
|
return Action.PASS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -42,15 +45,15 @@ public class RandomMovePolicy implements Policy {
|
|||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public List<String> genMoves(GameConfig gameConfig, GameState gameState,
|
public List<Action> genMoves(GameConfig gameConfig, GameState gameState,
|
||||||
String color, int nMoves) {
|
Player color, int nMoves) {
|
||||||
GameState gameStateCopy = new GameState(gameState);
|
GameState gameStateCopy = new GameState(gameState);
|
||||||
List<String> emptyCoordinates = gameStateCopy.getEmptyCoords();
|
List<String> emptyCoordinates = gameStateCopy.getEmptyCoords();
|
||||||
List<String> randomMoves = new ArrayList<String>();
|
List<Action> randomMoves = new ArrayList<Action>();
|
||||||
|
|
||||||
while (emptyCoordinates.size() > 0 && randomMoves.size() < nMoves) {
|
while (emptyCoordinates.size() > 0 && randomMoves.size() < nMoves) {
|
||||||
String randomMove = emptyCoordinates
|
Action randomMove = Action.getInstance(emptyCoordinates
|
||||||
.get((int) (Math.random() * emptyCoordinates.size()));
|
.get((int) (Math.random() * emptyCoordinates.size())));
|
||||||
if (gameStateCopy.playStone(color, randomMove)) {
|
if (gameStateCopy.playStone(color, randomMove)) {
|
||||||
randomMoves.add(randomMove);
|
randomMoves.add(randomMove);
|
||||||
}
|
}
|
||||||
@@ -58,7 +61,7 @@ public class RandomMovePolicy implements Policy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (randomMoves.size() == 0) {
|
if (randomMoves.size() == 0) {
|
||||||
randomMoves.add(PASS);
|
randomMoves.add(Action.PASS);
|
||||||
}
|
}
|
||||||
|
|
||||||
return randomMoves;
|
return randomMoves;
|
||||||
|
|||||||
@@ -3,8 +3,10 @@ package net.woodyfolsom.msproj.policy;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
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.Player;
|
||||||
|
|
||||||
//import org.apache.log4j.Logger;
|
//import org.apache.log4j.Logger;
|
||||||
|
|
||||||
@@ -12,23 +14,24 @@ public class ValidMoveGenerator implements ActionGenerator {
|
|||||||
//private static final Logger LOGGER = Logger.getLogger(ValidMoveGenerator.class.getName());
|
//private static final Logger LOGGER = Logger.getLogger(ValidMoveGenerator.class.getName());
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getActions(GameConfig gameConfig, GameState gameState,
|
public List<Action> getActions(GameConfig gameConfig, GameState gameState,
|
||||||
String color, int nMoves) {
|
Player color, int nMoves) {
|
||||||
|
|
||||||
GameState gameStateCopy = new GameState(gameState);
|
GameState gameStateCopy = new GameState(gameState);
|
||||||
List<String> emptyCoordinates = gameStateCopy.getEmptyCoords();
|
List<String> emptyCoordinates = gameStateCopy.getEmptyCoords();
|
||||||
List<String> validMoves = new ArrayList<String>();
|
List<Action> validMoves = new ArrayList<Action>();
|
||||||
|
|
||||||
while (emptyCoordinates.size() > 0) {
|
while (emptyCoordinates.size() > 0) {
|
||||||
String nextMove = emptyCoordinates.remove(emptyCoordinates.size()-1);
|
Action nextMove = Action.getInstance(emptyCoordinates.remove(emptyCoordinates.size()-1));
|
||||||
if (gameStateCopy.playStone(color, nextMove)) {
|
if (gameStateCopy.playStone(color, nextMove)) {
|
||||||
validMoves.add(nextMove);
|
validMoves.add(nextMove);
|
||||||
gameStateCopy = new GameState(gameState); // play successful? regenerate copy of gameState
|
gameStateCopy = new GameState(gameState); // play successful? regenerate copy of gameState
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Passing is always a VALID move. It may not be a GOOD move.
|
||||||
if (validMoves.size() == 0) {
|
if (validMoves.size() == 0) {
|
||||||
validMoves.add(Policy.PASS);
|
validMoves.add(Action.PASS);
|
||||||
}
|
}
|
||||||
|
|
||||||
return validMoves;
|
return validMoves;
|
||||||
|
|||||||
@@ -4,27 +4,21 @@ import static org.junit.Assert.assertEquals;
|
|||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import net.woodyfolsom.msproj.GameBoard;
|
|
||||||
import net.woodyfolsom.msproj.GameConfig;
|
|
||||||
import net.woodyfolsom.msproj.GameScore;
|
|
||||||
import net.woodyfolsom.msproj.GameState;
|
|
||||||
import net.woodyfolsom.msproj.StateEvaluator;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class CaptureTest {
|
public class CaptureTest {
|
||||||
@Test
|
@Test
|
||||||
public void testCapture() {
|
public void testCapture() {
|
||||||
GameState gameState = new GameState(5);
|
GameState gameState = new GameState(5);
|
||||||
gameState.playStone('A', 2, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("A2"));
|
||||||
gameState.playStone('B', 3, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("B3"));
|
||||||
gameState.playStone('B', 1, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("B1"));
|
||||||
assertTrue(gameState.playStone('B', 2, GameBoard.WHITE_STONE));
|
assertTrue(gameState.playStone(Player.WHITE, Action.getInstance("B2")));
|
||||||
|
|
||||||
assertEquals(0,gameState.getBlackPrisoners());
|
assertEquals(0,gameState.getBlackPrisoners());
|
||||||
assertEquals(0,gameState.getWhitePrisoners());
|
assertEquals(0,gameState.getWhitePrisoners());
|
||||||
|
|
||||||
assertTrue(gameState.playStone('C', 2, GameBoard.BLACK_STONE));
|
assertTrue(gameState.playStone(Player.BLACK, Action.getInstance("C2")));
|
||||||
|
|
||||||
assertEquals(1,gameState.getBlackPrisoners());
|
assertEquals(1,gameState.getBlackPrisoners());
|
||||||
assertEquals(0,gameState.getWhitePrisoners());
|
assertEquals(0,gameState.getWhitePrisoners());
|
||||||
@@ -37,25 +31,25 @@ public class CaptureTest {
|
|||||||
GameConfig gameConfig = new GameConfig();
|
GameConfig gameConfig = new GameConfig();
|
||||||
GameState gameState = new GameState(5);
|
GameState gameState = new GameState(5);
|
||||||
|
|
||||||
gameState.playStone('A', 2, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("A2"));
|
||||||
gameState.playStone('B', 3, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("B3"));
|
||||||
gameState.playStone('B', 1, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("B1"));
|
||||||
gameState.playStone('C', 4, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("C4"));
|
||||||
gameState.playStone('D', 3, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("D3"));
|
||||||
|
|
||||||
assertTrue(gameState.playStone('B', 2, GameBoard.WHITE_STONE));
|
assertTrue(gameState.playStone(Player.WHITE, Action.getInstance("B2")));
|
||||||
assertTrue(gameState.playStone('C', 3, GameBoard.WHITE_STONE));
|
assertTrue(gameState.playStone(Player.WHITE, Action.getInstance("C3")));
|
||||||
|
|
||||||
assertEquals(0,gameState.getBlackPrisoners());
|
assertEquals(0,gameState.getBlackPrisoners());
|
||||||
assertEquals(0,gameState.getWhitePrisoners());
|
assertEquals(0,gameState.getWhitePrisoners());
|
||||||
|
|
||||||
assertTrue(gameState.playStone('C', 2, GameBoard.BLACK_STONE));
|
assertTrue(gameState.playStone(Player.BLACK, Action.getInstance("C2")));
|
||||||
|
|
||||||
assertEquals(2,gameState.getBlackPrisoners());
|
assertEquals(2,gameState.getBlackPrisoners());
|
||||||
assertEquals(0,gameState.getWhitePrisoners());
|
assertEquals(0,gameState.getWhitePrisoners());
|
||||||
|
|
||||||
assertFalse(gameState.playStone('B', 2, GameBoard.WHITE_STONE));
|
assertFalse(gameState.playStone(Player.WHITE, Action.getInstance("B2")));
|
||||||
assertFalse(gameState.playStone('C', 3, GameBoard.WHITE_STONE));
|
assertFalse(gameState.playStone(Player.WHITE, Action.getInstance("C3")));
|
||||||
|
|
||||||
System.out.println(gameState);
|
System.out.println(gameState);
|
||||||
|
|
||||||
@@ -67,20 +61,21 @@ public class CaptureTest {
|
|||||||
public void testCaptureFromEye() {
|
public void testCaptureFromEye() {
|
||||||
GameState gameState = new GameState(5);
|
GameState gameState = new GameState(5);
|
||||||
|
|
||||||
gameState.playStone('A', 1, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("A1"));
|
||||||
gameState.playStone('B', 2, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("B2"));
|
||||||
gameState.playStone('C', 1, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("C1"));
|
||||||
gameState.playStone('A', 2, GameBoard.WHITE_STONE);
|
gameState.playStone(Player.WHITE, Action.getInstance("A2"));
|
||||||
gameState.playStone('B', 3, GameBoard.WHITE_STONE);
|
gameState.playStone(Player.WHITE, Action.getInstance("B3"));
|
||||||
gameState.playStone('C', 2, GameBoard.WHITE_STONE);
|
gameState.playStone(Player.WHITE, Action.getInstance("C2"));
|
||||||
|
|
||||||
//This capture should be allowed.
|
//This capture should be allowed.
|
||||||
assertTrue("Capture from within single eye should have been allowed but move was rejected.",
|
System.out.println("State before WHITE move: ");
|
||||||
gameState.playStone('B', 1, GameBoard.WHITE_STONE));
|
|
||||||
|
|
||||||
assertEquals(0,gameState.getBlackPrisoners());
|
|
||||||
assertEquals(2,gameState.getWhitePrisoners());
|
|
||||||
|
|
||||||
System.out.println(gameState);
|
System.out.println(gameState);
|
||||||
|
|
||||||
|
assertTrue("Capture from within single eye should have been allowed but move was rejected.",
|
||||||
|
gameState.playStone(Player.WHITE, Action.getInstance("B1")));
|
||||||
|
|
||||||
|
assertEquals("BLACK should have 0 prisoners.",0,gameState.getBlackPrisoners());
|
||||||
|
assertEquals("WHITE should have 2 prisoners.",2,gameState.getWhitePrisoners());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,9 +3,6 @@ package net.woodyfolsom.msproj;
|
|||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import net.woodyfolsom.msproj.GameBoard;
|
|
||||||
import net.woodyfolsom.msproj.GameState;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class IllegalMoveTest {
|
public class IllegalMoveTest {
|
||||||
@@ -13,53 +10,57 @@ public class IllegalMoveTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testIllegalMoveOnOwnStone() {
|
public void testIllegalMoveOnOwnStone() {
|
||||||
GameState gameState = new GameState(5);
|
GameState gameState = new GameState(5);
|
||||||
gameState.playStone('B', 3, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("B3"));
|
||||||
assertFalse(gameState.playStone('B', 3, GameBoard.BLACK_STONE));
|
assertFalse(gameState.playStone(Player.BLACK, Action.getInstance("B3")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIllegalMoveOnOtherStone() {
|
public void testIllegalMoveOnOtherStone() {
|
||||||
GameState gameState = new GameState(5);
|
GameState gameState = new GameState(5);
|
||||||
gameState.playStone('B', 3, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("B3"));
|
||||||
assertFalse(gameState.playStone('B', 3, GameBoard.WHITE_STONE));
|
assertFalse(gameState.playStone(Player.WHITE, Action.getInstance("B3")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIllegalMoveNoLiberties() {
|
public void testIllegalMoveNoLiberties() {
|
||||||
GameState gameState = new GameState(5);
|
GameState gameState = new GameState(5);
|
||||||
gameState.playStone('A', 2, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("A2"));
|
||||||
gameState.playStone('B', 3, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("B1"));
|
||||||
gameState.playStone('B', 1, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("B3"));
|
||||||
gameState.playStone('C', 2, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("C2"));
|
||||||
assertFalse(gameState.playStone('B', 2, GameBoard.WHITE_STONE));
|
System.out.println(gameState);
|
||||||
|
assertFalse(gameState.playStone(Player.WHITE, Action.getInstance("B2")));
|
||||||
System.out.println(gameState);
|
System.out.println(gameState);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIllegalMoveFormsTrappedGroup() {
|
public void testIllegalMoveFormsTrappedGroup() {
|
||||||
GameState gameState = new GameState(9);
|
GameState gameState = new GameState(9);
|
||||||
gameState.playStone('A', 5, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("A5"));
|
||||||
gameState.playStone('B', 6, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("B6"));
|
||||||
gameState.playStone('B', 7, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("B7"));
|
||||||
gameState.playStone('A', 8, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("A8"));
|
||||||
assertTrue(gameState.playStone('A', 6, GameBoard.WHITE_STONE));
|
assertTrue(gameState.playStone(Player.WHITE, Action.getInstance("A6")));
|
||||||
assertFalse(gameState.playStone('A', 7, GameBoard.WHITE_STONE));
|
assertFalse(gameState.playStone(Player.WHITE, Action.getInstance("A7")));
|
||||||
System.out.println(gameState);
|
System.out.println(gameState);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIllegalMoveFormsTrappedGroup2() {
|
public void testIllegalMoveFormsTrappedGroup2() {
|
||||||
GameState gameState = new GameState(9);
|
GameState gameState = new GameState(9);
|
||||||
gameState.playStone('G', 1, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("G1"));
|
||||||
gameState.playStone('H', 2, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("H2"));
|
||||||
gameState.playStone('H', 3, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("H3"));
|
||||||
gameState.playStone('J', 4, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("J4"));
|
||||||
gameState.playStone('A', 8, GameBoard.BLACK_STONE);
|
|
||||||
assertTrue(gameState.playStone('H', 1, GameBoard.WHITE_STONE));
|
gameState.playStone(Player.BLACK, Action.getInstance("A8"));
|
||||||
assertTrue(gameState.playStone('J', 2, GameBoard.WHITE_STONE));
|
|
||||||
assertTrue(gameState.playStone('J', 3, GameBoard.WHITE_STONE));
|
assertTrue(gameState.playStone(Player.WHITE, Action.getInstance("H1")));
|
||||||
System.out.println(gameState);
|
assertTrue(gameState.playStone(Player.WHITE, Action.getInstance("J2")));
|
||||||
assertFalse(gameState.playStone('J', 1, GameBoard.WHITE_STONE));
|
assertTrue(gameState.playStone(Player.WHITE, Action.getInstance("J3")));
|
||||||
|
|
||||||
|
System.out.println("State before move: ");
|
||||||
System.out.println(gameState);
|
System.out.println(gameState);
|
||||||
|
assertFalse("Play by WHITE at J1 should have failed.",gameState.playStone(Player.WHITE, Action.getInstance("J1")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,19 +2,16 @@ package net.woodyfolsom.msproj;
|
|||||||
|
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import net.woodyfolsom.msproj.GameBoard;
|
|
||||||
import net.woodyfolsom.msproj.GameState;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class LegalMoveTest {
|
public class LegalMoveTest {
|
||||||
@Test
|
@Test
|
||||||
public void testLegalMove1Liberty() {
|
public void testLegalMove1Liberty() {
|
||||||
GameState gameState = new GameState(5);
|
GameState gameState = new GameState(5);
|
||||||
gameState.playStone('A', 2, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("A2"));
|
||||||
gameState.playStone('B', 3, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("B3"));
|
||||||
gameState.playStone('B', 1, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("B1"));
|
||||||
assertTrue(gameState.playStone('B', 2, GameBoard.WHITE_STONE));
|
assertTrue(gameState.playStone(Player.WHITE, Action.getInstance("B2")));
|
||||||
System.out.println(gameState);
|
System.out.println(gameState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,98 +3,96 @@ package net.woodyfolsom.msproj;
|
|||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import net.woodyfolsom.msproj.GameBoard;
|
|
||||||
import net.woodyfolsom.msproj.GameConfig;
|
|
||||||
import net.woodyfolsom.msproj.GameScore;
|
|
||||||
import net.woodyfolsom.msproj.GameState;
|
|
||||||
import net.woodyfolsom.msproj.StateEvaluator;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
|
||||||
public class StateEvaluatorTest {
|
public class StateEvaluatorTest {
|
||||||
GameConfig gameConfig = new GameConfig();
|
GameConfig gameConfig = new GameConfig();
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testScoreEmptyBoard() {
|
public void testScoreEmptyBoard() {
|
||||||
GameState gameState = new GameState(5);
|
GameState gameState = new GameState(5);
|
||||||
GameScore gameScore = new StateEvaluator(gameConfig).scoreGame(gameState);
|
GameScore gameScore = new StateEvaluator(gameConfig)
|
||||||
|
.scoreGame(gameState);
|
||||||
assertEquals(0.0,gameScore.getWhiteScore(),0.5);
|
|
||||||
assertEquals(0.0,gameScore.getBlackScore(),0.5);
|
assertEquals(0.0, gameScore.getWhiteScore(), 0.5);
|
||||||
|
assertEquals(0.0, gameScore.getBlackScore(), 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testScoreFirstMove() {
|
public void testScoreFirstMove() {
|
||||||
GameState gameState = new GameState(5);
|
GameState gameState = new GameState(5);
|
||||||
gameState.playStone('B',3,GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("B3"));
|
||||||
|
|
||||||
GameScore gameScore = new StateEvaluator(gameConfig).scoreGame(gameState);
|
GameScore gameScore = new StateEvaluator(gameConfig)
|
||||||
|
.scoreGame(gameState);
|
||||||
|
|
||||||
System.out.println(gameScore.getScoreReport());
|
System.out.println(gameScore.getScoreReport());
|
||||||
|
|
||||||
assertEquals(0.0,gameScore.getWhiteScore(),0.5);
|
assertEquals(0.0, gameScore.getWhiteScore(), 0.5);
|
||||||
assertEquals(25.0,gameScore.getBlackScore(),0.5);
|
assertEquals(25.0, gameScore.getBlackScore(), 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testScoreTiedAtMove2() {
|
public void testScoreTiedAtMove2() {
|
||||||
GameState gameState = new GameState(5);
|
GameState gameState = new GameState(5);
|
||||||
|
|
||||||
gameState.playStone('B',3,GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("B3"));
|
||||||
gameState.playStone('A',1,GameBoard.WHITE_STONE);
|
gameState.playStone(Player.WHITE, Action.getInstance("A1"));
|
||||||
GameScore gameScore = new StateEvaluator(gameConfig).scoreGame(gameState);
|
GameScore gameScore = new StateEvaluator(gameConfig)
|
||||||
|
.scoreGame(gameState);
|
||||||
|
|
||||||
System.out.println(gameScore.getScoreReport());
|
System.out.println(gameScore.getScoreReport());
|
||||||
|
|
||||||
assertEquals(1.0,gameScore.getWhiteScore(),0.5);
|
assertEquals(1.0, gameScore.getWhiteScore(), 0.5);
|
||||||
assertEquals(1.0,gameScore.getBlackScore(),0.5);
|
assertEquals(1.0, gameScore.getBlackScore(), 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testScoreTerritory() {
|
public void testScoreTerritory() {
|
||||||
GameState gameState = new GameState(5);
|
GameState gameState = new GameState(5);
|
||||||
|
|
||||||
gameState.playStone('A',2,GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("A2"));
|
||||||
gameState.playStone('B',3,GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("B3"));
|
||||||
gameState.playStone('C',2,GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("C2"));
|
||||||
gameState.playStone('B',1,GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("B1"));
|
||||||
gameState.playStone('E',5,GameBoard.WHITE_STONE);
|
gameState.playStone(Player.WHITE, Action.getInstance("E5"));
|
||||||
|
|
||||||
System.out.println(gameState);
|
System.out.println(gameState);
|
||||||
GameScore gameScore = new StateEvaluator(gameConfig).scoreGame(gameState);
|
GameScore gameScore = new StateEvaluator(gameConfig)
|
||||||
|
.scoreGame(gameState);
|
||||||
|
|
||||||
System.out.println(gameScore.getScoreReport());
|
System.out.println(gameScore.getScoreReport());
|
||||||
|
|
||||||
assertEquals(1.0,gameScore.getWhiteScore(),0.5);
|
assertEquals(1.0, gameScore.getWhiteScore(), 0.5);
|
||||||
assertEquals(6.0,gameScore.getBlackScore(),0.5);
|
assertEquals(6.0, gameScore.getBlackScore(), 0.5);
|
||||||
//Black should be up by 5 if Black's territory at A1 & B2 is scored correctly.
|
// Black should be up by 5 if Black's territory at A1 & B2 is scored
|
||||||
|
// correctly.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCaptureAggScore() {
|
public void testCaptureAggScore() {
|
||||||
GameState gameState = new GameState(9);
|
GameState gameState = new GameState(9);
|
||||||
gameState.playStone('A', 2, GameBoard.WHITE_STONE);
|
gameState.playStone(Player.WHITE, Action.getInstance("A2"));
|
||||||
gameState.playStone('B', 1, GameBoard.WHITE_STONE);
|
gameState.playStone(Player.WHITE, Action.getInstance("B1"));
|
||||||
gameState.playStone('C', 2, GameBoard.WHITE_STONE);
|
gameState.playStone(Player.WHITE, Action.getInstance("C2"));
|
||||||
gameState.playStone('B', 2, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("B2"));
|
||||||
|
|
||||||
GameState moveToA1 = new GameState(gameState);
|
GameState moveToA1 = new GameState(gameState);
|
||||||
GameState capAtB3 = new GameState(gameState);
|
GameState capAtB3 = new GameState(gameState);
|
||||||
|
|
||||||
moveToA1.playStone("w","A1");
|
moveToA1.playStone(Player.WHITE, Action.getInstance("A1"));
|
||||||
capAtB3.playStone("w", "B3");
|
capAtB3.playStone(Player.WHITE, Action.getInstance("B3"));
|
||||||
|
|
||||||
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(new 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();
|
||||||
|
|
||||||
System.out.println("Score at A1: " + scoreA1);
|
System.out.println("Score at A1: " + scoreA1);
|
||||||
System.out.println("Score at B3: " + scoreB3);
|
System.out.println("Score at B3: " + scoreB3);
|
||||||
//moving as white, lower is better
|
// moving as white, lower is better
|
||||||
assertTrue(scoreA1 > scoreB3);
|
assertTrue(scoreA1 > scoreB3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,22 +1,18 @@
|
|||||||
package net.woodyfolsom.msproj;
|
package net.woodyfolsom.msproj;
|
||||||
|
|
||||||
import net.woodyfolsom.msproj.GameBoard;
|
|
||||||
import net.woodyfolsom.msproj.GameState;
|
|
||||||
import net.woodyfolsom.msproj.TerritoryMarker;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class TerritoryFinderTest {
|
public class TerritoryFinderTest {
|
||||||
@Test
|
@Test
|
||||||
public void testMarkTerritory() {
|
public void testMarkTerritory() {
|
||||||
GameState gameState = new GameState(5);
|
GameState gameState = new GameState(5);
|
||||||
|
|
||||||
gameState.playStone('A',2,GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("A2"));
|
||||||
gameState.playStone('B',3,GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("B3"));
|
||||||
gameState.playStone('C',2,GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("C2"));
|
||||||
gameState.playStone('B',1,GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("B1"));
|
||||||
gameState.playStone('E',5,GameBoard.WHITE_STONE);
|
gameState.playStone(Player.WHITE, Action.getInstance("E5"));
|
||||||
|
|
||||||
TerritoryMarker.markTerritory(gameState.getGameBoard());
|
TerritoryMarker.markTerritory(gameState.getGameBoard());
|
||||||
System.out.println(gameState);
|
System.out.println(gameState);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
package net.woodyfolsom.msproj.policy;
|
package net.woodyfolsom.msproj.policy;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import net.woodyfolsom.msproj.Action;
|
||||||
import net.woodyfolsom.msproj.GameBoard;
|
|
||||||
import net.woodyfolsom.msproj.GameConfig;
|
import net.woodyfolsom.msproj.GameConfig;
|
||||||
import net.woodyfolsom.msproj.GameState;
|
import net.woodyfolsom.msproj.GameState;
|
||||||
import net.woodyfolsom.msproj.policy.AlphaBeta;
|
import net.woodyfolsom.msproj.Player;
|
||||||
import net.woodyfolsom.msproj.policy.Policy;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
@@ -15,43 +13,40 @@ public class AlphaBetaTest {
|
|||||||
public void testGenmoveAsW() {
|
public void testGenmoveAsW() {
|
||||||
Policy treeSearch = new AlphaBeta();
|
Policy treeSearch = new AlphaBeta();
|
||||||
GameState gameState = new GameState(6);
|
GameState gameState = new GameState(6);
|
||||||
gameState.playStone('A', 2, GameBoard.WHITE_STONE);
|
gameState.playStone(Player.WHITE, Action.getInstance("A2"));
|
||||||
gameState.playStone('B', 1, GameBoard.WHITE_STONE);
|
gameState.playStone(Player.WHITE, Action.getInstance("B1"));
|
||||||
gameState.playStone('C', 2, GameBoard.WHITE_STONE);
|
gameState.playStone(Player.WHITE, Action.getInstance("C2"));
|
||||||
gameState.playStone('B', 2, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("B2"));
|
||||||
|
|
||||||
String move = treeSearch.getAction(new GameConfig(), gameState, "b");
|
Action move = treeSearch.getAction(new GameConfig(), gameState, Player.WHITE);
|
||||||
|
|
||||||
System.out.println(gameState);
|
System.out.println(gameState);
|
||||||
|
|
||||||
System.out.println("Generated move: " + move);
|
System.out.println("Generated move: " + move);
|
||||||
assertEquals("Expected B3 but was: " + move, "B3", move);
|
assertEquals("Expected B3 but was: " + move, Action.getInstance("B3"), move);
|
||||||
gameState.playStone("b", move);
|
gameState.playStone(Player.WHITE, move);
|
||||||
|
System.out.println("Final board state:");
|
||||||
System.out.println(gameState);
|
System.out.println(gameState);
|
||||||
|
|
||||||
assertEquals(Policy.PASS,
|
|
||||||
treeSearch.getAction(new GameConfig(), gameState, "?"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGenmoveAsB() {
|
public void testGenmoveAsB() {
|
||||||
Policy treeSearch = new AlphaBeta();
|
Policy treeSearch = new AlphaBeta();
|
||||||
GameState gameState = new GameState(6);
|
GameState gameState = new GameState(6);
|
||||||
gameState.playStone('A', 2, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("A2"));
|
||||||
gameState.playStone('B', 1, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("B1"));
|
||||||
gameState.playStone('C', 2, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("C2"));
|
||||||
gameState.playStone('B', 2, GameBoard.WHITE_STONE);
|
gameState.playStone(Player.WHITE, Action.getInstance("B2"));
|
||||||
|
|
||||||
String move = treeSearch.getAction(new GameConfig(), gameState, "b");
|
Action move = treeSearch.getAction(new GameConfig(), gameState, Player.BLACK);
|
||||||
|
|
||||||
System.out.println(gameState);
|
System.out.println(gameState);
|
||||||
|
|
||||||
System.out.println("Generated move: " + move);
|
System.out.println("Generated move: " + move);
|
||||||
assertEquals("Expected B3 but was: " + move, "B3", move);
|
assertEquals("Expected B3 but was: " + move, Action.getInstance("B3"), move);
|
||||||
gameState.playStone("b", move);
|
gameState.playStone(Player.BLACK, move);
|
||||||
|
|
||||||
|
System.out.println("Final board state:");
|
||||||
System.out.println(gameState);
|
System.out.println(gameState);
|
||||||
|
|
||||||
assertEquals(Policy.PASS,
|
|
||||||
treeSearch.getAction(new GameConfig(), gameState, "?"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,34 +1,53 @@
|
|||||||
package net.woodyfolsom.msproj.policy;
|
package net.woodyfolsom.msproj.policy;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import net.woodyfolsom.msproj.Action;
|
||||||
import net.woodyfolsom.msproj.GameBoard;
|
|
||||||
import net.woodyfolsom.msproj.GameConfig;
|
import net.woodyfolsom.msproj.GameConfig;
|
||||||
import net.woodyfolsom.msproj.GameState;
|
import net.woodyfolsom.msproj.GameState;
|
||||||
import net.woodyfolsom.msproj.policy.Policy;
|
import net.woodyfolsom.msproj.Player;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
|
||||||
public class MinimaxTest {
|
public class MinimaxTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGenmove() {
|
public void testGenmoveAsW() {
|
||||||
Policy moveGenerator = new Minimax();
|
Policy treeSearch = new Minimax();
|
||||||
GameState gameState = new GameState(5);
|
GameState gameState = new GameState(6);
|
||||||
gameState.playStone('A', 2, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.WHITE, Action.getInstance("A2"));
|
||||||
gameState.playStone('B', 1, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.WHITE, Action.getInstance("B1"));
|
||||||
gameState.playStone('C', 2, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.WHITE, Action.getInstance("C2"));
|
||||||
gameState.playStone('B', 4, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("B2"));
|
||||||
|
|
||||||
String move = moveGenerator.getAction(new GameConfig(), gameState, "w");
|
Action move = treeSearch.getAction(new GameConfig(), gameState,
|
||||||
System.out.println("Generated move: " + move);
|
Player.WHITE);
|
||||||
gameState.playStone("w", move);
|
|
||||||
|
|
||||||
System.out.println(gameState);
|
System.out.println(gameState);
|
||||||
|
|
||||||
assertEquals(Policy.PASS,moveGenerator.getAction(new GameConfig(), gameState, "?"));
|
System.out.println("Generated move: " + move);
|
||||||
|
assertEquals("Expected B3 but was: " + move, "B3", move);
|
||||||
|
gameState.playStone(Player.WHITE, move);
|
||||||
|
|
||||||
System.out.println(gameState);
|
System.out.println(gameState);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@Test
|
||||||
|
public void testGenmoveAsB() {
|
||||||
|
Policy treeSearch = new Minimax();
|
||||||
|
GameState gameState = new GameState(6);
|
||||||
|
gameState.playStone(Player.BLACK, Action.getInstance("A2"));
|
||||||
|
gameState.playStone(Player.BLACK, Action.getInstance("B1"));
|
||||||
|
gameState.playStone(Player.BLACK, Action.getInstance("C2"));
|
||||||
|
gameState.playStone(Player.WHITE, Action.getInstance("B2"));
|
||||||
|
|
||||||
|
Action move = treeSearch.getAction(new GameConfig(), gameState,
|
||||||
|
Player.BLACK);
|
||||||
|
|
||||||
|
System.out.println(gameState);
|
||||||
|
|
||||||
|
System.out.println("Generated move: " + move);
|
||||||
|
assertEquals("Expected B3 but was: " + move, "B3", move);
|
||||||
|
gameState.playStone(Player.BLACK, move);
|
||||||
|
|
||||||
|
System.out.println(gameState);
|
||||||
|
}
|
||||||
|
}
|
||||||
53
test/net/woodyfolsom/msproj/policy/MonteCarloUCTTest.java
Normal file
53
test/net/woodyfolsom/msproj/policy/MonteCarloUCTTest.java
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
package net.woodyfolsom.msproj.policy;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import net.woodyfolsom.msproj.Action;
|
||||||
|
import net.woodyfolsom.msproj.GameConfig;
|
||||||
|
import net.woodyfolsom.msproj.GameState;
|
||||||
|
import net.woodyfolsom.msproj.Player;
|
||||||
|
import net.woodyfolsom.msproj.policy.Policy;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class MonteCarloUCTTest {
|
||||||
|
@Test
|
||||||
|
public void testGenmoveAsW() {
|
||||||
|
Policy treeSearch = new MonteCarloUCT(new RandomMovePolicy(),2000L);
|
||||||
|
GameState gameState = new GameState(6);
|
||||||
|
gameState.playStone(Player.WHITE, Action.getInstance("A2"));
|
||||||
|
gameState.playStone(Player.WHITE, Action.getInstance("B1"));
|
||||||
|
gameState.playStone(Player.WHITE, Action.getInstance("C2"));
|
||||||
|
gameState.playStone(Player.BLACK, Action.getInstance("B2"));
|
||||||
|
|
||||||
|
Action move = treeSearch.getAction(new GameConfig(), gameState, Player.WHITE);
|
||||||
|
|
||||||
|
System.out.println(gameState);
|
||||||
|
|
||||||
|
System.out.println("Generated move: " + move);
|
||||||
|
assertEquals("Expected B3 but was: " + move, "B3", move);
|
||||||
|
gameState.playStone(Player.WHITE, move);
|
||||||
|
|
||||||
|
System.out.println(gameState);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGenmoveAsB() {
|
||||||
|
Policy treeSearch = new MonteCarloUCT(new RandomMovePolicy(),2000L);
|
||||||
|
GameState gameState = new GameState(6);
|
||||||
|
gameState.playStone(Player.BLACK, Action.getInstance("A2"));
|
||||||
|
gameState.playStone(Player.BLACK, Action.getInstance("B1"));
|
||||||
|
gameState.playStone(Player.BLACK, Action.getInstance("C2"));
|
||||||
|
gameState.playStone(Player.WHITE, Action.getInstance("B2"));
|
||||||
|
|
||||||
|
Action move = treeSearch.getAction(new GameConfig(), gameState, Player.BLACK);
|
||||||
|
|
||||||
|
System.out.println(gameState);
|
||||||
|
|
||||||
|
System.out.println("Generated move: " + move);
|
||||||
|
assertEquals("Expected B3 but was: " + move, "B3", move);
|
||||||
|
gameState.playStone(Player.BLACK, move);
|
||||||
|
|
||||||
|
System.out.println(gameState);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,53 +1,56 @@
|
|||||||
package net.woodyfolsom.msproj.policy;
|
package net.woodyfolsom.msproj.policy;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertTrue;
|
import net.woodyfolsom.msproj.Action;
|
||||||
|
|
||||||
import net.woodyfolsom.msproj.GameBoard;
|
|
||||||
import net.woodyfolsom.msproj.GameConfig;
|
import net.woodyfolsom.msproj.GameConfig;
|
||||||
import net.woodyfolsom.msproj.GameState;
|
import net.woodyfolsom.msproj.GameState;
|
||||||
import net.woodyfolsom.msproj.policy.Policy;
|
import net.woodyfolsom.msproj.Player;
|
||||||
import net.woodyfolsom.msproj.policy.RandomMovePolicy;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
|
||||||
public class RandomTest {
|
public class RandomTest {
|
||||||
|
|
||||||
@Test
|
@Test(expected = IllegalArgumentException.class)
|
||||||
public void testGenmove() {
|
public void testGenmoveForNone() {
|
||||||
Policy moveGenerator = new RandomMovePolicy();
|
Policy moveGenerator = new RandomMovePolicy();
|
||||||
GameState gameState = new GameState(5);
|
GameState gameState = new GameState(5);
|
||||||
moveGenerator.getAction(new GameConfig(), gameState, "b");
|
moveGenerator.getAction(new GameConfig(), gameState, Player.BLACK);
|
||||||
gameState = new GameState(5);
|
gameState = new GameState(5);
|
||||||
moveGenerator.getAction(new GameConfig(), gameState, "w");
|
moveGenerator.getAction(new GameConfig(), gameState, Player.WHITE);
|
||||||
|
|
||||||
assertEquals(Policy.PASS,moveGenerator.getAction(new GameConfig(), gameState, "?"));
|
assertEquals(Action.PASS, moveGenerator.getAction(new GameConfig(), gameState, Player.NONE));
|
||||||
|
|
||||||
System.out.println(gameState);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAlternativeToIllegalMove() {
|
public void testAlternativeToIllegalMove() {
|
||||||
GameState gameState = new GameState(4);
|
GameState gameState = new GameState(4);
|
||||||
gameState.playStone('A', 1, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("A1"));
|
||||||
gameState.playStone('A', 2, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("A2"));
|
||||||
gameState.playStone('A', 3, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("A3"));
|
||||||
gameState.playStone('A', 4, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("A4"));
|
||||||
gameState.playStone('B', 1, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("B1"));;
|
||||||
gameState.playStone('B', 2, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("B2"));
|
||||||
|
|
||||||
//gameState.playStone('B', 3, GameBoard.BLACK_STONE);
|
//gameState.playStone('B', 3, GameBoard.BLACK_STONE);
|
||||||
gameState.playStone('B', 4, GameBoard.BLACK_STONE);
|
|
||||||
gameState.playStone('C', 2, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("B4"));
|
||||||
gameState.playStone('C', 3, GameBoard.BLACK_STONE);
|
|
||||||
gameState.playStone('C', 4, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("C2"));
|
||||||
gameState.playStone('D', 4, GameBoard.BLACK_STONE);
|
gameState.playStone(Player.BLACK, Action.getInstance("C3"));
|
||||||
assertTrue(gameState.playStone('C', 1, GameBoard.WHITE_STONE));
|
gameState.playStone(Player.BLACK, Action.getInstance("C4"));
|
||||||
assertTrue(gameState.playStone('D', 2, GameBoard.WHITE_STONE));
|
|
||||||
assertTrue(gameState.playStone('D', 3, GameBoard.WHITE_STONE));
|
gameState.playStone(Player.BLACK, Action.getInstance("D4"));
|
||||||
|
|
||||||
|
gameState.playStone(Player.WHITE, Action.getInstance("C1"));
|
||||||
|
gameState.playStone(Player.WHITE, Action.getInstance("D2"));
|
||||||
|
gameState.playStone(Player.WHITE, Action.getInstance("D3"));
|
||||||
|
|
||||||
|
System.out.println("State before random WHITE move selection:");
|
||||||
System.out.println(gameState);
|
System.out.println(gameState);
|
||||||
//This is correct - checked vs. MFOG
|
//This is correct - checked vs. MFOG
|
||||||
assertEquals("B3", new RandomMovePolicy().getAction(new GameConfig(), gameState, "w"));
|
assertEquals(Action.getInstance("B3"), new RandomMovePolicy().getAction(new GameConfig(), gameState, Player.WHITE));
|
||||||
|
|
||||||
System.out.println(gameState);
|
System.out.println(gameState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
package net.woodyfolsom.msproj.policy;
|
package net.woodyfolsom.msproj.policy;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import net.woodyfolsom.msproj.GameBoard;
|
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.policy.ValidMoveGenerator;
|
import net.woodyfolsom.msproj.Player;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
@@ -26,18 +27,22 @@ public class ValidMoveGeneratorTest {
|
|||||||
A B C D E
|
A B C D E
|
||||||
*/
|
*/
|
||||||
GameState gameState = new GameState(5);
|
GameState gameState = new GameState(5);
|
||||||
gameState.playStone('A', 2, GameBoard.WHITE_STONE);
|
gameState.playStone(Player.WHITE, Action.getInstance("A2"));
|
||||||
gameState.playStone('B', 1, GameBoard.WHITE_STONE);
|
gameState.playStone(Player.WHITE, Action.getInstance("B1"));
|
||||||
gameState.playStone('B', 4, GameBoard.WHITE_STONE);
|
gameState.playStone(Player.WHITE, Action.getInstance("B4"));
|
||||||
gameState.playStone('C', 2, GameBoard.WHITE_STONE);
|
gameState.playStone(Player.WHITE, Action.getInstance("C2"));
|
||||||
assertFalse(gameState.playStone('A', 1, GameBoard.BLACK_STONE));
|
|
||||||
|
assertFalse(gameState.playStone(Player.BLACK, Action.getInstance("A1")));
|
||||||
|
|
||||||
|
List<Action> validMoves = new ValidMoveGenerator().getActions(new GameConfig(), gameState, Player.BLACK,0);
|
||||||
|
|
||||||
List<String> validMoves = new ValidMoveGenerator().getActions(new GameConfig(), gameState, "b",0);
|
|
||||||
assertTrue(validMoves.size() > 0);
|
assertTrue(validMoves.size() > 0);
|
||||||
for (String vm : validMoves) {
|
|
||||||
|
for (Action vm : validMoves) {
|
||||||
System.out.println(vm);
|
System.out.println(vm);
|
||||||
}
|
}
|
||||||
assertFalse(validMoves.contains("A1"));
|
|
||||||
|
assertFalse(validMoves.contains(Action.getInstance("A1")));
|
||||||
|
|
||||||
System.out.println(gameState);
|
System.out.println(gameState);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user