[jgogears commit] r52 - in trunk/jgogears: doc jgogears jgogears/engine

0 views
Skip to first unread message

codesite...@google.com

unread,
Mar 6, 2008, 7:49:52 PM3/6/08
to jgog...@googlegroups.com
Author: syeates
Date: Thu Mar 6 16:42:16 2008
New Revision: 52

Added:
trunk/jgogears/jgogears/engine/Scorer.java
trunk/jgogears/jgogears/engine/Trainer.java
Modified:
trunk/jgogears/doc/TODO
trunk/jgogears/jgogears/BoardI.java
trunk/jgogears/jgogears/BoardTest.java
trunk/jgogears/jgogears/CachingKoRule.java
trunk/jgogears/jgogears/FastBoardTest.java
trunk/jgogears/jgogears/FasterBoardTest.java
trunk/jgogears/jgogears/engine/Engine.java
trunk/jgogears/jgogears/engine/Model.java
trunk/jgogears/jgogears/engine/ModelTest.java
trunk/jgogears/jgogears/engine/Node.java
trunk/jgogears/jgogears/engine/SufgoEngine.java
trunk/jgogears/jgogears/engine/SufogoEngineTest.java

Log:
Zobrist tests, seperation of Trainer and Scorer from Model and Node code.

Modified: trunk/jgogears/doc/TODO
==============================================================================
--- trunk/jgogears/doc/TODO (original)
+++ trunk/jgogears/doc/TODO Thu Mar 6 16:42:16 2008
@@ -2,13 +2,11 @@
====

Short Term
-* fix java compiler style warnings (javadoc etc)
* trace lack of symmetry in testTrainedModelEmptyBoard
* work on ASCIIToBoard -> BoardI round triping
* update javacc generated files in svn (eclipse javacc plugin is
preventing this happening)
* commandline program to play jgogears against gnugo
* commandline program to guess moves from real games
-* separate the model data structures from the algorithms

SGF Support
* parse tt in SGF files
@@ -27,8 +25,7 @@
* cut and paste
* Better test coverage
* improve GTP support
-* SGF saving (validation use SGFC)
-* tests for ko rules
+* SGF saving (use SGFC for validation)
* generate and quality-check the javadoc

Speed improvements, test and improve:
@@ -38,5 +35,7 @@

DONE
* implement abstract KO detection
-
+* fix java compiler style warnings (javadoc etc)
+* tests for ko rules
+* separate the Model/Node data structures from the algorithms


Modified: trunk/jgogears/jgogears/BoardI.java
==============================================================================
--- trunk/jgogears/jgogears/BoardI.java (original)
+++ trunk/jgogears/jgogears/BoardI.java Thu Mar 6 16:42:16 2008
@@ -258,11 +258,16 @@

@Override
public boolean equals(Object obj) {
- if (obj.getClass() != this.getClass())
+ if (obj == this)
+ return true;
+ BoardI other = null;
+ try {
+ other = (BoardI) obj;
+ } catch (Throwable t) {
return super.equals(obj);
- BoardI other = (BoardI) obj;
+ }
if (other == null)
- throw new Error();
+ return false;
if (this.size != other.size)
return false;
if (this.getZobrist() != null && other.getZobrist() != null)

Modified: trunk/jgogears/jgogears/BoardTest.java
==============================================================================
--- trunk/jgogears/jgogears/BoardTest.java (original)
+++ trunk/jgogears/jgogears/BoardTest.java Thu Mar 6 16:42:16 2008
@@ -137,7 +137,37 @@
}

/**
- * Test each undoable ii.
+ *
+ */
+ public void testEachUndoableI() {
+ for (int i = 0; i < Zobrist.MAX_BOARD_SIZE; i++)
+ for (int j = 0; j < Zobrist.MAX_BOARD_SIZE; j++)
+ for (int k = 0; k < Zobrist.MAX_COLOUR; k++) {
+
+ BoardI board1 = new Board();
+ BoardI board2 = board1.newBoard(new Move((short) 1, (short) 1, BoardI.VERTEX_BLACK));
+ BoardI board3 = board1.newBoard(new Move((short) 1, (short) 1, BoardI.VERTEX_BLACK));
+ BoardI board4 = board2.newBoard(new Move((short) 1, (short) 1, BoardI.VERTEX_BLACK));
+
+ assertTrue(board1.equals(board1));
+ assertTrue(board2.equals(board2));
+ assertTrue(board3.equals(board3));
+ assertTrue(board4.equals(board4));
+
+ assertFalse(board1.equals(board2));
+ assertFalse(board2.equals(board1));
+ assertFalse(board1.equals(board3));
+ assertFalse(board3.equals(board1));
+ assertTrue(board4.equals(board1));
+ assertTrue(board1.equals(board4));
+ assertTrue(board2.equals(board3));
+ assertTrue(board3.equals(board2));
+
+ }
+ }
+
+ /**
+ *
*/
public void testEachUndoableII() {
for (int i = 0; i < Zobrist.MAX_BOARD_SIZE; i++)
@@ -149,16 +179,25 @@
BoardI board3 = board1.newBoard(new Move((short) 1, (short) 1, BoardI.VERTEX_BLACK));
BoardI board4 = board2.newBoard(new Move((short) 1, (short) 1, BoardI.VERTEX_BLACK));

+ assertTrue(board1.equals(board1));
+ assertTrue(board2.equals(board2));
+ assertTrue(board3.equals(board3));
+ assertTrue(board4.equals(board4));
+
assertFalse(board1.equals(board2));
+ assertFalse(board2.equals(board1));
assertFalse(board1.equals(board3));
+ assertFalse(board3.equals(board1));
+ assertTrue(board4.equals(board1));
assertTrue(board1.equals(board4));
assertTrue(board2.equals(board3));
+ assertTrue(board3.equals(board2));

}
}

/**
- * Test each undoable ii.
+ *
*/
public void testEachUndoableIII() {
for (int i = 0; i < Zobrist.MAX_BOARD_SIZE; i++)
@@ -170,10 +209,17 @@
BoardI board3 = board1.newBoard(new Move((short) 1, (short) 1, BoardI.VERTEX_BLACK));
BoardI board4 = board2.newBoard(new Move((short) 1, (short) 1, BoardI.VERTEX_BLACK));

+ assertTrue(board1.equals(board1));
+ assertTrue(board2.equals(board2));
+ assertTrue(board3.equals(board3));
+ assertTrue(board4.equals(board4));
+
assertFalse(board1.equals(board2));
+ assertFalse(board2.equals(board1));
assertFalse(board1.equals(board3));
- assertTrue(board1.equals(board4));
+ assertFalse(board3.equals(board1));
assertTrue(board2.equals(board3));
+ assertTrue(board3.equals(board2));

}
}

Modified: trunk/jgogears/jgogears/CachingKoRule.java
==============================================================================
--- trunk/jgogears/jgogears/CachingKoRule.java (original)
+++ trunk/jgogears/jgogears/CachingKoRule.java Thu Mar 6 16:42:16 2008
@@ -5,6 +5,8 @@
/**
* A RuleSet that caches the results to speed things up.
*
+ * TODO this class is still a skeleton, it doesn't actually do
anything yet.
+ *
* @author syeates
*/
public class CachingKoRule extends RuleSet {

Modified: trunk/jgogears/jgogears/FastBoardTest.java
==============================================================================
--- trunk/jgogears/jgogears/FastBoardTest.java (original)
+++ trunk/jgogears/jgogears/FastBoardTest.java Thu Mar 6 16:42:16 2008
@@ -326,4 +326,94 @@
// System.out.println(working);
}

+ /**
+ *
+ */
+ public void testEachUndoableI() {
+ for (int i = 0; i < Zobrist.MAX_BOARD_SIZE; i++)
+ for (int j = 0; j < Zobrist.MAX_BOARD_SIZE; j++)
+ for (int k = 0; k < Zobrist.MAX_COLOUR; k++) {
+
+ BoardI board1 = new FastBoard();
+ BoardI board2 = board1.newBoard(new Move((short) 1, (short) 1, BoardI.VERTEX_BLACK));
+ BoardI board3 = board1.newBoard(new Move((short) 1, (short) 1, BoardI.VERTEX_BLACK));
+ BoardI board4 = board2.newBoard(new Move((short) 1, (short) 1, BoardI.VERTEX_BLACK));
+
+ assertTrue(board1.equals(board1));
+ assertTrue(board2.equals(board2));
+ assertTrue(board3.equals(board3));
+ assertTrue(board4.equals(board4));
+
+ assertFalse(board1.equals(board2));
+ assertFalse(board2.equals(board1));
+ assertFalse(board1.equals(board3));
+ assertFalse(board3.equals(board1));
+ assertTrue(board4.equals(board1));
+ assertTrue(board1.equals(board4));
+ assertTrue(board2.equals(board3));
+ assertTrue(board3.equals(board2));
+
+ }
+ }
+
+ /**
+ *
+ */
+ public void testEachUndoableII() {
+ for (int i = 0; i < Zobrist.MAX_BOARD_SIZE; i++)
+ for (int j = 0; j < Zobrist.MAX_BOARD_SIZE; j++)
+ for (int k = 0; k < Zobrist.MAX_COLOUR; k++) {
+
+ BoardI board1 = new FastBoard(true);
+ BoardI board2 = board1.newBoard(new Move((short) 1, (short) 1, BoardI.VERTEX_BLACK));
+ BoardI board3 = board1.newBoard(new Move((short) 1, (short) 1, BoardI.VERTEX_BLACK));
+ BoardI board4 = board2.newBoard(new Move((short) 1, (short) 1, BoardI.VERTEX_BLACK));
+
+ assertTrue(board1.equals(board1));
+ assertTrue(board2.equals(board2));
+ assertTrue(board3.equals(board3));
+ assertTrue(board4.equals(board4));
+
+ assertFalse(board1.equals(board2));
+ assertFalse(board2.equals(board1));
+ assertFalse(board1.equals(board3));
+ assertFalse(board3.equals(board1));
+ assertTrue(board4.equals(board1));
+ assertTrue(board1.equals(board4));
+ assertTrue(board2.equals(board3));
+ assertTrue(board3.equals(board2));
+
+ }
+ }
+
+ /**
+ *
+ */
+ public void testEachUndoableIII() {
+ for (int i = 0; i < Zobrist.MAX_BOARD_SIZE; i++)
+ for (int j = 0; j < Zobrist.MAX_BOARD_SIZE; j++)
+ for (int k = 0; k < Zobrist.MAX_COLOUR; k++) {
+
+ BoardI board1 = new FastBoard(false);
+ BoardI board2 = board1.newBoard(new Move((short) 1, (short) 1, BoardI.VERTEX_BLACK));
+ BoardI board3 = board1.newBoard(new Move((short) 1, (short) 1, BoardI.VERTEX_BLACK));
+ BoardI board4 = board2.newBoard(new Move((short) 1, (short) 1, BoardI.VERTEX_BLACK));
+
+ assertTrue(board1.equals(board1));
+ assertTrue(board2.equals(board2));
+ assertTrue(board3.equals(board3));
+ assertTrue(board4.equals(board4));
+
+ assertFalse(board1.equals(board2));
+ assertFalse(board2.equals(board1));
+ assertFalse(board1.equals(board3));
+ assertFalse(board3.equals(board1));
+ assertTrue(board4.equals(board1));
+ assertTrue(board1.equals(board4));
+ assertTrue(board2.equals(board3));
+ assertTrue(board3.equals(board2));
+
+ }
+ }
+
}

Modified: trunk/jgogears/jgogears/FasterBoardTest.java
==============================================================================
--- trunk/jgogears/jgogears/FasterBoardTest.java (original)
+++ trunk/jgogears/jgogears/FasterBoardTest.java Thu Mar 6 16:42:16 2008
@@ -201,4 +201,94 @@
System.out.println(working);
}

+ /**
+ *
+ */
+ public void testEachUndoableI() {
+ for (int i = 0; i < Zobrist.MAX_BOARD_SIZE; i++)
+ for (int j = 0; j < Zobrist.MAX_BOARD_SIZE; j++)
+ for (int k = 0; k < Zobrist.MAX_COLOUR; k++) {
+
+ BoardI board1 = new FasterBoard();
+ BoardI board2 = board1.newBoard(new Move((short) 1, (short) 1, BoardI.VERTEX_BLACK));
+ BoardI board3 = board1.newBoard(new Move((short) 1, (short) 1, BoardI.VERTEX_BLACK));
+ BoardI board4 = board2.newBoard(new Move((short) 1, (short) 1, BoardI.VERTEX_BLACK));
+
+ assertTrue(board1.equals(board1));
+ assertTrue(board2.equals(board2));
+ assertTrue(board3.equals(board3));
+ assertTrue(board4.equals(board4));
+
+ assertFalse(board1.equals(board2));
+ assertFalse(board2.equals(board1));
+ assertFalse(board1.equals(board3));
+ assertFalse(board3.equals(board1));
+ assertTrue(board4.equals(board1));
+ assertTrue(board1.equals(board4));
+ assertTrue(board2.equals(board3));
+ assertTrue(board3.equals(board2));
+
+ }
+ }
+
+ /**
+ *
+ */
+ public void testEachUndoableII() {
+ for (int i = 0; i < Zobrist.MAX_BOARD_SIZE; i++)
+ for (int j = 0; j < Zobrist.MAX_BOARD_SIZE; j++)
+ for (int k = 0; k < Zobrist.MAX_COLOUR; k++) {
+
+ BoardI board1 = new FasterBoard(true);
+ BoardI board2 = board1.newBoard(new Move((short) 1, (short) 1, BoardI.VERTEX_BLACK));
+ BoardI board3 = board1.newBoard(new Move((short) 1, (short) 1, BoardI.VERTEX_BLACK));
+ BoardI board4 = board2.newBoard(new Move((short) 1, (short) 1, BoardI.VERTEX_BLACK));
+
+ assertTrue(board1.equals(board1));
+ assertTrue(board2.equals(board2));
+ assertTrue(board3.equals(board3));
+ assertTrue(board4.equals(board4));
+
+ assertFalse(board1.equals(board2));
+ assertFalse(board2.equals(board1));
+ assertFalse(board1.equals(board3));
+ assertFalse(board3.equals(board1));
+ assertTrue(board4.equals(board1));
+ assertTrue(board1.equals(board4));
+ assertTrue(board2.equals(board3));
+ assertTrue(board3.equals(board2));
+
+ }
+ }
+
+ /**
+ *
+ */
+ public void testEachUndoableIII() {
+ for (int i = 0; i < Zobrist.MAX_BOARD_SIZE; i++)
+ for (int j = 0; j < Zobrist.MAX_BOARD_SIZE; j++)
+ for (int k = 0; k < Zobrist.MAX_COLOUR; k++) {
+
+ BoardI board1 = new FasterBoard(false);
+ BoardI board2 = board1.newBoard(new Move((short) 1, (short) 1, BoardI.VERTEX_BLACK));
+ BoardI board3 = board1.newBoard(new Move((short) 1, (short) 1, BoardI.VERTEX_BLACK));
+ BoardI board4 = board2.newBoard(new Move((short) 1, (short) 1, BoardI.VERTEX_BLACK));
+
+ assertTrue(board1.equals(board1));
+ assertTrue(board2.equals(board2));
+ assertTrue(board3.equals(board3));
+ assertTrue(board4.equals(board4));
+
+ assertFalse(board1.equals(board2));
+ assertFalse(board2.equals(board1));
+ assertFalse(board1.equals(board3));
+ assertFalse(board3.equals(board1));
+ assertTrue(board4.equals(board1));
+ assertTrue(board1.equals(board4));
+ assertTrue(board2.equals(board3));
+ assertTrue(board3.equals(board2));
+
+ }
+ }
+
}

Modified: trunk/jgogears/jgogears/engine/Engine.java
==============================================================================
--- trunk/jgogears/jgogears/engine/Engine.java (original)
+++ trunk/jgogears/jgogears/engine/Engine.java Thu Mar 6 16:42:16 2008
@@ -26,7 +26,7 @@
Model model = new Model();
System.out.println("about to train model");

- ModelTest.trainNFiles(100, model);
+ new Trainer().trainNFiles(100, model);
System.out.println("model trained");

SufgoEngine black = new SufgoEngine();

Modified: trunk/jgogears/jgogears/engine/Model.java
==============================================================================
--- trunk/jgogears/jgogears/engine/Model.java (original)
+++ trunk/jgogears/jgogears/engine/Model.java Thu Mar 6 16:42:16 2008
@@ -87,34 +87,6 @@
}

/**
- * Which vertex is the best to play?
- *
- * @param board
- * the board we're playing on
- * @param white
- * is white to play?
- * @return the vertex to play
- */
- Vertex getBestScore(BoardI board, boolean white) {
- double[][] result = this.getScores(board, white);
- double best = Double.MAX_VALUE;
- int I = 0, J = 0;
- int i, j;
- for (i = 0; i < board.getSize(); i++)
- for (j = 0; j < board.getSize(); j++) {
- if (result[i][j] < best) {
- if (RuleSet.DEFAULT.moveIsLegal(null, board, new Move(i, j,
white ? BoardI.VERTEX_WHITE
- : BoardI.VERTEX_BLACK))) {
- best = result[i][j];
- I = i;
- J = j;
- }
- }
- }
- return new Vertex(I, J);
- }
-
- /**
* Gets the root of the model
*
* @return the root
@@ -123,128 +95,4 @@
return this.root;
}

- /**
- * TODO
- *
- * @param board
- * @param white
- * @return the array of scores
- */
- public double[][] getScores(BoardI board, boolean white) {
- short size = board.getSize();
- double[][] result = new double[size][size];
- for (short row = 0; row < size; row++) {
- for (short column = 0; column < size; column++) {
- for (short sym = 0; sym < 8; sym++) {
- result[row][column] = 0.0;
- Node node = this.getRoot();
- int maxdepth = 0;
- VertexLineariser linear = new VertexLineariser(board, row,
column, sym, white);
- double estimate = 1.0;
- int depth = 0;
- while (linear.hasNext() && node != null) {
- depth++;
- if (depth > maxdepth)
- maxdepth = depth;
- short colour = linear.next();
- Node child = null;
-
- switch (colour) {
- case BoardI.VERTEX_BLACK:
- child = node.getBlack();
- break;
- case BoardI.VERTEX_WHITE:
- child = node.getWhite();
- break;
- case BoardI.VERTEX_OFF_BOARD:
- child = node.getOff();
- break;
- case BoardI.VERTEX_KO:
- case BoardI.VERTEX_EMPTY:
- child = node.getEmpty();
- break;
- default:
- throw new Error("Unknown vertex colour: " + colour);
- }
- double childP = 1;
- double childNP = 1;
- if (child != null) {
- childP = child.getPlayed();
- childNP = child.getNotPlayed();
- node = child;
- estimate = estimate * 0.5 + childP / (childP + childNP) * 0.5;
- }
-
- if (DEBUG)
- System.err.println("Model::getScores following a " + BoardI.colourString(colour)
- + " branch, estimate = " + estimate + ", childP = " + childP
+ ", childNP = "
- + childNP + ", combination = " + childP / (childP + childNP)
* 0.5);
- }
-
- // estimate = (1 + previous.getPlayed()) / (previous.getPlayed()
+ previous.getNotPlayed()) * (1 -
- // (1 /depth));
- if (result[row][column] < estimate) {
- result[row][column] = estimate;
- if (DEBUG)
- System.err.println("Model::getScores " + estimate);
- }
- if (DEBUG)
- System.err.println("Model::getScores " + maxdepth);
- }
- }
- }
- return result;
- }
-
- /**
- * Train.
- *
- * @param game
- * the game
- */
- public void train(Game game) {
- short size = game.getSize();
- Iterator<BoardI> boards = game.getBoards();
- if (boards == null)
- throw new Error();
- Iterator<Move> moves = game.getMoves();
- if (moves == null)
- throw new Error();
- int movecounter = 1;
-
- //double strengthB = game.getBlackRank().getRating();
- //double strengthW = game.getWhiteRank().getRating();
-
- while (boards.hasNext() && moves.hasNext()) {
- movecounter++;
- BoardI board = boards.next();
- if (board == null)
- throw new Error();
- Move move = moves.next();
- if (move == null)
- throw new Error();
- if (DEBUG)
- System.err.println("Model::train next board is: \n" + board);
- if (DEBUG)
- System.err.println("Model::train about to train on: " + move);
- int colour = move.getColour();
- boolean isBlack = colour == BoardI.VERTEX_BLACK;
- // float str = (float) (isBlack ? strengthB : strengthW);
-
- if (game != null || move.getPass()) {
- movecounter++;
- for (short i = 0; i < size; i++)
- for (short j = 0; j < size; j++)
- for (short sym = 0; sym < 8; sym++) {
- // TODO this needs a lot of work, i think
-
- VertexLineariser linear = new VertexLineariser(board, i, j, sym, !isBlack);
- if (!move.getPass() && move.getRow() != i &&
move.getColumn() != j)
- this.root.train(linear, true, true, 100);
- else
- this.root.train(linear, false, true, 30);
- }
- }
- }
- }
}

Modified: trunk/jgogears/jgogears/engine/ModelTest.java
==============================================================================
--- trunk/jgogears/jgogears/engine/ModelTest.java (original)
+++ trunk/jgogears/jgogears/engine/ModelTest.java Thu Mar 6 16:42:16 2008
@@ -18,50 +18,6 @@
/** The model. */
static Model model = null;

- /**
- * Train n files.
- *
- * @param count
- * the count
- * @param model
- * the model
- * @return the model
- * @throws IOException
- * Signals that an I/O exception has occurred.
- */
- public static Model trainNFiles(int count, Model model) throws
IOException {
- Stack<String> files = new Stack<String>();
- files.push("sgf/2004-12");
- assertNotNull(files);
-
- int filecount = 0;
- assertNotNull(model);
- Date start = new Date();
- assertNotNull(start);
-
- while (files.size() > 0 && filecount < count) {
- String filename = files.pop();
- File file = new File(filename);
- if (file.exists()) {
- if (!file.isDirectory()) {
-
- Game game = Game.loadFromFile(file);
- if (game.getSize() == 19) {
- filecount++;
- model.train(game);
- }
- } else {
- String[] children = file.list();
- for (int i = 0; i < children.length; i++) {
- files.push(filename + "/" + children[i]);
- }
- }
- }
- }
- if (DEBUG)
- System.err.println("ModelTest::trainNFiles loaded " + filecount + " files ");
- return model;
- }

/**
* Instantiates a new model test.
@@ -72,7 +28,7 @@
public ModelTest() throws IOException {
if (model == null) {
model = new Model();
- ModelTest.trainNFiles(10, model);
+ new Trainer().trainNFiles(10, model);
}
}

@@ -160,7 +116,7 @@
public void testEmptyModelEmptyBoard() throws IOException {
assertNotNull(model);
BoardI board = BoardI.newBoard();
- double[][] r = new Model().getScores(board, false);
+ double[][] r = new Scorer().getScores(model,board, false);
assertNotNull(r);
assertTrue(r.length == r[0].length);
if (DEBUG) {
@@ -199,7 +155,7 @@
board = board.newBoard(new Move("white d4"));
board = board.newBoard(new Move("black a4"));
board = board.newBoard(new Move("white d2"));
- double[][] r = model.getScores(board, false);
+ double[][] r = new Scorer().getScores(model, board, false);
assertNotNull(r);
if (DEBUG)
System.err.println("ModelTest::testLoadAllSGFFiles() ");
@@ -273,7 +229,7 @@
public void testTrainedModel() throws IOException {
assertNotNull(model);
System.err.println("ModeTest::testTrainedModel() model size = " + model.getRoot().size());
- model.train(this.loadTestGame());
+ new Trainer().train(model,this.loadTestGame());
System.err.println("ModeTest::testTrainedModel() model size = " + model.getRoot().size());
BoardI board = BoardI.newBoard(19);
board = board.newBoard(new Move("white b2"));
@@ -283,7 +239,7 @@
board = board.newBoard(new Move("white d4"));
board = board.newBoard(new Move("black h4"));
board = board.newBoard(new Move("white n4"));
- double[][] r = model.getScores(board, false);
+ double[][] r = new Scorer().getScores(model, board, false);
assertNotNull(r);
if (DEBUG) {
System.err.println("ModeTest::testTrainedModel() Double.MIN_VALUE "
+ Double.MIN_VALUE);
@@ -304,10 +260,10 @@
public void testTrainedModelEmptyBoard() throws IOException {
assertNotNull(model);
System.err.println("ModeTest::testTrainedModelEmptyBoard() model
size = " + model.getRoot().size());
- model.train(this.loadTestGame());
+ new Trainer().train(model,this.loadTestGame());
System.err.println("ModeTest::testTrainedModelEmptyBoard() model
size = " + model.getRoot().size());
BoardI board = BoardI.newBoard(19);
- double[][] r = model.getScores(board, false);
+ double[][] r = new Scorer().getScores(model,board, false);
assertNotNull(r);
assertTrue(r.length == r[0].length);
if (DEBUG) {

Modified: trunk/jgogears/jgogears/engine/Node.java
==============================================================================
--- trunk/jgogears/jgogears/engine/Node.java (original)
+++ trunk/jgogears/jgogears/engine/Node.java Thu Mar 6 16:42:16 2008
@@ -83,65 +83,65 @@
public final Node getEmpty() {
return this.empty;
}
-/**
- * find a particular leaf in this tree
- * @param board
- * @param colour
- * @param row
- * @param column
- * @param sym
- * @param node
- * @return the leaf node
- */
- static public Node getLeaf(BoardI board, short colour, short row,
short column, short sym, Node node) {
- if (board == null)
- throw new Error();
- VertexLineariser linear = null;
- boolean invert = colour == BoardI.VERTEX_WHITE;
-
- linear = new VertexLineariser(board, row, column, sym, invert);
- if (!linear.hasNext())
- throw new Error();
- return getLeaf(linear, node);
-
- }
- /**
- * find a particular leaf in this tree
- * @param linear the linearisation to use
- * @param node the root node to use
- * @return the leaf node
- */
-
- static public Node getLeaf(VertexLineariser linear, Node node) {
- if (!linear.hasNext())
- throw new Error();
-
- while (linear.hasNext()) {
- Node child = null;
- Short colour = linear.next();
- switch (colour) {
- case BoardI.VERTEX_BLACK:
- child = node.black;
- break;
- case BoardI.VERTEX_WHITE:
- child = node.white;
- break;
- case BoardI.VERTEX_OFF_BOARD:
- child = node.off;
- break;
- case BoardI.VERTEX_KO:
- case BoardI.VERTEX_EMPTY:
- child = node.empty;
- break;
- default:
- throw new Error("Unknown vertex colour: " + colour);
- }
- if (child == null)
- return node;
- node = child;
- }
- return node;
- }
+///**
+// * find a particular leaf in this tree
+// * @param board
+// * @param colour
+// * @param row
+// * @param column
+// * @param sym
+// * @param node
+// * @return the leaf node
+// */
+// static public Node getLeaf(BoardI board, short colour, short row,
short column, short sym, Node node) {
+// if (board == null)
+// throw new Error();
+// VertexLineariser linear = null;
+// boolean invert = colour == BoardI.VERTEX_WHITE;
+//
+// linear = new VertexLineariser(board, row, column, sym, invert);
+// if (!linear.hasNext())
+// throw new Error();
+// return getLeaf(linear, node);
+//
+// }
+// /**
+// * find a particular leaf in this tree
+// * @param linear the linearisation to use
+// * @param node the root node to use
+// * @return the leaf node
+// */
+//
+// static public Node getLeaf(VertexLineariser linear, Node node) {
+// if (!linear.hasNext())
+// throw new Error();
+//
+// while (linear.hasNext()) {
+// Node child = null;
+// Short colour = linear.next();
+// switch (colour) {
+// case BoardI.VERTEX_BLACK:
+// child = node.black;
+// break;
+// case BoardI.VERTEX_WHITE:
+// child = node.white;
+// break;
+// case BoardI.VERTEX_OFF_BOARD:
+// child = node.off;
+// break;
+// case BoardI.VERTEX_KO:
+// case BoardI.VERTEX_EMPTY:
+// child = node.empty;
+// break;
+// default:
+// throw new Error("Unknown vertex colour: " + colour);
+// }
+// if (child == null)
+// return node;
+// node = child;
+// }
+// return node;
+// }

/**
* how many times has this node not been played?
@@ -278,78 +278,4 @@
return result;
}

- /**
- * Train.
- *
- * @param linear
- * the linear
- * @param expand
- * are we expanding?
- * @param depth
- * the depth to expand to
- * @param playeda
- * the played
- */
- public void train(VertexLineariser linear, boolean playeda, boolean
expand, int depth) {
- if (depth <= 0)
- expand = false;
- if (this.notPlayed + this.played < 100)
- expand = false;
- depth--;
- if (playeda)
- this.played++;
- else
- this.notPlayed++;
- if (!linear.hasNext())
- return;
- Short colour = linear.next();
-
- switch (colour) {
- case BoardI.VERTEX_BLACK:
- if (this.black == null)
- if (expand) {
- this.black = new Node();
- this.black.train(linear, playeda, false, depth);
- } else
- return;
- else
- this.black.train(linear, playeda, expand, depth);
- break;
- case BoardI.VERTEX_WHITE:
- if (this.white == null)
- if (expand) {
- this.white = new Node();
- this.white.train(linear, playeda, false, depth);
- } else
- return;
- else
- this.white.train(linear, playeda, expand, depth);
- break;
- case BoardI.VERTEX_OFF_BOARD:
- if (this.off == null)
-
- if (expand) {
- this.off = new Node();
- this.off.train(linear, playeda, false, depth);
- } else
- return;
- else
- this.off.train(linear, playeda, expand, depth);
-
- break;
- case BoardI.VERTEX_EMPTY:
- case BoardI.VERTEX_KO:
- if (this.empty == null)
- if (expand) {
- this.empty = new Node();
- this.empty.train(linear, playeda, false, depth);
- } else
- return;
- else
- this.empty.train(linear, playeda, expand, depth);
- break;
- default:
- throw new Error();
- }
- }
}

Added: trunk/jgogears/jgogears/engine/Scorer.java
==============================================================================
--- (empty file)
+++ trunk/jgogears/jgogears/engine/Scorer.java Thu Mar 6 16:42:16 2008
@@ -0,0 +1,120 @@
+/**
+ *
+ */
+package jgogears.engine;
+
+import jgogears.*;
+
+/**
+ * TODO
+ * @author syeates
+ *
+ */
+public class Scorer {
+ /** are we being verbose? */
+ public static boolean DEBUG = false;
+
+ /**
+ * Which vertex is the best to play?
+ *
+ * @param board
+ * the board we're playing on
+ * @param white
+ * is white to play?
+ * @param model
+ * @return the vertex to play
+ */
+ Vertex getBestScore(Model model, BoardI board, boolean white) {
+ double[][] result = this.getScores(model, board, white);
+ double best = Double.MAX_VALUE;
+ int I = 0, J = 0;
+ int i, j;
+ for (i = 0; i < board.getSize(); i++)
+ for (j = 0; j < board.getSize(); j++) {
+ if (result[i][j] < best) {
+ if (RuleSet.DEFAULT.moveIsLegal(null, board, new Move(i, j,
white ? BoardI.VERTEX_WHITE
+ : BoardI.VERTEX_BLACK))) {
+ best = result[i][j];
+ I = i;
+ J = j;
+ }
+ }
+ }
+ return new Vertex(I, J);
+ }
+
+ /**
+ * TODO
+ *
+ * @param board
+ * @param white
+ * @param model
+ * @return the array of scores
+ */
+ public double[][] getScores(Model model,BoardI board, boolean white) {
+ short size = board.getSize();
+ double[][] result = new double[size][size];
+ for (short row = 0; row < size; row++) {
+ for (short column = 0; column < size; column++) {
+ for (short sym = 0; sym < 8; sym++) {
+ result[row][column] = 0.0;
+ Node node = model.getRoot();
+ int maxdepth = 0;
+ VertexLineariser linear = new VertexLineariser(board, row,
column, sym, white);
+ double estimate = 1.0;
+ int depth = 0;
+ while (linear.hasNext() && node != null) {
+ depth++;
+ if (depth > maxdepth)
+ maxdepth = depth;
+ short colour = linear.next();
+ Node child = null;
+
+ switch (colour) {
+ case BoardI.VERTEX_BLACK:
+ child = node.getBlack();
+ break;
+ case BoardI.VERTEX_WHITE:
+ child = node.getWhite();
+ break;
+ case BoardI.VERTEX_OFF_BOARD:
+ child = node.getOff();
+ break;
+ case BoardI.VERTEX_KO:
+ case BoardI.VERTEX_EMPTY:
+ child = node.getEmpty();
+ break;
+ default:
+ throw new Error("Unknown vertex colour: " + colour);
+ }
+ double childP = 1;
+ double childNP = 1;
+ if (child != null) {
+ childP = child.getPlayed();
+ childNP = child.getNotPlayed();
+ node = child;
+ estimate = estimate * 0.5 + childP / (childP + childNP) * 0.5;
+ }
+
+ if (DEBUG)
+ System.err.println("Model::getScores following a " + BoardI.colourString(colour)
+ + " branch, estimate = " + estimate + ", childP = " + childP
+ ", childNP = "
+ + childNP + ", combination = " + childP / (childP + childNP)
* 0.5);
+ }
+
+ // estimate = (1 + previous.getPlayed()) / (previous.getPlayed()
+ previous.getNotPlayed()) * (1 -
+ // (1 /depth));
+ if (result[row][column] < estimate) {
+ result[row][column] = estimate;
+ if (DEBUG)
+ System.err.println("Model::getScores " + estimate);
+ }
+ if (DEBUG)
+ System.err.println("Model::getScores " + maxdepth);
+ }
+ }
+ }
+ return result;
+ }
+
+}

Modified: trunk/jgogears/jgogears/engine/SufgoEngine.java
==============================================================================
--- trunk/jgogears/jgogears/engine/SufgoEngine.java (original)
+++ trunk/jgogears/jgogears/engine/SufgoEngine.java Thu Mar 6 16:42:16 2008
@@ -82,7 +82,7 @@
public Move regGenMove(int colour, GTPState state) {
BoardI board = state.getBoard();

- Vertex vertex = this.model.getBestScore(board, colour == BoardI.VERTEX_WHITE);
+ Vertex vertex = new Scorer().getBestScore(this.model, board, colour
== BoardI.VERTEX_WHITE);

return new Move(vertex.getRow(), vertex.getColumn(), colour);
}

Modified: trunk/jgogears/jgogears/engine/SufogoEngineTest.java
==============================================================================
--- trunk/jgogears/jgogears/engine/SufogoEngineTest.java (original)
+++ trunk/jgogears/jgogears/engine/SufogoEngineTest.java Thu Mar 6
16:42:16 2008
@@ -28,7 +28,7 @@
// TODO make sure this terminates
GTPState state = new GTPState();
Model model = new Model();
- ModelTest.trainNFiles(10, model);
+ new Trainer().trainNFiles(10, model);

SufgoEngine black = new SufgoEngine();
black.setModel(model);

Added: trunk/jgogears/jgogears/engine/Trainer.java
==============================================================================
--- (empty file)
+++ trunk/jgogears/jgogears/engine/Trainer.java Thu Mar 6 16:42:16 2008
@@ -0,0 +1,184 @@
+/**
+ *
+ */
+package jgogears.engine;
+
+import java.io.*;
+import java.util.*;
+
+import jgogears.*;
+
+/**
+ * TODO
+ * @author syeates
+ *
+ */
+public class Trainer {
+ static final private boolean DEBUG = false;
+
+
+ /**
+ * Train n files.
+ *
+ * @param count
+ * the count
+ * @param model
+ * the model
+ * @return the model
+ * @throws IOException
+ * Signals that an I/O exception has occurred.
+ */
+ public Model trainNFiles(int count, Model model) throws IOException {
+ Stack<String> files = new Stack<String>();
+ files.push("sgf/2004-12");
+
+ int filecount = 0;
+
+ while (files.size() > 0 && filecount < count) {
+ String filename = files.pop();
+ File file = new File(filename);
+ if (file.exists()) {
+ if (!file.isDirectory()) {
+
+ Game game = Game.loadFromFile(file);
+ if (game.getSize() == 19) {
+ filecount++;
+ train(model, game);
+ }
+ } else {
+ String[] children = file.list();
+ for (int i = 0; i < children.length; i++) {
+ files.push(filename + "/" + children[i]);
+ }
+ }
+ }
+ }
+ if (DEBUG)
+ System.err.println("Trainer::trainNFiles loaded " + filecount + " files ");
+ return model;
+ }
+
+
+ /**
+ * Train.
+ *
+ * @param game
+ * the game
+ */
+ public void train(Model model, Game game) {
+ short size = game.getSize();
+ Iterator<BoardI> boards = game.getBoards();
+ if (boards == null)
+ throw new Error();
+ Iterator<Move> moves = game.getMoves();
+ if (moves == null)
+ throw new Error();
+ int movecounter = 1;
+
+ while (boards.hasNext() && moves.hasNext()) {
+ movecounter++;
+ BoardI board = boards.next();
+ if (board == null)
+ throw new Error();
+ Move move = moves.next();
+ if (move == null)
+ throw new Error();
+ if (DEBUG)
+ System.err.println("Model::train next board is: \n" + board);
+ if (DEBUG)
+ System.err.println("Model::train about to train on: " + move);
+ int colour = move.getColour();
+ boolean isBlack = colour == BoardI.VERTEX_BLACK;
+ // float str = (float) (isBlack ? strengthB : strengthW);
+
+ if (game != null || move.getPass()) {
+ movecounter++;
+ for (short i = 0; i < size; i++)
+ for (short j = 0; j < size; j++)
+ for (short sym = 0; sym < 8; sym++) {
+ // TODO this needs a lot of work, i think
+
+ VertexLineariser linear = new VertexLineariser(board, i, j, sym, !isBlack);
+ if (!move.getPass() && move.getRow() != i &&
move.getColumn() != j)
+ train(model.getRoot(),linear, true, true, 100);
+ else
+ train(model.getRoot(),linear, false, true, 30);
+ }
+ }
+ }
+ }
+
+ /**
+ * Train.
+ *
+ * @param linear
+ * the linear
+ * @param expand
+ * are we expanding?
+ * @param depth
+ * the depth to expand to
+ * @param playeda
+ * the played
+ */
+ public void train(Node root, VertexLineariser linear, boolean
playeda, boolean expand, int depth) {
+ if (depth <= 0)
+ expand = false;
+ if (root.getNotPlayed() + root.getPlayed() < 100)
+ expand = false;
+ depth--;
+ if (playeda)
+ root.setPlayed(root.getPlayed() +1);
+ else
+ root.setNotPlayed(root.getNotPlayed() +1);
+ if (!linear.hasNext())
+ return;
+ Short colour = linear.next();
+
+ switch (colour) {
+ case BoardI.VERTEX_BLACK:
+ if (root.getBlack() == null)
+ if (expand) {
+ root.setBlack(new Node());
+ train(root.getBlack(),linear, playeda, false, depth);
+ } else
+ return;
+ else
+ train(root.getBlack(),linear, playeda, expand, depth);
+ break;
+ case BoardI.VERTEX_WHITE:
+ if (root.getWhite() == null)
+ if (expand) {
+ root.setWhite(new Node());
+ train(root.getWhite(),linear, playeda, false, depth);
+ } else
+ return;
+ else
+ train(root.getWhite(),linear, playeda, expand, depth);
+ break;
+ case BoardI.VERTEX_KO:
+ case BoardI.VERTEX_EMPTY:
+ if (root.getEmpty() == null)
+ if (expand) {
+ root.setEmpty(new Node());
+ train(root.getEmpty(),linear, playeda, false, depth);
+ } else
+ return;
+ else
+ train(root.getEmpty(),linear, playeda, expand, depth);
+ break;
+ case BoardI.VERTEX_OFF_BOARD:
+ if (root.getOff() == null)
+ if (expand) {
+ root.setOff(new Node());
+ train(root.getOff(),linear, playeda, false, depth);
+ } else
+ return;
+ else
+ train(root.getOff(),linear, playeda, expand, depth);
+ break;
+ default:
+ throw new Error();
+ }
+ }
+
+}

Reply all
Reply to author
Forward
0 new messages