From aca83206002ca542a8a0fe34eec844b60d5ce7c7 Mon Sep 17 00:00:00 2001 From: Woody Folsom Date: Sat, 17 Nov 2012 18:40:31 -0500 Subject: [PATCH] First working implementation of ANN which is trained using GameResults. The PassFilter simply outputs BlackWins and WhiteWins (Range 0 - 1 but not presently clamped). In principle, this type of feedforward ANN can be used to decide whether a PASS will result in blackwins or whitewins at any stage. The goal is for the network to learn that passing while losing when valid moves exist is bad, but passing while winning is relatively harmless later in the game. --- data/SGF.g | 13 +- data/games/pro9x9/game002.sgf | 2 +- .../pro9x9/{game003.sgf => game003.sgf.time} | 0 data/games/pro9x9/game004.sgf | 4 +- data/games/pro9x9/game005.sgf | 4 +- data/games/pro9x9/game006.sgf | 4 +- data/games/pro9x9/game007.sgf | 4 +- data/games/pro9x9/game008.sgf | 4 +- data/games/pro9x9/game009.sgf | 4 +- .../pro9x9/{game010.sgf => game010.sgf.time} | 0 data/games/pro9x9/game011.sgf | 4 +- data/networks/Pass1.nn | Bin 0 -> 3701 bytes data/test/scoretest1.sgf | 1 + data/tourney1/gogame-121117181002-0500.sgf | 1 + data/tourney1/gogame-121117181051-0500.sgf | 1 + data/tourney1/gogame-121117181139-0500.sgf | 1 + data/tourney1/gogame-121117181230-0500.sgf | 1 + data/tourney1/gogame-121117181328-0500.sgf | 1 + data/tourney1/gogame-121117181405-0500.sgf | 1 + data/tourney1/gotournament-121117181405.txt | 9 + src/net/woodyfolsom/msproj/GameBoard.java | 33 + src/net/woodyfolsom/msproj/GameState.java | 4 + src/net/woodyfolsom/msproj/SGFWriter.java | 1 + .../woodyfolsom/msproj/StandAloneGame.java | 49 +- src/net/woodyfolsom/msproj/ann/PassData.java | 98 +++ .../woodyfolsom/msproj/ann/PassLearner.java | 109 ++- .../woodyfolsom/msproj/policy/MonteCarlo.java | 4 +- .../msproj/policy/MonteCarloUCT.java | 17 +- .../msproj/policy/RandomMovePolicy.java | 25 +- .../msproj/policy/RootParallelization.java | 28 +- src/net/woodyfolsom/msproj/sgf/SGF.tokens | 60 +- src/net/woodyfolsom/msproj/sgf/SGFLexer.java | 732 ++++++++++-------- src/net/woodyfolsom/msproj/sgf/SGFNode.java | 4 + src/net/woodyfolsom/msproj/sgf/SGFParser.java | 242 +++--- .../net/woodyfolsom/msproj/GameBoardTest.java | 29 + .../net/woodyfolsom/msproj/GameScoreTest.java | 60 +- .../msproj/ann/PassNetworkTest.java | 30 + 37 files changed, 1040 insertions(+), 544 deletions(-) rename data/games/pro9x9/{game003.sgf => game003.sgf.time} (100%) rename data/games/pro9x9/{game010.sgf => game010.sgf.time} (100%) create mode 100644 data/networks/Pass1.nn create mode 100644 data/test/scoretest1.sgf create mode 100644 data/tourney1/gogame-121117181002-0500.sgf create mode 100644 data/tourney1/gogame-121117181051-0500.sgf create mode 100644 data/tourney1/gogame-121117181139-0500.sgf create mode 100644 data/tourney1/gogame-121117181230-0500.sgf create mode 100644 data/tourney1/gogame-121117181328-0500.sgf create mode 100644 data/tourney1/gogame-121117181405-0500.sgf create mode 100644 data/tourney1/gotournament-121117181405.txt create mode 100644 src/net/woodyfolsom/msproj/ann/PassData.java create mode 100644 test/net/woodyfolsom/msproj/GameBoardTest.java create mode 100644 test/net/woodyfolsom/msproj/ann/PassNetworkTest.java diff --git a/data/SGF.g b/data/SGF.g index e9855e2..4e24994 100644 --- a/data/SGF.g +++ b/data/SGF.g @@ -139,7 +139,7 @@ blackRank whiteRank : 'WR'; -komi : 'KM'; +komi : 'KM' | 'KoMi'; result : 'RE' | 'REsult' @@ -169,7 +169,7 @@ copyright username: 'US'; -comment : 'C'; +comment : 'C' | 'Comment'; strValue : (STRVALUE)+; @@ -190,11 +190,14 @@ PLUS : '+'; SLASH : '/'; - -STRVALUE : (UCLETTER | LCLETTER | MINUS | DIGIT | SPACE | PERIOD | COMMA | PLUS | SLASH | COLON )+; LPAREN : '(' ; +RPAREN : ')'; + +STRVALUE : (UCLETTER | LCLETTER | MINUS | DIGIT | SPACE | PERIOD | COMMA | PLUS | SLASH | COLON | LPAREN | RPAREN )+; + + SEMICOLON : ';' ; fragment UCLETTER : 'A'..'Z'; @@ -206,8 +209,6 @@ LBRACKET RBRACKET : ']'; - -RPAREN : ')'; //CR : '\r'{$channel=HIDDEN;}; diff --git a/data/games/pro9x9/game002.sgf b/data/games/pro9x9/game002.sgf index 3412982..3862ae6 100644 --- a/data/games/pro9x9/game002.sgf +++ b/data/games/pro9x9/game002.sgf @@ -28,7 +28,7 @@ DaTe[1968] PlaCe[] -REsult[Black wins by four points] +REsult[B+4] C[This was the second and last game in a two game match on 9x9, diff --git a/data/games/pro9x9/game003.sgf b/data/games/pro9x9/game003.sgf.time similarity index 100% rename from data/games/pro9x9/game003.sgf rename to data/games/pro9x9/game003.sgf.time diff --git a/data/games/pro9x9/game004.sgf b/data/games/pro9x9/game004.sgf index 25b9d56..086975f 100644 --- a/data/games/pro9x9/game004.sgf +++ b/data/games/pro9x9/game004.sgf @@ -13,7 +13,7 @@ VieW[] SiZe[9] -KoMi[5 1/2] +KoMi[5.5] EVent[TV game] @@ -31,7 +31,7 @@ DaTe[1992] PlaCe[Osaka] -REsult[White wins by 11 1/2] +REsult[W+11.5] Comment[ diff --git a/data/games/pro9x9/game005.sgf b/data/games/pro9x9/game005.sgf index 92931a3..4f548a4 100644 --- a/data/games/pro9x9/game005.sgf +++ b/data/games/pro9x9/game005.sgf @@ -13,7 +13,7 @@ VieW[] SiZe[9] -KoMi[5 1/2] +KoMi[5.5] EVent[TV game] @@ -31,7 +31,7 @@ DaTe[1992] PlaCe[Osaka] -REsult[Black wins by 1/2 point] +REsult[B+0.5] Comment[ diff --git a/data/games/pro9x9/game006.sgf b/data/games/pro9x9/game006.sgf index c122d85..96d9a5c 100644 --- a/data/games/pro9x9/game006.sgf +++ b/data/games/pro9x9/game006.sgf @@ -13,7 +13,7 @@ VieW[] SiZe[9] -KoMi[5 1/2] +KoMi[5.5] EVent[TV game] @@ -31,7 +31,7 @@ DaTe[1992] PlaCe[Osaka] -REsult[White wins by 4 1/2] +REsult[W+4.5] Comment[ diff --git a/data/games/pro9x9/game007.sgf b/data/games/pro9x9/game007.sgf index 3bf3fb9..b86f03b 100644 --- a/data/games/pro9x9/game007.sgf +++ b/data/games/pro9x9/game007.sgf @@ -13,7 +13,7 @@ VieW[] SiZe[9] -KoMi[5 1/2] +KoMi[5.5] EVent[TV game] @@ -31,7 +31,7 @@ DaTe[1992] PlaCe[Osaka] -REsult[Black wins by 1/2] +REsult[B+0.5] Comment[ diff --git a/data/games/pro9x9/game008.sgf b/data/games/pro9x9/game008.sgf index d938085..b4afe9e 100644 --- a/data/games/pro9x9/game008.sgf +++ b/data/games/pro9x9/game008.sgf @@ -13,7 +13,7 @@ VieW[] SiZe[9] -KoMi[5 1/2] +KoMi[5.5] EVent[TV game] @@ -31,7 +31,7 @@ DaTe[1992] PlaCe[Osaka] -REsult[Black wins by 5 1/2] +REsult[B+5.5] Comment[ diff --git a/data/games/pro9x9/game009.sgf b/data/games/pro9x9/game009.sgf index 8950cd1..52d423d 100644 --- a/data/games/pro9x9/game009.sgf +++ b/data/games/pro9x9/game009.sgf @@ -13,7 +13,7 @@ VieW[] SiZe[9] -KoMi[5 1/2] +KoMi[5.5] EVent[TV game] @@ -31,7 +31,7 @@ DaTe[1992] PlaCe[Osaka] -REsult[White wins by 3 1/2] +REsult[W+3.5] Comment[ diff --git a/data/games/pro9x9/game010.sgf b/data/games/pro9x9/game010.sgf.time similarity index 100% rename from data/games/pro9x9/game010.sgf rename to data/games/pro9x9/game010.sgf.time diff --git a/data/games/pro9x9/game011.sgf b/data/games/pro9x9/game011.sgf index ef46659..85469b0 100644 --- a/data/games/pro9x9/game011.sgf +++ b/data/games/pro9x9/game011.sgf @@ -13,7 +13,7 @@ VieW[] SiZe[9] -KoMi[5 1/2] +KoMi[5.5] EVent[TV game] @@ -31,7 +31,7 @@ DaTe[1992] PlaCe[Osaka] -REsult[Black wins by 4 1/2] +REsult[B+4.5] Comment[ diff --git a/data/networks/Pass1.nn b/data/networks/Pass1.nn new file mode 100644 index 0000000000000000000000000000000000000000..43292b07376f51f204a030c4449e76d7f59f7104 GIT binary patch literal 3701 zcma)9-ES0C6u;fwvZYYA6jIU3SNV`aorM>J1+#qYQnpU9c1w&Pp_koZcVu>EoVn9( zYeY1@nV9H<1{41RjV3;rXiUJ5L=qqTh!4g$lm{O)5)y*ZD4uif?0oEYE1PsWbMN{1 zo!>e4%$fIoXWg#Dc34hTF*VPz?3!YlnouS^L+C1B(3~mFDQmWHER)G!BEeY0VVj~l zWy{f&6JUTFCp0l{ITw84RDz{dwpurBPvE{~x`Oqq&+<8*^@MI@RoxW_RMu_qbDAO8 zfZQ^;SkLR8XxKpHIt)xf3FWZk@CA&n@zVDj zFMq|~NwTgYOS$@@*06z{#C!^_y`Z!;$|SL0w(7Q03_0`3?2^pi7nKi~5Au^tuoWun zC(4gnV6QB6pxqC*kJgWQCans#GZq`sM-o|b-;@h7gjSL&TLVnC+g@dJM>7SLjbIzv zEz=Iz>K6_--Se8$v@h6byL3}1JJTYKTqBSk7<6I!L@)#F5N z@1PJ1-B*FChuX`yUcC;b7vf%`{3L(iEh-67XXXirdk@MIav&*->wyk%!?@^ZVjXsh ztVsn$7$w6F84U|_sLf%R^H3Seq4&IF)#dRP?Edyl$}OOvM_BS6)At~pY)Q$IN)juC zj}f1XylA zh!S&HGF^GrJ;x0Xj{Mc3O|O4*?an$>-X)EJi7ioz!?S-x=dL6w4HN+K*aDXg! ziZH~!7j0~&=h58HzdV$=ed!D?DR_VeqhP49(1Gfjwk%x6% znuk}_?zXrB-PYD3&7d9DuyZ&4NBbAM+Of4+A6IxbBuOGm6=_lKGH8x9&Mkl}kt`V2Q~ep;aG;W={+%hpKsu|xij z#Gkvl`_4y;G}ChhyFR$~ z#>A(%^vJUDL{c@5(xuLjul)1y&c}C5>_@RZBsNBo8BqYk4Z#>KV?9UmF@|chcsY%o zX+zhnd5xAK~Q-HVm-5%5mO_#otr+g`gRXbT)-1rj{~+^KPt(#37XQ zYTeQ+c^F_h4yB=QRNUCvp*mUeW&NRgG%8DJ4dN_$w&u*~u2yMIwZ1C!<-{qr@*EfC z+N4#{@~o%M8wJO)9PqxUv&Ev&9N=nBYcU8llPa?QvghD5=Sx}UDYjOZ8Zb?&dL14r z`N%ZRg;r#J;5yK7!T-+A{+n*&ly$*-1Yaw`TLO#VQ8@*q8SDO$Av~{5W@OFwb|VfBNi;!P)PUEOCtW8Wyh{<7HtvMYdAZ z9L=p+Mg@BQA+oc29t*M`{<`K`zK>|S_dgmG6+c_tDf)yUMW|w$6yci%cMwju$_8Q) zkrM7CfuLoW3mB>L@teOViG!wh$Sf!p6mx z37W9r5E5hpzjOQ`*#Lb6t|6B3YfUMb!FWxZwqS#kC)JtaS@rPKh3T_Xh3TV(shQ~~ GPW%UUyCOdT literal 0 HcmV?d00001 diff --git a/data/test/scoretest1.sgf b/data/test/scoretest1.sgf new file mode 100644 index 0000000..fd10cfe --- /dev/null +++ b/data/test/scoretest1.sgf @@ -0,0 +1 @@ +(;FF[4]GM[1]SZ[5]KM[3.5]RE[W+11.5];B[ad];W[bd];B[be];W[ed];B[dd];W[ba];B[cd];W[ca];B[ee];W[cb];B[];W[dc];B[db];W[ac];B[];W[ec];B[ae];W[bc];B[ce];W[cc];B[aa];W[de];B[be];W[];B[ce];W[ad];B[dd];W[];B[ea];W[eb];B[ae];W[];B[ee];W[da];B[bb];W[de];B[];W[]) \ No newline at end of file diff --git a/data/tourney1/gogame-121117181002-0500.sgf b/data/tourney1/gogame-121117181002-0500.sgf new file mode 100644 index 0000000..148ef31 --- /dev/null +++ b/data/tourney1/gogame-121117181002-0500.sgf @@ -0,0 +1 @@ +(;FF[4]GM[1]SZ[6]KM[1.5]RE[W+26.5];B[ab];W[ff];B[ca];W[df];B[de];W[ce];B[cf];W[ba];B[aa];W[eb];B[be];W[bf];B[dc];W[ea];B[bc];W[cc];B[dd];W[fc];B[ad];W[db];B[fd];W[fa];B[cb];W[ed];B[];W[ec];B[fe];W[af];B[cd];W[ef];B[];W[ae];B[];W[bd];B[];W[ac];B[bb];W[da];B[ad];W[ee];B[];W[cc];B[dc];W[dd];B[];W[ac];B[];W[fd];B[];W[ba];B[aa];W[cb];B[];W[ab];B[];W[bc];B[];W[]) \ No newline at end of file diff --git a/data/tourney1/gogame-121117181051-0500.sgf b/data/tourney1/gogame-121117181051-0500.sgf new file mode 100644 index 0000000..f179526 --- /dev/null +++ b/data/tourney1/gogame-121117181051-0500.sgf @@ -0,0 +1 @@ +(;FF[4]GM[1]SZ[6]KM[1.5]RE[B+1.5];B[de];W[eb];B[af];W[ce];B[df];W[ef];B[cb];W[ff];B[cd];W[be];B[ee];W[db];B[ad];W[ea];B[ed];W[fc];B[fe];W[cc];B[bc];W[ef];B[];W[fa];B[ae];W[ba];B[];W[ac];B[];W[cf];B[ca];W[ec];B[dd];W[dc];B[bb];W[bd];B[];W[da];B[bf];W[ce];B[ab];W[];B[aa];W[be];B[];W[cf];B[];W[fd];B[];W[]) \ No newline at end of file diff --git a/data/tourney1/gogame-121117181139-0500.sgf b/data/tourney1/gogame-121117181139-0500.sgf new file mode 100644 index 0000000..fd89272 --- /dev/null +++ b/data/tourney1/gogame-121117181139-0500.sgf @@ -0,0 +1 @@ +(;FF[4]GM[1]SZ[6]KM[1.5]RE[W+16.5];B[bc];W[ff];B[fb];W[eb];B[ee];W[ce];B[de];W[ef];B[fe];W[df];B[ea];W[fc];B[];W[db];B[ed];W[fa];B[ab];W[fd];B[cd];W[aa];B[];W[cc];B[af];W[bb];B[bf];W[ec];B[cb];W[be];B[ca];W[dd];B[ac];W[cf];B[de];W[bd];B[ed];W[ae];B[ba];W[bf];B[];W[da];B[];W[fe];B[];W[ee];B[];W[ad];B[];W[]) \ No newline at end of file diff --git a/data/tourney1/gogame-121117181230-0500.sgf b/data/tourney1/gogame-121117181230-0500.sgf new file mode 100644 index 0000000..efb97ce --- /dev/null +++ b/data/tourney1/gogame-121117181230-0500.sgf @@ -0,0 +1 @@ +(;FF[4]GM[1]SZ[6]KM[1.5]RE[W+4.5];B[eb];W[bf];B[ff];W[dc];B[ba];W[bc];B[ce];W[cd];B[df];W[ee];B[be];W[af];B[ec];W[ca];B[ea];W[ed];B[fc];W[];B[ef];W[];B[fd];W[fe];B[cf];W[dd];B[cc];W[ad];B[bd];W[ae];B[fb];W[de];B[ab];W[ac];B[bb];W[];B[ce];W[];B[be];W[cb];B[df];W[aa];B[cf];W[bb];B[ff];W[];B[bd];W[];B[db];W[];B[da];W[];B[]) \ No newline at end of file diff --git a/data/tourney1/gogame-121117181328-0500.sgf b/data/tourney1/gogame-121117181328-0500.sgf new file mode 100644 index 0000000..9ca588f --- /dev/null +++ b/data/tourney1/gogame-121117181328-0500.sgf @@ -0,0 +1 @@ +(;FF[4]GM[1]SZ[6]KM[1.5]RE[B+25.5];B[ce];W[ef];B[eb];W[fe];B[ba];W[ee];B[be];W[bd];B[df];W[ae];B[dd];W[fb];B[ea];W[cd];B[fc];W[dc];B[cc];W[ad];B[fa];W[ca];B[cf];W[ed];B[db];W[de];B[af];W[aa];B[da];W[];B[fd];W[bc];B[ec];W[ab];B[cb];W[bb];B[dd];W[];B[ff];W[ee];B[ac];W[ed];B[bd];W[aa];B[ef];W[];B[ae];W[];B[de];W[];B[fe];W[ed];B[ab];W[];B[bc];W[];B[ee];W[];B[]) \ No newline at end of file diff --git a/data/tourney1/gogame-121117181405-0500.sgf b/data/tourney1/gogame-121117181405-0500.sgf new file mode 100644 index 0000000..dde8528 --- /dev/null +++ b/data/tourney1/gogame-121117181405-0500.sgf @@ -0,0 +1 @@ +(;FF[4]GM[1]SZ[6]KM[1.5]RE[B+2.5];B[eb];W[cb];B[ff];W[ed];B[ce];W[de];B[ba];W[bc];B[be];W[ee];B[ae];W[];B[df];W[aa];B[cc];W[ea];B[cf];W[ca];B[db];W[ac];B[fa];W[bd];B[ef];W[dd];B[fc];W[cd];B[ec];W[];B[dc];W[];B[da];W[bb];B[fe];W[fd];B[bf];W[];B[]) \ No newline at end of file diff --git a/data/tourney1/gotournament-121117181405.txt b/data/tourney1/gotournament-121117181405.txt new file mode 100644 index 0000000..903f647 --- /dev/null +++ b/data/tourney1/gotournament-121117181405.txt @@ -0,0 +1,9 @@ +Cumulative results for 3 games (BLACK=ROOT_PAR, WHITE=UCT) +1. W+26.5 +2. B+1.5 +3. W+16.5 +Cumulative results for 3 games (BLACK=UCT, WHITE=ROOT_PAR) +1. W+4.5 +2. B+25.5 +3. B+2.5 +Elapsed Time: 301.403 seconds. \ No newline at end of file diff --git a/src/net/woodyfolsom/msproj/GameBoard.java b/src/net/woodyfolsom/msproj/GameBoard.java index 60db6f9..f002fef 100644 --- a/src/net/woodyfolsom/msproj/GameBoard.java +++ b/src/net/woodyfolsom/msproj/GameBoard.java @@ -178,6 +178,39 @@ public class GameBoard { return false; } + public boolean isSelfFill(Action action, Player player) { + if (action.isNone() || action.isPass() || action.isResign()) { + return false; + } + + int col = getColumnIndex(action.getColumn()); + int row = action.getRow() - 1; + + char stoneSymbol; + if (player == Player.BLACK) { + stoneSymbol = BLACK_STONE; + } else if (player == Player.WHITE) { + stoneSymbol = WHITE_STONE; + } else { + throw new RuntimeException("Invalid player " + player); + } + + //checking the # liberties of this stone's 'string' would be a generalization of self-atari. This is a simple case. + if (col > 0 && getSymbolAt(col-1,row) != stoneSymbol) { + return false; + } + if (col < size - 1 && getSymbolAt(col+1,row) != stoneSymbol) { + return false; + } + if (row > 0 && getSymbolAt(col,row-1) != stoneSymbol) { + return false; + } + if (row < size -1 && getSymbolAt(col,row+1) != stoneSymbol) { + return false; + } + return true; + } + public boolean isTerritoryMarked() { return territoryMarked; } diff --git a/src/net/woodyfolsom/msproj/GameState.java b/src/net/woodyfolsom/msproj/GameState.java index 0c30e8e..342711c 100644 --- a/src/net/woodyfolsom/msproj/GameState.java +++ b/src/net/woodyfolsom/msproj/GameState.java @@ -119,6 +119,10 @@ public class GameState { return whitePrisoners; } + public boolean isSelfFill(Action action, Player player) { + return gameBoard.isSelfFill(action, player); + } + /** * Used for setting up the board. Places the player's stone at the specified coordinates. * diff --git a/src/net/woodyfolsom/msproj/SGFWriter.java b/src/net/woodyfolsom/msproj/SGFWriter.java index e2dd23c..7555c7b 100644 --- a/src/net/woodyfolsom/msproj/SGFWriter.java +++ b/src/net/woodyfolsom/msproj/SGFWriter.java @@ -18,6 +18,7 @@ public class SGFWriter { writer.write("SZ[" + gameConfig.getSize() + "]"); writer.write("KM[" + gameConfig.getKomi() + "]"); + writer.write("RE[" + gameRecord.getGameState(gameRecord.getNumTurns()).getResult() + "]"); for (int i = 1; i <= gameRecord.getNumTurns(); i++) { Player player = gameRecord.getPlayerToMove(i-1); diff --git a/src/net/woodyfolsom/msproj/StandAloneGame.java b/src/net/woodyfolsom/msproj/StandAloneGame.java index f0d2d60..af4979c 100644 --- a/src/net/woodyfolsom/msproj/StandAloneGame.java +++ b/src/net/woodyfolsom/msproj/StandAloneGame.java @@ -18,15 +18,14 @@ import net.woodyfolsom.msproj.policy.RandomMovePolicy; import net.woodyfolsom.msproj.policy.RootParallelization; public class StandAloneGame { - private static final int DEFAULT_TURN_LENGTH = 2; // default turn is 2 + private static final int DEFAULT_TURN_LENGTH = 1; // default turn is 2 // seconds; - private static final double DEFAULT_KOMI = 5.5; private static final int DEFAULT_NUM_GAMES = 1; private static final int DEFAULT_SIZE = 9; enum PLAYER_TYPE { - HUMAN, HUMAN_GUI, ROOT_PAR, UCT_FAST, UCT_SLOW, RANDOM + HUMAN, HUMAN_GUI, ROOT_PAR, UCT, RANDOM }; public static void main(String[] args) { @@ -39,8 +38,11 @@ public class StandAloneGame { int nGames = DEFAULT_NUM_GAMES; int size = DEFAULT_SIZE; double komi = DEFAULT_KOMI; - + int turnLength = DEFAULT_TURN_LENGTH; + switch (args.length) { + case 6: + turnLength = Integer.valueOf(args[5]); case 5: nGames = Integer.valueOf(args[4]); case 4: @@ -59,17 +61,14 @@ public class StandAloneGame { + "."); } new StandAloneGame().playGame(parsePlayerType(args[0]), - parsePlayerType(args[1]), size, komi, nGames); + parsePlayerType(args[1]), size, komi, nGames, turnLength); } private static PLAYER_TYPE parsePlayerType(String playerTypeStr) { - if ("UCT_FAST".equalsIgnoreCase(playerTypeStr)) { - return PLAYER_TYPE.UCT_FAST; + if ("UCT".equalsIgnoreCase(playerTypeStr)) { + return PLAYER_TYPE.UCT; } else if ("ROOT_PAR".equalsIgnoreCase(playerTypeStr)) { return PLAYER_TYPE.ROOT_PAR; - } else if ("UCT_SLOW".equalsIgnoreCase(playerTypeStr) - || "UCT".equalsIgnoreCase(playerTypeStr)) { - return PLAYER_TYPE.UCT_SLOW; } else if ("HUMAN".equalsIgnoreCase(playerTypeStr)) { return PLAYER_TYPE.HUMAN; } else if ("HUMAN_GUI".equalsIgnoreCase(playerTypeStr)) { @@ -82,16 +81,18 @@ public class StandAloneGame { } public void playGame(PLAYER_TYPE playerType1, PLAYER_TYPE playerType2, - int size, double komi, int rounds) { + int size, double komi, int rounds, int turnLength) { + long startTime = System.currentTimeMillis(); + GameConfig gameConfig = new GameConfig(size); gameConfig.setKomi(komi); Referee referee = new Referee(); referee.setPolicy(Player.BLACK, - getPolicy(playerType1, gameConfig, Player.BLACK)); + getPolicy(playerType1, gameConfig, Player.BLACK, turnLength)); referee.setPolicy(Player.WHITE, - getPolicy(playerType2, gameConfig, Player.WHITE)); + getPolicy(playerType2, gameConfig, Player.WHITE, turnLength)); List round1results = new ArrayList(); @@ -102,14 +103,16 @@ public class StandAloneGame { List round2results = new ArrayList(); referee.setPolicy(Player.BLACK, - getPolicy(playerType2, gameConfig, Player.BLACK)); + getPolicy(playerType2, gameConfig, Player.BLACK, turnLength)); referee.setPolicy(Player.WHITE, - getPolicy(playerType1, gameConfig, Player.WHITE)); + getPolicy(playerType1, gameConfig, Player.WHITE, turnLength)); for (int round = 0; round < rounds; round++) { round2results.add(referee.play(gameConfig)); } - DateFormat dateFormat = new SimpleDateFormat("yyMMddHHmmssZ"); + long endTime = System.currentTimeMillis(); + + DateFormat dateFormat = new SimpleDateFormat("yyMMddHHmmss"); try { @@ -123,6 +126,8 @@ public class StandAloneGame { logResults(writer, round2results, playerType2.toString(), playerType1.toString()); + writer.write("Elapsed Time: " + (endTime - startTime) / 1000.0 + " seconds."); + System.out.println("Game tournament saved as " + txtFile.getAbsolutePath()); } finally { @@ -136,7 +141,6 @@ public class StandAloneGame { System.out.println("Unable to save game file due to IOException: " + ioe.getMessage()); } - } private void logResults(FileWriter writer, List results, @@ -158,20 +162,17 @@ public class StandAloneGame { } private Policy getPolicy(PLAYER_TYPE playerType, GameConfig gameConfig, - Player player) { + Player player, int turnLength) { switch (playerType) { case HUMAN: return new HumanKeyboardInput(); case HUMAN_GUI: return new HumanGuiInput(new Goban(gameConfig, player)); case ROOT_PAR: - return new RootParallelization(4, DEFAULT_TURN_LENGTH * 1000L * 3); - case UCT_SLOW: + return new RootParallelization(4, turnLength * 1000L); + case UCT: return new MonteCarloUCT(new RandomMovePolicy(), - DEFAULT_TURN_LENGTH * 1000L * 3); - case UCT_FAST: - return new MonteCarloUCT(new RandomMovePolicy(), - DEFAULT_TURN_LENGTH * 1000L); + turnLength * 1000L); case RANDOM: return new RandomMovePolicy(); default: diff --git a/src/net/woodyfolsom/msproj/ann/PassData.java b/src/net/woodyfolsom/msproj/ann/PassData.java new file mode 100644 index 0000000..be601b3 --- /dev/null +++ b/src/net/woodyfolsom/msproj/ann/PassData.java @@ -0,0 +1,98 @@ +package net.woodyfolsom.msproj.ann; + +import java.util.Arrays; + +import net.woodyfolsom.msproj.GameRecord; +import net.woodyfolsom.msproj.GameResult; +import net.woodyfolsom.msproj.GameState; +import net.woodyfolsom.msproj.Player; + +import org.neuroph.core.learning.SupervisedTrainingElement; +import org.neuroph.core.learning.TrainingSet; + +public class PassData { + public enum DATA_TYPE { TRAINING, TEST, VALIDATION }; + + public String[] inputs = { "BlackScore", "WhiteScore" }; + public String[] outputs = { "BlackWins", "WhiteWins" }; + + private TrainingSet testSet; + private TrainingSet trainingSet; + private TrainingSet valSet; + + public PassData() { + testSet = new TrainingSet(inputs.length, outputs.length); + trainingSet = new TrainingSet(inputs.length, outputs.length); + valSet = new TrainingSet(inputs.length, outputs.length); + } + + public void addData(DATA_TYPE dataType, GameRecord gameRecord) { + GameState finalState = gameRecord.getGameState(gameRecord.getNumTurns()); + GameResult result = finalState.getResult(); + double maxScore = finalState.getGameConfig().getSize() * finalState.getGameConfig().getSize(); + + double whiteScore = Math.min(1.0, result.getWhiteScore() / maxScore); + double blackScore = Math.min(1.0, result.getBlackScore() / maxScore); + + double blackWinner = result.isWinner(Player.BLACK) ? 1.0 : 0.0; + double whiteWinner = result.isWinner(Player.WHITE) ? 1.0 : 0.0; + + addData(dataType, blackScore, whiteScore, blackWinner, whiteWinner); + } + + public void addData(DATA_TYPE dataType, double...data ) { + double[] desiredInput = Arrays.copyOfRange(data,0,inputs.length); + double[] desiredOutput = Arrays.copyOfRange(data, inputs.length, data.length); + + switch (dataType) { + case TEST : + testSet.addElement(new SupervisedTrainingElement(desiredInput, desiredOutput)); + break; + case TRAINING : + trainingSet.addElement(new SupervisedTrainingElement(desiredInput, desiredOutput)); + System.out.println("Added training input data: " + getInput(desiredInput) + ", output data: " + getOutput(desiredOutput)); + break; + case VALIDATION : + valSet.addElement(new SupervisedTrainingElement(desiredInput, desiredOutput)); + break; + default : + throw new UnsupportedOperationException("invalid dataType " + dataType); + } + } + + public String getInput(double... inputValues) { + StringBuilder sbuilder = new StringBuilder(); + boolean first = true; + for (int i = 0; i < outputs.length; i++) { + if (first) { + first = false; + } else { + sbuilder.append(","); + } + sbuilder.append(inputs[i]); + sbuilder.append(": "); + sbuilder.append(inputValues[i]); + } + return sbuilder.toString(); + } + + public String getOutput(double... outputValues) { + StringBuilder sbuilder = new StringBuilder(); + boolean first = true; + for (int i = 0; i < outputs.length; i++) { + if (first) { + first = false; + } else { + sbuilder.append(","); + } + sbuilder.append(outputs[i]); + sbuilder.append(": "); + sbuilder.append(outputValues[i]); + } + return sbuilder.toString(); + } + + public TrainingSet getTrainingSet() { + return trainingSet; + } +} diff --git a/src/net/woodyfolsom/msproj/ann/PassLearner.java b/src/net/woodyfolsom/msproj/ann/PassLearner.java index 6f6c307..cea200b 100644 --- a/src/net/woodyfolsom/msproj/ann/PassLearner.java +++ b/src/net/woodyfolsom/msproj/ann/PassLearner.java @@ -2,22 +2,36 @@ package net.woodyfolsom.msproj.ann; import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.FilenameFilter; import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import net.woodyfolsom.msproj.Action; import net.woodyfolsom.msproj.GameRecord; import net.woodyfolsom.msproj.Referee; +import net.woodyfolsom.msproj.ann.PassData.DATA_TYPE; import org.antlr.runtime.RecognitionException; +import org.neuroph.core.NeuralNetwork; +import org.neuroph.core.learning.SupervisedTrainingElement; +import org.neuroph.core.learning.TrainingSet; +import org.neuroph.nnet.MultiLayerPerceptron; +import org.neuroph.util.TransferFunctionType; -public class PassLearner { +public class PassLearner implements NeuralNetLearner { + private NeuralNetwork neuralNetwork; + + public PassLearner() { + reset(); + } + private File[] getDataFiles(String dirName) { File file = new File(dirName); return file.listFiles(new FilenameFilter() { @Override public boolean accept(File dir, String name) { - // TODO Auto-generated method stub return name.toLowerCase().endsWith(".sgf"); } }); @@ -28,25 +42,86 @@ public class PassLearner { } private void learnANN() { - for (File sgfFile : getDataFiles("data/games/pro9x9")) { + List parsedRecords = new ArrayList(); + + for (File sgfFile : getDataFiles("data/tourney1")) { System.out.println("Parsing " + sgfFile.getPath() + "..."); - parseSGF(sgfFile); + try { + GameRecord gameRecord = parseSGF(sgfFile); + while (!gameRecord.isFinished()) { + System.out.println("Game is not finished, passing as player to move"); + gameRecord.play(gameRecord.getPlayerToMove(), Action.PASS); + } + parsedRecords.add(gameRecord); + } catch (RecognitionException re) { + re.printStackTrace(); + } catch (IOException ioe) { + ioe.printStackTrace(); + } } + + PassData passData = new PassData(); + + for (GameRecord gameRecord : parsedRecords) { + System.out.println(gameRecord.getResult().getFullText()); + passData.addData(DATA_TYPE.TRAINING, gameRecord); + } + + System.out.println("PassData: "); + System.out.println(passData); + + learn(passData.getTrainingSet()); + + getNeuralNetwork().setInput(0.75,0.25); + System.out.println("Output of ann(0.75,0.25): " + passData.getOutput(getNeuralNetwork().getOutput())); + + getNeuralNetwork().setInput(0.25,0.50); + System.out.println("Output of ann(0.50,0.99): " + passData.getOutput(getNeuralNetwork().getOutput())); + + getNeuralNetwork().save("data/networks/Pass.nn"); + + testNetwork(getNeuralNetwork(), passData.getTrainingSet()); } - public void parseSGF(File sgfFile) { + public GameRecord parseSGF(File sgfFile) throws IOException, + RecognitionException { FileInputStream sgfInputStream; - try { - sgfInputStream = new FileInputStream(sgfFile); - GameRecord gameRecord = Referee.replay(sgfInputStream); - // ... - } catch (FileNotFoundException fnfe) { - fnfe.printStackTrace(); - } catch (RecognitionException re) { - re.printStackTrace(); - } catch (IOException ioe) { - ioe.printStackTrace(); - } + sgfInputStream = new FileInputStream(sgfFile); + return Referee.replay(sgfInputStream); + } + + @Override + public NeuralNetwork getNeuralNetwork() { + return neuralNetwork; + } + + @Override + public void learn(TrainingSet trainingSet) { + this.neuralNetwork.learn(trainingSet); + } + + @Override + public void reset() { + this.neuralNetwork = new MultiLayerPerceptron( + TransferFunctionType.TANH, 2, 3, 2); + } + + @Override + public void setNeuralNetwork(NeuralNetwork neuralNetwork) { + this.neuralNetwork = neuralNetwork; + } + +private void testNetwork(NeuralNetwork nnet, TrainingSet trainingSet) { + for (SupervisedTrainingElement trainingElement : trainingSet.elements()) { + + nnet.setInput(trainingElement.getInput()); + nnet.calculate(); + double[] networkOutput = nnet.getOutput(); + System.out.print("Input: " + + Arrays.toString(trainingElement.getInput())); + System.out.println(" Output: " + Arrays.toString(networkOutput)); + } } +} diff --git a/src/net/woodyfolsom/msproj/policy/MonteCarlo.java b/src/net/woodyfolsom/msproj/policy/MonteCarlo.java index 606dd7d..3d241c6 100644 --- a/src/net/woodyfolsom/msproj/policy/MonteCarlo.java +++ b/src/net/woodyfolsom/msproj/policy/MonteCarlo.java @@ -37,8 +37,8 @@ public abstract class MonteCarlo implements Policy { GameTreeNode node); private GameTreeNode buildTree(GameConfig gameConfig, GameState gameState, Player player) { - System.out.println(player + " is thinking for up to " - + (searchTimeLimit / 1000.0) + " seconds..."); + //System.out.println(player + " is thinking for up to " + // + (searchTimeLimit / 1000.0) + " seconds..."); long startTime = System.currentTimeMillis(); if (gameState.getPlayerToMove() != player) { diff --git a/src/net/woodyfolsom/msproj/policy/MonteCarloUCT.java b/src/net/woodyfolsom/msproj/policy/MonteCarloUCT.java index 33e8632..5a0019c 100644 --- a/src/net/woodyfolsom/msproj/policy/MonteCarloUCT.java +++ b/src/net/woodyfolsom/msproj/policy/MonteCarloUCT.java @@ -80,7 +80,22 @@ public class MonteCarloUCT extends MonteCarlo { double bestScore = Double.NEGATIVE_INFINITY; GameTreeNode bestChild = null; + //int nActions = node.getNumChildren(); + //GameState rootGameState = node.getGameState(); + //boolean playerToMoveIsWinning = rootGameState.getResult().isWinner(rootGameState.getPlayerToMove()); + //playerToMove is winning or only one move (PASS) is available + //boolean allowPass = playerToMoveIsWinning || nActions == 1; + for (Action action : node.getActions()) { + ///HEURISTIC - work on ways of removing this go-specific logic ///// + //If action is PASS and the play who moved is not the winner while other moves are available, don't pass + //i.e. don't pass when losing + //if (action.isPass() && !allowPass) { + // continue; //If the best rated action is PASS and I'm not winning and there are other valid actions, + // //keep searching. + //} + //////////////////////////////////////////////////////////////////// + GameTreeNode childNode = node .getChild(action); @@ -97,7 +112,7 @@ public class MonteCarloUCT extends MonteCarlo { if (bestAction == Action.NONE) { System.out - .println("MonteCarloUCT failed - no actions were found for the current game staet (not even PASS)."); + .println("MonteCarloUCT failed - no actions were found for the current game state (not even PASS)."); } else { System.out.println("Action " + bestAction + " selected for " + node.getGameState().getPlayerToMove() diff --git a/src/net/woodyfolsom/msproj/policy/RandomMovePolicy.java b/src/net/woodyfolsom/msproj/policy/RandomMovePolicy.java index a81779c..d686469 100644 --- a/src/net/woodyfolsom/msproj/policy/RandomMovePolicy.java +++ b/src/net/woodyfolsom/msproj/policy/RandomMovePolicy.java @@ -47,20 +47,41 @@ public class RandomMovePolicy implements Policy, ActionGenerator { ActionGenerator.ALL_ACTIONS); List randomActions = new ArrayList(); + // + boolean playerIsWinning = gameState.getResult().isWinner(player); + // + while (possibleActions.size() > 0 && randomActions.size() < nMoves) { Action randomAction = possibleActions .remove((int) (Math.random() * possibleActions.size())); - randomActions.add(randomAction); + if (isValidRandomAction(randomAction, player,playerIsWinning, gameState)) { + randomActions.add(randomAction); + } } + //if (randomActions.size() == 0) { + // randomActions.add(Action.NONE); + //} + + //PASS is always the move of last resort if no valid moves exist if (randomActions.size() == 0) { - randomActions.add(Action.NONE); + randomActions.add(Action.PASS); } + + //when to resign? return randomActions; } + private boolean isValidRandomAction(Action action, Player player, boolean playerIsWinning, GameState gameState) { + //do not pass while losing + if (action.isPass()) { + return playerIsWinning; + } + //do not fill in my own eye + return !gameState.isSelfFill(action, player); + } /** * RandomMoveGenerator does not evaluate any states, but simply returns * elements of a set of uniformly distributed, distinct valid moves. diff --git a/src/net/woodyfolsom/msproj/policy/RootParallelization.java b/src/net/woodyfolsom/msproj/policy/RootParallelization.java index 676cc05..f7713d7 100644 --- a/src/net/woodyfolsom/msproj/policy/RootParallelization.java +++ b/src/net/woodyfolsom/msproj/policy/RootParallelization.java @@ -74,14 +74,24 @@ public class RootParallelization implements Policy { double bestValue = 0.0; int totalRollouts = 0; int bestWins = 0; - int nValidActions = totalReward.keySet().size(); + int bestSims = 0; + + //int nActions = totalReward.size(); + //boolean playerToMoveIsWinning = gameState.getResult().isWinner(player); + //playerToMove is winning or only one move (PASS) is available + //boolean allowPass = playerToMoveIsWinning || nActions == 1; for (Action action : totalReward.keySet()) { - if (action.isPass() && !gameState.getResult().isWinner(player) && nValidActions > 1) { - continue; //If the best rated action is PASS and I'm not winning and there are other valid actions, - //keep searching. - } + //HEURISTIC - work on ways of removing this go-specific logic + // + //This heuristic must be duplicated here because RootPar. does not benefit + //from MonteCarloUCT culling PASS just before returning from getAction(). + //if (action.isPass() && !allowPass) { + // continue; //If the best rated action is PASS and I'm not winning and there are other valid actions, + // //keep searching. + //} + int totalWins = totalReward.get(action); int totalSims = numSims.get(action); @@ -93,6 +103,7 @@ public class RootParallelization implements Policy { bestAction = action; bestValue = value; bestWins = totalWins; + bestSims = totalSims; } } @@ -102,9 +113,10 @@ public class RootParallelization implements Policy { + " with simulated win ratio of " + (bestValue * 100.0 + "% among " + numTrees + " parallel simulations.")); System.out.println("It won " - + bestWins + " out of " - + totalRollouts + " rollouts among " - + " valid actions from the current state."); + + bestWins + " out of " + bestSims + + " rollouts among " + totalRollouts + + " total rollouts (" + totalReward.keySet() + + " possible actions) from the current state."); return bestAction; } diff --git a/src/net/woodyfolsom/msproj/sgf/SGF.tokens b/src/net/woodyfolsom/msproj/sgf/SGF.tokens index bdf7aac..5cd7273 100644 --- a/src/net/woodyfolsom/msproj/sgf/SGF.tokens +++ b/src/net/woodyfolsom/msproj/sgf/SGF.tokens @@ -36,6 +36,8 @@ T__54=54 T__55=55 T__56=56 T__57=57 +T__58=58 +T__59=59 COLON=4 COMMA=5 DIGIT=6 @@ -62,31 +64,33 @@ UCLETTER=19 'C'=27 'CA'=28 'CP'=29 -'DT'=30 -'DaTe'=31 -'EV'=32 -'EVent'=33 -'FF'=34 -'GM'=35 -'GaMe'=36 -'KM'=37 -'PB'=38 -'PC'=39 -'PW'=40 -'PlaCe'=41 -'PlayerBlack'=42 -'PlayerWhite'=43 -'RE'=44 -'REsult'=45 -'RU'=46 -'SO'=47 -'SZ'=48 -'SiZe'=49 -'TM'=50 -'US'=51 -'VW'=52 -'VieW'=53 -'W'=54 -'WC'=55 -'WR'=56 -'White'=57 +'Comment'=30 +'DT'=31 +'DaTe'=32 +'EV'=33 +'EVent'=34 +'FF'=35 +'GM'=36 +'GaMe'=37 +'KM'=38 +'KoMi'=39 +'PB'=40 +'PC'=41 +'PW'=42 +'PlaCe'=43 +'PlayerBlack'=44 +'PlayerWhite'=45 +'RE'=46 +'REsult'=47 +'RU'=48 +'SO'=49 +'SZ'=50 +'SiZe'=51 +'TM'=52 +'US'=53 +'VW'=54 +'VieW'=55 +'W'=56 +'WC'=57 +'WR'=58 +'White'=59 diff --git a/src/net/woodyfolsom/msproj/sgf/SGFLexer.java b/src/net/woodyfolsom/msproj/sgf/SGFLexer.java index 97a8d77..44d3d92 100644 --- a/src/net/woodyfolsom/msproj/sgf/SGFLexer.java +++ b/src/net/woodyfolsom/msproj/sgf/SGFLexer.java @@ -1,4 +1,4 @@ -// $ANTLR 3.4 C:\\Users\\Woody\\Documents\\antlr\\SGF.g 2012-11-14 04:25:56 +// $ANTLR 3.4 C:\\Users\\Woody\\Documents\\antlr\\SGF.g 2012-11-17 16:41:53 package net.woodyfolsom.msproj.sgf; import org.antlr.runtime.*; @@ -47,6 +47,8 @@ public class SGFLexer extends Lexer { public static final int T__55=55; public static final int T__56=56; public static final int T__57=57; + public static final int T__58=58; + public static final int T__59=59; public static final int COLON=4; public static final int COMMA=5; public static final int DIGIT=6; @@ -310,10 +312,10 @@ public class SGFLexer extends Lexer { try { int _type = T__30; int _channel = DEFAULT_TOKEN_CHANNEL; - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:14:7: ( 'DT' ) - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:14:9: 'DT' + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:14:7: ( 'Comment' ) + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:14:9: 'Comment' { - match("DT"); + match("Comment"); @@ -333,10 +335,10 @@ public class SGFLexer extends Lexer { try { int _type = T__31; int _channel = DEFAULT_TOKEN_CHANNEL; - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:15:7: ( 'DaTe' ) - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:15:9: 'DaTe' + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:15:7: ( 'DT' ) + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:15:9: 'DT' { - match("DaTe"); + match("DT"); @@ -356,10 +358,10 @@ public class SGFLexer extends Lexer { try { int _type = T__32; int _channel = DEFAULT_TOKEN_CHANNEL; - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:16:7: ( 'EV' ) - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:16:9: 'EV' + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:16:7: ( 'DaTe' ) + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:16:9: 'DaTe' { - match("EV"); + match("DaTe"); @@ -379,10 +381,10 @@ public class SGFLexer extends Lexer { try { int _type = T__33; int _channel = DEFAULT_TOKEN_CHANNEL; - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:17:7: ( 'EVent' ) - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:17:9: 'EVent' + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:17:7: ( 'EV' ) + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:17:9: 'EV' { - match("EVent"); + match("EV"); @@ -402,10 +404,10 @@ public class SGFLexer extends Lexer { try { int _type = T__34; int _channel = DEFAULT_TOKEN_CHANNEL; - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:18:7: ( 'FF' ) - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:18:9: 'FF' + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:18:7: ( 'EVent' ) + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:18:9: 'EVent' { - match("FF"); + match("EVent"); @@ -425,10 +427,10 @@ public class SGFLexer extends Lexer { try { int _type = T__35; int _channel = DEFAULT_TOKEN_CHANNEL; - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:19:7: ( 'GM' ) - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:19:9: 'GM' + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:19:7: ( 'FF' ) + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:19:9: 'FF' { - match("GM"); + match("FF"); @@ -448,10 +450,10 @@ public class SGFLexer extends Lexer { try { int _type = T__36; int _channel = DEFAULT_TOKEN_CHANNEL; - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:20:7: ( 'GaMe' ) - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:20:9: 'GaMe' + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:20:7: ( 'GM' ) + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:20:9: 'GM' { - match("GaMe"); + match("GM"); @@ -471,10 +473,10 @@ public class SGFLexer extends Lexer { try { int _type = T__37; int _channel = DEFAULT_TOKEN_CHANNEL; - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:21:7: ( 'KM' ) - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:21:9: 'KM' + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:21:7: ( 'GaMe' ) + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:21:9: 'GaMe' { - match("KM"); + match("GaMe"); @@ -494,10 +496,10 @@ public class SGFLexer extends Lexer { try { int _type = T__38; int _channel = DEFAULT_TOKEN_CHANNEL; - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:22:7: ( 'PB' ) - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:22:9: 'PB' + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:22:7: ( 'KM' ) + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:22:9: 'KM' { - match("PB"); + match("KM"); @@ -517,10 +519,10 @@ public class SGFLexer extends Lexer { try { int _type = T__39; int _channel = DEFAULT_TOKEN_CHANNEL; - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:23:7: ( 'PC' ) - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:23:9: 'PC' + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:23:7: ( 'KoMi' ) + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:23:9: 'KoMi' { - match("PC"); + match("KoMi"); @@ -540,10 +542,10 @@ public class SGFLexer extends Lexer { try { int _type = T__40; int _channel = DEFAULT_TOKEN_CHANNEL; - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:24:7: ( 'PW' ) - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:24:9: 'PW' + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:24:7: ( 'PB' ) + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:24:9: 'PB' { - match("PW"); + match("PB"); @@ -563,10 +565,10 @@ public class SGFLexer extends Lexer { try { int _type = T__41; int _channel = DEFAULT_TOKEN_CHANNEL; - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:25:7: ( 'PlaCe' ) - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:25:9: 'PlaCe' + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:25:7: ( 'PC' ) + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:25:9: 'PC' { - match("PlaCe"); + match("PC"); @@ -586,10 +588,10 @@ public class SGFLexer extends Lexer { try { int _type = T__42; int _channel = DEFAULT_TOKEN_CHANNEL; - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:26:7: ( 'PlayerBlack' ) - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:26:9: 'PlayerBlack' + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:26:7: ( 'PW' ) + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:26:9: 'PW' { - match("PlayerBlack"); + match("PW"); @@ -609,10 +611,10 @@ public class SGFLexer extends Lexer { try { int _type = T__43; int _channel = DEFAULT_TOKEN_CHANNEL; - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:27:7: ( 'PlayerWhite' ) - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:27:9: 'PlayerWhite' + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:27:7: ( 'PlaCe' ) + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:27:9: 'PlaCe' { - match("PlayerWhite"); + match("PlaCe"); @@ -632,10 +634,10 @@ public class SGFLexer extends Lexer { try { int _type = T__44; int _channel = DEFAULT_TOKEN_CHANNEL; - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:28:7: ( 'RE' ) - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:28:9: 'RE' + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:28:7: ( 'PlayerBlack' ) + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:28:9: 'PlayerBlack' { - match("RE"); + match("PlayerBlack"); @@ -655,10 +657,10 @@ public class SGFLexer extends Lexer { try { int _type = T__45; int _channel = DEFAULT_TOKEN_CHANNEL; - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:29:7: ( 'REsult' ) - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:29:9: 'REsult' + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:29:7: ( 'PlayerWhite' ) + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:29:9: 'PlayerWhite' { - match("REsult"); + match("PlayerWhite"); @@ -678,10 +680,10 @@ public class SGFLexer extends Lexer { try { int _type = T__46; int _channel = DEFAULT_TOKEN_CHANNEL; - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:30:7: ( 'RU' ) - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:30:9: 'RU' + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:30:7: ( 'RE' ) + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:30:9: 'RE' { - match("RU"); + match("RE"); @@ -701,10 +703,10 @@ public class SGFLexer extends Lexer { try { int _type = T__47; int _channel = DEFAULT_TOKEN_CHANNEL; - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:31:7: ( 'SO' ) - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:31:9: 'SO' + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:31:7: ( 'REsult' ) + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:31:9: 'REsult' { - match("SO"); + match("REsult"); @@ -724,10 +726,10 @@ public class SGFLexer extends Lexer { try { int _type = T__48; int _channel = DEFAULT_TOKEN_CHANNEL; - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:32:7: ( 'SZ' ) - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:32:9: 'SZ' + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:32:7: ( 'RU' ) + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:32:9: 'RU' { - match("SZ"); + match("RU"); @@ -747,10 +749,10 @@ public class SGFLexer extends Lexer { try { int _type = T__49; int _channel = DEFAULT_TOKEN_CHANNEL; - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:33:7: ( 'SiZe' ) - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:33:9: 'SiZe' + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:33:7: ( 'SO' ) + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:33:9: 'SO' { - match("SiZe"); + match("SO"); @@ -770,10 +772,10 @@ public class SGFLexer extends Lexer { try { int _type = T__50; int _channel = DEFAULT_TOKEN_CHANNEL; - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:34:7: ( 'TM' ) - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:34:9: 'TM' + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:34:7: ( 'SZ' ) + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:34:9: 'SZ' { - match("TM"); + match("SZ"); @@ -793,10 +795,10 @@ public class SGFLexer extends Lexer { try { int _type = T__51; int _channel = DEFAULT_TOKEN_CHANNEL; - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:35:7: ( 'US' ) - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:35:9: 'US' + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:35:7: ( 'SiZe' ) + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:35:9: 'SiZe' { - match("US"); + match("SiZe"); @@ -816,10 +818,10 @@ public class SGFLexer extends Lexer { try { int _type = T__52; int _channel = DEFAULT_TOKEN_CHANNEL; - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:36:7: ( 'VW' ) - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:36:9: 'VW' + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:36:7: ( 'TM' ) + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:36:9: 'TM' { - match("VW"); + match("TM"); @@ -839,10 +841,10 @@ public class SGFLexer extends Lexer { try { int _type = T__53; int _channel = DEFAULT_TOKEN_CHANNEL; - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:37:7: ( 'VieW' ) - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:37:9: 'VieW' + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:37:7: ( 'US' ) + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:37:9: 'US' { - match("VieW"); + match("US"); @@ -862,10 +864,12 @@ public class SGFLexer extends Lexer { try { int _type = T__54; int _channel = DEFAULT_TOKEN_CHANNEL; - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:38:7: ( 'W' ) - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:38:9: 'W' + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:38:7: ( 'VW' ) + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:38:9: 'VW' { - match('W'); + match("VW"); + + } @@ -883,10 +887,10 @@ public class SGFLexer extends Lexer { try { int _type = T__55; int _channel = DEFAULT_TOKEN_CHANNEL; - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:39:7: ( 'WC' ) - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:39:9: 'WC' + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:39:7: ( 'VieW' ) + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:39:9: 'VieW' { - match("WC"); + match("VieW"); @@ -906,12 +910,10 @@ public class SGFLexer extends Lexer { try { int _type = T__56; int _channel = DEFAULT_TOKEN_CHANNEL; - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:40:7: ( 'WR' ) - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:40:9: 'WR' + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:40:7: ( 'W' ) + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:40:9: 'W' { - match("WR"); - - + match('W'); } @@ -929,8 +931,54 @@ public class SGFLexer extends Lexer { try { int _type = T__57; int _channel = DEFAULT_TOKEN_CHANNEL; - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:41:7: ( 'White' ) - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:41:9: 'White' + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:41:7: ( 'WC' ) + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:41:9: 'WC' + { + match("WC"); + + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "T__57" + + // $ANTLR start "T__58" + public final void mT__58() throws RecognitionException { + try { + int _type = T__58; + int _channel = DEFAULT_TOKEN_CHANNEL; + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:42:7: ( 'WR' ) + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:42:9: 'WR' + { + match("WR"); + + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "T__58" + + // $ANTLR start "T__59" + public final void mT__59() throws RecognitionException { + try { + int _type = T__59; + int _channel = DEFAULT_TOKEN_CHANNEL; + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:43:7: ( 'White' ) + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:43:9: 'White' { match("White"); @@ -945,7 +993,7 @@ public class SGFLexer extends Lexer { // do for sure before leaving } } - // $ANTLR end "T__57" + // $ANTLR end "T__59" // $ANTLR start "SPACE" public final void mSPACE() throws RecognitionException { @@ -1117,22 +1165,64 @@ public class SGFLexer extends Lexer { } // $ANTLR end "SLASH" + // $ANTLR start "LPAREN" + public final void mLPAREN() throws RecognitionException { + try { + int _type = LPAREN; + int _channel = DEFAULT_TOKEN_CHANNEL; + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:194:9: ( '(' ) + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:194:11: '(' + { + match('('); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "LPAREN" + + // $ANTLR start "RPAREN" + public final void mRPAREN() throws RecognitionException { + try { + int _type = RPAREN; + int _channel = DEFAULT_TOKEN_CHANNEL; + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:196:9: ( ')' ) + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:196:11: ')' + { + match(')'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "RPAREN" + // $ANTLR start "STRVALUE" public final void mSTRVALUE() throws RecognitionException { try { int _type = STRVALUE; int _channel = DEFAULT_TOKEN_CHANNEL; - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:194:10: ( ( UCLETTER | LCLETTER | MINUS | DIGIT | SPACE | PERIOD | COMMA | PLUS | SLASH | COLON )+ ) - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:194:12: ( UCLETTER | LCLETTER | MINUS | DIGIT | SPACE | PERIOD | COMMA | PLUS | SLASH | COLON )+ + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:198:10: ( ( UCLETTER | LCLETTER | MINUS | DIGIT | SPACE | PERIOD | COMMA | PLUS | SLASH | COLON | LPAREN | RPAREN )+ ) + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:198:12: ( UCLETTER | LCLETTER | MINUS | DIGIT | SPACE | PERIOD | COMMA | PLUS | SLASH | COLON | LPAREN | RPAREN )+ { - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:194:12: ( UCLETTER | LCLETTER | MINUS | DIGIT | SPACE | PERIOD | COMMA | PLUS | SLASH | COLON )+ + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:198:12: ( UCLETTER | LCLETTER | MINUS | DIGIT | SPACE | PERIOD | COMMA | PLUS | SLASH | COLON | LPAREN | RPAREN )+ int cnt1=0; loop1: do { int alt1=2; int LA1_0 = input.LA(1); - if ( (LA1_0==' '||(LA1_0 >= '+' && LA1_0 <= ':')||(LA1_0 >= 'A' && LA1_0 <= 'Z')||(LA1_0 >= 'a' && LA1_0 <= 'z')) ) { + if ( (LA1_0==' '||(LA1_0 >= '(' && LA1_0 <= ')')||(LA1_0 >= '+' && LA1_0 <= ':')||(LA1_0 >= 'A' && LA1_0 <= 'Z')||(LA1_0 >= 'a' && LA1_0 <= 'z')) ) { alt1=1; } @@ -1141,7 +1231,7 @@ public class SGFLexer extends Lexer { case 1 : // C:\\Users\\Woody\\Documents\\antlr\\SGF.g: { - if ( input.LA(1)==' '||(input.LA(1) >= '+' && input.LA(1) <= ':')||(input.LA(1) >= 'A' && input.LA(1) <= 'Z')||(input.LA(1) >= 'a' && input.LA(1) <= 'z') ) { + if ( input.LA(1)==' '||(input.LA(1) >= '(' && input.LA(1) <= ')')||(input.LA(1) >= '+' && input.LA(1) <= ':')||(input.LA(1) >= 'A' && input.LA(1) <= 'Z')||(input.LA(1) >= 'a' && input.LA(1) <= 'z') ) { input.consume(); } else { @@ -1175,34 +1265,13 @@ public class SGFLexer extends Lexer { } // $ANTLR end "STRVALUE" - // $ANTLR start "LPAREN" - public final void mLPAREN() throws RecognitionException { - try { - int _type = LPAREN; - int _channel = DEFAULT_TOKEN_CHANNEL; - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:196:9: ( '(' ) - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:196:11: '(' - { - match('('); - - } - - state.type = _type; - state.channel = _channel; - } - finally { - // do for sure before leaving - } - } - // $ANTLR end "LPAREN" - // $ANTLR start "SEMICOLON" public final void mSEMICOLON() throws RecognitionException { try { int _type = SEMICOLON; int _channel = DEFAULT_TOKEN_CHANNEL; - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:198:11: ( ';' ) - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:198:14: ';' + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:201:11: ( ';' ) + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:201:14: ';' { match(';'); @@ -1220,7 +1289,7 @@ public class SGFLexer extends Lexer { // $ANTLR start "UCLETTER" public final void mUCLETTER() throws RecognitionException { try { - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:200:19: ( 'A' .. 'Z' ) + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:203:19: ( 'A' .. 'Z' ) // C:\\Users\\Woody\\Documents\\antlr\\SGF.g: { if ( (input.LA(1) >= 'A' && input.LA(1) <= 'Z') ) { @@ -1246,7 +1315,7 @@ public class SGFLexer extends Lexer { // $ANTLR start "LCLETTER" public final void mLCLETTER() throws RecognitionException { try { - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:202:19: ( 'a' .. 'z' ) + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:205:19: ( 'a' .. 'z' ) // C:\\Users\\Woody\\Documents\\antlr\\SGF.g: { if ( (input.LA(1) >= 'a' && input.LA(1) <= 'z') ) { @@ -1274,8 +1343,8 @@ public class SGFLexer extends Lexer { try { int _type = LBRACKET; int _channel = DEFAULT_TOKEN_CHANNEL; - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:205:2: ( '[' ) - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:205:4: '[' + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:208:2: ( '[' ) + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:208:4: '[' { match('['); @@ -1295,8 +1364,8 @@ public class SGFLexer extends Lexer { try { int _type = RBRACKET; int _channel = DEFAULT_TOKEN_CHANNEL; - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:208:2: ( ']' ) - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:208:4: ']' + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:211:2: ( ']' ) + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:211:4: ']' { match(']'); @@ -1311,30 +1380,9 @@ public class SGFLexer extends Lexer { } // $ANTLR end "RBRACKET" - // $ANTLR start "RPAREN" - public final void mRPAREN() throws RecognitionException { - try { - int _type = RPAREN; - int _channel = DEFAULT_TOKEN_CHANNEL; - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:210:9: ( ')' ) - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:210:11: ')' - { - match(')'); - - } - - state.type = _type; - state.channel = _channel; - } - finally { - // do for sure before leaving - } - } - // $ANTLR end "RPAREN" - public void mTokens() throws RecognitionException { - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:1:8: ( T__20 | T__21 | T__22 | T__23 | T__24 | T__25 | T__26 | T__27 | T__28 | T__29 | T__30 | T__31 | T__32 | T__33 | T__34 | T__35 | T__36 | T__37 | T__38 | T__39 | T__40 | T__41 | T__42 | T__43 | T__44 | T__45 | T__46 | T__47 | T__48 | T__49 | T__50 | T__51 | T__52 | T__53 | T__54 | T__55 | T__56 | T__57 | SPACE | COLON | MINUS | COMMA | PLUS | SLASH | STRVALUE | LPAREN | SEMICOLON | LBRACKET | RBRACKET | RPAREN ) - int alt2=50; + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:1:8: ( T__20 | T__21 | T__22 | T__23 | T__24 | T__25 | T__26 | T__27 | T__28 | T__29 | T__30 | T__31 | T__32 | T__33 | T__34 | T__35 | T__36 | T__37 | T__38 | T__39 | T__40 | T__41 | T__42 | T__43 | T__44 | T__45 | T__46 | T__47 | T__48 | T__49 | T__50 | T__51 | T__52 | T__53 | T__54 | T__55 | T__56 | T__57 | T__58 | T__59 | SPACE | COLON | MINUS | COMMA | PLUS | SLASH | LPAREN | RPAREN | STRVALUE | SEMICOLON | LBRACKET | RBRACKET ) + int alt2=52; alt2 = dfa2.predict(input); switch (alt2) { case 1 : @@ -1642,99 +1690,115 @@ public class SGFLexer extends Lexer { } break; case 39 : - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:1:238: SPACE + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:1:238: T__58 + { + mT__58(); + + + } + break; + case 40 : + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:1:244: T__59 + { + mT__59(); + + + } + break; + case 41 : + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:1:250: SPACE { mSPACE(); } break; - case 40 : - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:1:244: COLON + case 42 : + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:1:256: COLON { mCOLON(); } break; - case 41 : - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:1:250: MINUS + case 43 : + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:1:262: MINUS { mMINUS(); } break; - case 42 : - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:1:256: COMMA + case 44 : + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:1:268: COMMA { mCOMMA(); } break; - case 43 : - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:1:262: PLUS + case 45 : + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:1:274: PLUS { mPLUS(); } break; - case 44 : - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:1:267: SLASH + case 46 : + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:1:279: SLASH { mSLASH(); } break; - case 45 : - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:1:273: STRVALUE - { - mSTRVALUE(); - - - } - break; - case 46 : - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:1:282: LPAREN + case 47 : + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:1:285: LPAREN { mLPAREN(); } break; - case 47 : - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:1:289: SEMICOLON + case 48 : + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:1:292: RPAREN + { + mRPAREN(); + + + } + break; + case 49 : + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:1:299: STRVALUE + { + mSTRVALUE(); + + + } + break; + case 50 : + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:1:308: SEMICOLON { mSEMICOLON(); } break; - case 48 : - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:1:299: LBRACKET + case 51 : + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:1:318: LBRACKET { mLBRACKET(); } break; - case 49 : - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:1:308: RBRACKET + case 52 : + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:1:327: RBRACKET { mRBRACKET(); - } - break; - case 50 : - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:1:317: RPAREN - { - mRPAREN(); - - } break; @@ -1745,189 +1809,209 @@ public class SGFLexer extends Lexer { protected DFA2 dfa2 = new DFA2(this); static final String DFA2_eotS = - "\1\uffff\1\26\1\42\1\45\13\26\1\75\1\76\1\77\1\100\1\101\1\102\1"+ - "\103\6\uffff\1\104\1\105\1\106\1\107\1\110\1\26\1\uffff\1\112\1"+ - "\113\1\uffff\1\114\1\26\1\117\1\120\1\121\1\26\1\123\1\124\1\125"+ - "\1\126\1\26\1\131\1\132\1\133\1\134\1\26\1\136\1\137\1\140\1\26"+ - "\1\142\1\143\1\26\14\uffff\1\26\3\uffff\2\26\3\uffff\1\26\4\uffff"+ - "\2\26\4\uffff\1\26\3\uffff\1\26\2\uffff\2\26\1\160\1\26\1\162\3"+ - "\26\1\166\1\167\1\26\1\171\1\uffff\1\172\1\uffff\1\173\2\26\2\uffff"+ - "\1\176\3\uffff\1\26\1\u0081\1\uffff\2\26\1\uffff\6\26\1\u008a\1"+ - "\u008b\2\uffff"; + "\1\uffff\1\30\1\42\1\46\13\30\1\77\1\100\1\101\1\102\1\103\1\104"+ + "\1\105\1\106\1\107\4\uffff\1\110\1\111\1\112\1\113\1\114\1\30\1"+ + "\uffff\1\116\1\117\1\30\1\uffff\1\121\1\30\1\124\1\125\1\126\1\30"+ + "\1\130\1\30\1\132\1\133\1\134\1\30\1\137\1\140\1\141\1\142\1\30"+ + "\1\144\1\145\1\146\1\30\1\150\1\151\1\30\16\uffff\1\30\2\uffff\1"+ + "\30\1\uffff\2\30\3\uffff\1\30\1\uffff\1\30\3\uffff\2\30\4\uffff"+ + "\1\30\3\uffff\1\30\2\uffff\3\30\1\171\1\30\1\173\1\174\3\30\1\u0080"+ + "\1\u0081\1\30\1\u0083\1\30\1\uffff\1\u0085\2\uffff\1\u0086\2\30"+ + "\2\uffff\1\u0089\1\uffff\1\30\2\uffff\1\30\1\u008d\1\uffff\1\u008e"+ + "\2\30\2\uffff\6\30\1\u0097\1\u0098\2\uffff"; static final String DFA2_eofS = - "\u008c\uffff"; + "\u0099\uffff"; static final String DFA2_minS = "\1\40\1\102\2\40\1\124\1\126\1\106\2\115\1\102\1\105\1\117\1\115"+ - "\1\123\1\127\7\40\6\uffff\5\40\1\141\1\uffff\2\40\1\uffff\1\40\1"+ - "\124\3\40\1\115\4\40\1\141\4\40\1\132\3\40\1\145\2\40\1\151\14\uffff"+ - "\1\143\3\uffff\1\145\1\156\3\uffff\1\145\4\uffff\1\103\1\165\4\uffff"+ - "\1\145\3\uffff\1\127\2\uffff\1\164\1\153\1\40\1\164\1\40\2\145\1"+ - "\154\2\40\1\145\1\40\1\uffff\1\40\1\uffff\1\40\1\162\1\164\2\uffff"+ - "\1\40\3\uffff\1\102\1\40\1\uffff\1\154\1\150\1\uffff\1\141\1\151"+ - "\1\143\1\164\1\153\1\145\2\40\2\uffff"; + "\1\123\1\127\11\40\4\uffff\5\40\1\141\1\uffff\2\40\1\155\1\uffff"+ + "\1\40\1\124\3\40\1\115\1\40\1\115\3\40\1\141\4\40\1\132\3\40\1\145"+ + "\2\40\1\151\16\uffff\1\143\2\uffff\1\155\1\uffff\1\145\1\156\3\uffff"+ + "\1\145\1\uffff\1\151\3\uffff\1\103\1\165\4\uffff\1\145\3\uffff\1"+ + "\127\2\uffff\1\164\1\153\1\145\1\40\1\164\2\40\2\145\1\154\2\40"+ + "\1\145\1\40\1\156\1\uffff\1\40\2\uffff\1\40\1\162\1\164\2\uffff"+ + "\1\40\1\uffff\1\164\2\uffff\1\102\1\40\1\uffff\1\40\1\154\1\150"+ + "\2\uffff\1\141\1\151\1\143\1\164\1\153\1\145\2\40\2\uffff"; static final String DFA2_maxS = - "\1\172\1\127\2\172\1\141\1\126\1\106\1\141\1\115\1\154\1\125\1\151"+ - "\1\115\1\123\1\151\7\172\6\uffff\5\172\1\141\1\uffff\2\172\1\uffff"+ - "\1\172\1\124\3\172\1\115\4\172\1\141\4\172\1\132\3\172\1\145\2\172"+ - "\1\151\14\uffff\1\143\3\uffff\1\145\1\156\3\uffff\1\145\4\uffff"+ - "\1\171\1\165\4\uffff\1\145\3\uffff\1\127\2\uffff\1\164\1\153\1\172"+ - "\1\164\1\172\2\145\1\154\2\172\1\145\1\172\1\uffff\1\172\1\uffff"+ - "\1\172\1\162\1\164\2\uffff\1\172\3\uffff\1\127\1\172\1\uffff\1\154"+ - "\1\150\1\uffff\1\141\1\151\1\143\1\164\1\153\1\145\2\172\2\uffff"; + "\1\172\1\127\2\172\1\141\1\126\1\106\1\141\1\157\1\154\1\125\1\151"+ + "\1\115\1\123\1\151\11\172\4\uffff\5\172\1\141\1\uffff\2\172\1\155"+ + "\1\uffff\1\172\1\124\3\172\1\115\1\172\1\115\3\172\1\141\4\172\1"+ + "\132\3\172\1\145\2\172\1\151\16\uffff\1\143\2\uffff\1\155\1\uffff"+ + "\1\145\1\156\3\uffff\1\145\1\uffff\1\151\3\uffff\1\171\1\165\4\uffff"+ + "\1\145\3\uffff\1\127\2\uffff\1\164\1\153\1\145\1\172\1\164\2\172"+ + "\2\145\1\154\2\172\1\145\1\172\1\156\1\uffff\1\172\2\uffff\1\172"+ + "\1\162\1\164\2\uffff\1\172\1\uffff\1\164\2\uffff\1\127\1\172\1\uffff"+ + "\1\172\1\154\1\150\2\uffff\1\141\1\151\1\143\1\164\1\153\1\145\2"+ + "\172\2\uffff"; static final String DFA2_acceptS = - "\26\uffff\1\55\1\56\1\57\1\60\1\61\1\62\6\uffff\1\4\2\uffff\1\10"+ - "\27\uffff\1\43\1\47\1\50\1\51\1\52\1\53\1\54\1\1\1\2\1\3\1\5\1\6"+ - "\1\uffff\1\11\1\12\1\13\2\uffff\1\15\1\17\1\20\1\uffff\1\22\1\23"+ - "\1\24\1\25\2\uffff\1\31\1\33\1\34\1\35\1\uffff\1\37\1\40\1\41\1"+ - "\uffff\1\44\1\45\14\uffff\1\14\1\uffff\1\21\3\uffff\1\36\1\42\1"+ - "\uffff\1\7\1\16\1\26\2\uffff\1\46\2\uffff\1\32\10\uffff\1\27\1\30"; + "\30\uffff\1\61\1\62\1\63\1\64\6\uffff\1\4\3\uffff\1\10\30\uffff"+ + "\1\45\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\1\1\2\1\3\1\5\1"+ + "\6\1\uffff\1\11\1\12\1\uffff\1\14\2\uffff\1\16\1\20\1\21\1\uffff"+ + "\1\23\1\uffff\1\25\1\26\1\27\2\uffff\1\33\1\35\1\36\1\37\1\uffff"+ + "\1\41\1\42\1\43\1\uffff\1\46\1\47\17\uffff\1\15\1\uffff\1\22\1\24"+ + "\3\uffff\1\40\1\44\1\uffff\1\7\1\uffff\1\17\1\30\2\uffff\1\50\3"+ + "\uffff\1\34\1\13\10\uffff\1\31\1\32"; static final String DFA2_specialS = - "\u008c\uffff}>"; + "\u0099\uffff}>"; static final String[] DFA2_transitionS = { - "\1\20\7\uffff\1\27\1\33\1\uffff\1\24\1\23\1\22\1\26\1\25\12"+ - "\26\1\21\1\30\5\uffff\1\1\1\2\1\3\1\4\1\5\1\6\1\7\3\26\1\10"+ - "\4\26\1\11\1\26\1\12\1\13\1\14\1\15\1\16\1\17\3\26\1\31\1\uffff"+ - "\1\32\3\uffff\32\26", + "\1\20\7\uffff\1\26\1\27\1\uffff\1\24\1\23\1\22\1\30\1\25\12"+ + "\30\1\21\1\31\5\uffff\1\1\1\2\1\3\1\4\1\5\1\6\1\7\3\30\1\10"+ + "\4\30\1\11\1\30\1\12\1\13\1\14\1\15\1\16\1\17\3\30\1\32\1\uffff"+ + "\1\33\3\uffff\32\30", "\1\34\15\uffff\1\35\6\uffff\1\36", - "\1\26\12\uffff\20\26\6\uffff\2\26\1\37\16\26\1\40\10\26\6\uffff"+ - "\13\26\1\41\16\26", - "\1\26\12\uffff\20\26\6\uffff\1\43\16\26\1\44\12\26\6\uffff"+ - "\32\26", - "\1\46\14\uffff\1\47", - "\1\50", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\2\30\1\37\16\30\1"+ + "\40\10\30\6\uffff\13\30\1\41\16\30", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\1\43\16\30\1\44\12"+ + "\30\6\uffff\16\30\1\45\13\30", + "\1\47\14\uffff\1\50", "\1\51", - "\1\52\23\uffff\1\53", - "\1\54", - "\1\55\1\56\23\uffff\1\57\24\uffff\1\60", - "\1\61\17\uffff\1\62", - "\1\63\12\uffff\1\64\16\uffff\1\65", - "\1\66", - "\1\67", - "\1\70\21\uffff\1\71", - "\1\26\12\uffff\20\26\6\uffff\2\26\1\72\16\26\1\73\10\26\6\uffff"+ - "\7\26\1\74\22\26", - "\1\26\12\uffff\20\26\6\uffff\32\26\6\uffff\32\26", - "\1\26\12\uffff\20\26\6\uffff\32\26\6\uffff\32\26", - "\1\26\12\uffff\20\26\6\uffff\32\26\6\uffff\32\26", - "\1\26\12\uffff\20\26\6\uffff\32\26\6\uffff\32\26", - "\1\26\12\uffff\20\26\6\uffff\32\26\6\uffff\32\26", - "\1\26\12\uffff\20\26\6\uffff\32\26\6\uffff\32\26", + "\1\52", + "\1\53\23\uffff\1\54", + "\1\55\41\uffff\1\56", + "\1\57\1\60\23\uffff\1\61\24\uffff\1\62", + "\1\63\17\uffff\1\64", + "\1\65\12\uffff\1\66\16\uffff\1\67", + "\1\70", + "\1\71", + "\1\72\21\uffff\1\73", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\2\30\1\74\16\30\1"+ + "\75\10\30\6\uffff\7\30\1\76\22\30", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", "", "", "", "", - "", - "", - "\1\26\12\uffff\20\26\6\uffff\32\26\6\uffff\32\26", - "\1\26\12\uffff\20\26\6\uffff\32\26\6\uffff\32\26", - "\1\26\12\uffff\20\26\6\uffff\32\26\6\uffff\32\26", - "\1\26\12\uffff\20\26\6\uffff\32\26\6\uffff\32\26", - "\1\26\12\uffff\20\26\6\uffff\32\26\6\uffff\32\26", - "\1\111", - "", - "\1\26\12\uffff\20\26\6\uffff\32\26\6\uffff\32\26", - "\1\26\12\uffff\20\26\6\uffff\32\26\6\uffff\32\26", - "", - "\1\26\12\uffff\20\26\6\uffff\32\26\6\uffff\32\26", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", "\1\115", - "\1\26\12\uffff\20\26\6\uffff\32\26\6\uffff\4\26\1\116\25\26", - "\1\26\12\uffff\20\26\6\uffff\32\26\6\uffff\32\26", - "\1\26\12\uffff\20\26\6\uffff\32\26\6\uffff\32\26", + "", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", + "\1\120", + "", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", "\1\122", - "\1\26\12\uffff\20\26\6\uffff\32\26\6\uffff\32\26", - "\1\26\12\uffff\20\26\6\uffff\32\26\6\uffff\32\26", - "\1\26\12\uffff\20\26\6\uffff\32\26\6\uffff\32\26", - "\1\26\12\uffff\20\26\6\uffff\32\26\6\uffff\32\26", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\4\30"+ + "\1\123\25\30", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", "\1\127", - "\1\26\12\uffff\20\26\6\uffff\32\26\6\uffff\22\26\1\130\7\26", - "\1\26\12\uffff\20\26\6\uffff\32\26\6\uffff\32\26", - "\1\26\12\uffff\20\26\6\uffff\32\26\6\uffff\32\26", - "\1\26\12\uffff\20\26\6\uffff\32\26\6\uffff\32\26", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", + "\1\131", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", "\1\135", - "\1\26\12\uffff\20\26\6\uffff\32\26\6\uffff\32\26", - "\1\26\12\uffff\20\26\6\uffff\32\26\6\uffff\32\26", - "\1\26\12\uffff\20\26\6\uffff\32\26\6\uffff\32\26", - "\1\141", - "\1\26\12\uffff\20\26\6\uffff\32\26\6\uffff\32\26", - "\1\26\12\uffff\20\26\6\uffff\32\26\6\uffff\32\26", - "\1\144", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "\1\145", - "", - "", - "", - "\1\146", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\22\30"+ + "\1\136\7\30", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", + "\1\143", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", "\1\147", - "", - "", - "", - "\1\150", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", + "\1\152", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", "", "", "", "", - "\1\151\65\uffff\1\152", "\1\153", "", "", - "", - "", "\1\154", "", - "", - "", "\1\155", - "", - "", "\1\156", + "", + "", + "", "\1\157", - "\1\26\12\uffff\20\26\6\uffff\32\26\6\uffff\32\26", - "\1\161", - "\1\26\12\uffff\20\26\6\uffff\32\26\6\uffff\32\26", + "", + "\1\160", + "", + "", + "", + "\1\161\65\uffff\1\162", "\1\163", + "", + "", + "", + "", "\1\164", + "", + "", + "", "\1\165", - "\1\26\12\uffff\20\26\6\uffff\32\26\6\uffff\32\26", - "\1\26\12\uffff\20\26\6\uffff\32\26\6\uffff\32\26", + "", + "", + "\1\166", + "\1\167", "\1\170", - "\1\26\12\uffff\20\26\6\uffff\32\26\6\uffff\32\26", - "", - "\1\26\12\uffff\20\26\6\uffff\32\26\6\uffff\32\26", - "", - "\1\26\12\uffff\20\26\6\uffff\32\26\6\uffff\32\26", - "\1\174", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", + "\1\172", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", "\1\175", - "", - "", - "\1\26\12\uffff\20\26\6\uffff\32\26\6\uffff\32\26", - "", - "", - "", - "\1\177\24\uffff\1\u0080", - "\1\26\12\uffff\20\26\6\uffff\32\26\6\uffff\32\26", - "", + "\1\176", + "\1\177", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", "\1\u0082", - "\1\u0083", - "", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", "\1\u0084", - "\1\u0085", - "\1\u0086", + "", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", + "", + "", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", "\1\u0087", "\1\u0088", - "\1\u0089", - "\1\26\12\uffff\20\26\6\uffff\32\26\6\uffff\32\26", - "\1\26\12\uffff\20\26\6\uffff\32\26\6\uffff\32\26", + "", + "", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", + "", + "\1\u008a", + "", + "", + "\1\u008b\24\uffff\1\u008c", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", + "", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", + "\1\u008f", + "\1\u0090", + "", + "", + "\1\u0091", + "\1\u0092", + "\1\u0093", + "\1\u0094", + "\1\u0095", + "\1\u0096", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", + "\1\30\7\uffff\2\30\1\uffff\20\30\6\uffff\32\30\6\uffff\32\30", "", "" }; @@ -1962,7 +2046,7 @@ public class SGFLexer extends Lexer { this.transition = DFA2_transition; } public String getDescription() { - return "1:1: Tokens : ( T__20 | T__21 | T__22 | T__23 | T__24 | T__25 | T__26 | T__27 | T__28 | T__29 | T__30 | T__31 | T__32 | T__33 | T__34 | T__35 | T__36 | T__37 | T__38 | T__39 | T__40 | T__41 | T__42 | T__43 | T__44 | T__45 | T__46 | T__47 | T__48 | T__49 | T__50 | T__51 | T__52 | T__53 | T__54 | T__55 | T__56 | T__57 | SPACE | COLON | MINUS | COMMA | PLUS | SLASH | STRVALUE | LPAREN | SEMICOLON | LBRACKET | RBRACKET | RPAREN );"; + return "1:1: Tokens : ( T__20 | T__21 | T__22 | T__23 | T__24 | T__25 | T__26 | T__27 | T__28 | T__29 | T__30 | T__31 | T__32 | T__33 | T__34 | T__35 | T__36 | T__37 | T__38 | T__39 | T__40 | T__41 | T__42 | T__43 | T__44 | T__45 | T__46 | T__47 | T__48 | T__49 | T__50 | T__51 | T__52 | T__53 | T__54 | T__55 | T__56 | T__57 | T__58 | T__59 | SPACE | COLON | MINUS | COMMA | PLUS | SLASH | LPAREN | RPAREN | STRVALUE | SEMICOLON | LBRACKET | RBRACKET );"; } } diff --git a/src/net/woodyfolsom/msproj/sgf/SGFNode.java b/src/net/woodyfolsom/msproj/sgf/SGFNode.java index 1a68744..d44f5dd 100644 --- a/src/net/woodyfolsom/msproj/sgf/SGFNode.java +++ b/src/net/woodyfolsom/msproj/sgf/SGFNode.java @@ -41,6 +41,10 @@ public class SGFNode { return properties.get(i).getValues().get(0); } } + if (identifier == SGFIdentifier.KOMI) { + System.out.println("This node does not contain " + identifier + ", using default value 0.0."); + return new SGFValue(0.0); + } throw new RuntimeException( "SGFNode does not contain a property with identifier '" + identifier + "'"); diff --git a/src/net/woodyfolsom/msproj/sgf/SGFParser.java b/src/net/woodyfolsom/msproj/sgf/SGFParser.java index f01c250..8b20951 100644 --- a/src/net/woodyfolsom/msproj/sgf/SGFParser.java +++ b/src/net/woodyfolsom/msproj/sgf/SGFParser.java @@ -1,4 +1,4 @@ -// $ANTLR 3.4 C:\\Users\\Woody\\Documents\\antlr\\SGF.g 2012-11-14 04:25:56 +// $ANTLR 3.4 C:\\Users\\Woody\\Documents\\antlr\\SGF.g 2012-11-17 16:41:53 package net.woodyfolsom.msproj.sgf; import org.antlr.runtime.*; @@ -9,7 +9,7 @@ import java.util.ArrayList; @SuppressWarnings({"all", "warnings", "unchecked"}) public class SGFParser extends Parser { public static final String[] tokenNames = new String[] { - "", "", "", "", "COLON", "COMMA", "DIGIT", "LBRACKET", "LCLETTER", "LPAREN", "MINUS", "PERIOD", "PLUS", "RBRACKET", "RPAREN", "SEMICOLON", "SLASH", "SPACE", "STRVALUE", "UCLETTER", "'AB'", "'AP'", "'AW'", "'B'", "'BC'", "'BR'", "'Black'", "'C'", "'CA'", "'CP'", "'DT'", "'DaTe'", "'EV'", "'EVent'", "'FF'", "'GM'", "'GaMe'", "'KM'", "'PB'", "'PC'", "'PW'", "'PlaCe'", "'PlayerBlack'", "'PlayerWhite'", "'RE'", "'REsult'", "'RU'", "'SO'", "'SZ'", "'SiZe'", "'TM'", "'US'", "'VW'", "'VieW'", "'W'", "'WC'", "'WR'", "'White'" + "", "", "", "", "COLON", "COMMA", "DIGIT", "LBRACKET", "LCLETTER", "LPAREN", "MINUS", "PERIOD", "PLUS", "RBRACKET", "RPAREN", "SEMICOLON", "SLASH", "SPACE", "STRVALUE", "UCLETTER", "'AB'", "'AP'", "'AW'", "'B'", "'BC'", "'BR'", "'Black'", "'C'", "'CA'", "'CP'", "'Comment'", "'DT'", "'DaTe'", "'EV'", "'EVent'", "'FF'", "'GM'", "'GaMe'", "'KM'", "'KoMi'", "'PB'", "'PC'", "'PW'", "'PlaCe'", "'PlayerBlack'", "'PlayerWhite'", "'RE'", "'REsult'", "'RU'", "'SO'", "'SZ'", "'SiZe'", "'TM'", "'US'", "'VW'", "'VieW'", "'W'", "'WC'", "'WR'", "'White'" }; public static final int EOF=-1; @@ -51,6 +51,8 @@ public class SGFParser extends Parser { public static final int T__55=55; public static final int T__56=56; public static final int T__57=57; + public static final int T__58=58; + public static final int T__59=59; public static final int COLON=4; public static final int COMMA=5; public static final int DIGIT=6; @@ -329,7 +331,7 @@ public class SGFParser extends Parser { int alt4=2; int LA4_0 = input.LA(1); - if ( ((LA4_0 >= 20 && LA4_0 <= 57)) ) { + if ( ((LA4_0 >= 20 && LA4_0 <= 59)) ) { alt4=1; } @@ -410,12 +412,12 @@ public class SGFParser extends Parser { // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:37:2: ( ( numIdent ) ( ( LBRACKET numValue RBRACKET ) )+ | ( playerIdent ) ( ( LBRACKET RBRACKET ) )+ | ( playerIdent ) ( ( LBRACKET coordValue RBRACKET ) )+ | ( strIdent ) ( ( LBRACKET RBRACKET ) ) | ( strIdent ) ( ( LBRACKET strValue RBRACKET ) )+ | ( result ) ( ( LBRACKET strValue RBRACKET ) )+ | ( komi ) ( ( LBRACKET realValue RBRACKET ) )+ | ( coordIdent ) ( ( LBRACKET coordValue RBRACKET ) )+ ) int alt12=8; switch ( input.LA(1) ) { - case 34: case 35: case 36: - case 48: - case 49: + case 37: case 50: + case 51: + case 52: { alt12=1; } @@ -492,7 +494,7 @@ public class SGFParser extends Parser { } } break; - case 47: + case 49: { int LA12_3 = input.LA(2); @@ -636,7 +638,7 @@ public class SGFParser extends Parser { } } break; - case 55: + case 57: { int LA12_5 = input.LA(2); @@ -708,8 +710,8 @@ public class SGFParser extends Parser { } } break; - case 32: case 33: + case 34: { int LA12_6 = input.LA(2); @@ -781,8 +783,8 @@ public class SGFParser extends Parser { } } break; - case 38: - case 42: + case 40: + case 44: { int LA12_7 = input.LA(2); @@ -854,8 +856,8 @@ public class SGFParser extends Parser { } } break; - case 40: - case 43: + case 42: + case 45: { int LA12_8 = input.LA(2); @@ -999,7 +1001,7 @@ public class SGFParser extends Parser { } } break; - case 56: + case 58: { int LA12_10 = input.LA(2); @@ -1071,7 +1073,7 @@ public class SGFParser extends Parser { } } break; - case 46: + case 48: { int LA12_11 = input.LA(2); @@ -1143,8 +1145,8 @@ public class SGFParser extends Parser { } } break; - case 39: case 41: + case 43: { int LA12_12 = input.LA(2); @@ -1360,7 +1362,7 @@ public class SGFParser extends Parser { } } break; - case 51: + case 53: { int LA12_15 = input.LA(2); @@ -1432,8 +1434,8 @@ public class SGFParser extends Parser { } } break; - case 30: case 31: + case 32: { int LA12_16 = input.LA(2); @@ -1577,7 +1579,7 @@ public class SGFParser extends Parser { } } break; - case 57: + case 59: { int LA12_18 = input.LA(2); @@ -1721,7 +1723,7 @@ public class SGFParser extends Parser { } } break; - case 54: + case 56: { int LA12_20 = input.LA(2); @@ -1793,8 +1795,8 @@ public class SGFParser extends Parser { } } break; - case 52: - case 53: + case 54: + case 55: { int LA12_21 = input.LA(2); @@ -1867,6 +1869,7 @@ public class SGFParser extends Parser { } break; case 27: + case 30: { int LA12_22 = input.LA(2); @@ -1938,13 +1941,14 @@ public class SGFParser extends Parser { } } break; - case 44: - case 45: + case 46: + case 47: { alt12=6; } break; - case 37: + case 38: + case 39: { alt12=7; } @@ -2518,7 +2522,7 @@ public class SGFParser extends Parser { } } break; - case 47: + case 49: { int LA13_2 = input.LA(2); @@ -2568,7 +2572,7 @@ public class SGFParser extends Parser { } } break; - case 55: + case 57: { int LA13_4 = input.LA(2); @@ -2593,8 +2597,8 @@ public class SGFParser extends Parser { } } break; - case 32: case 33: + case 34: { int LA13_5 = input.LA(2); @@ -2619,8 +2623,8 @@ public class SGFParser extends Parser { } } break; - case 38: - case 42: + case 40: + case 44: { int LA13_6 = input.LA(2); @@ -2645,8 +2649,8 @@ public class SGFParser extends Parser { } } break; - case 40: - case 43: + case 42: + case 45: { int LA13_7 = input.LA(2); @@ -2696,7 +2700,7 @@ public class SGFParser extends Parser { } } break; - case 56: + case 58: { int LA13_9 = input.LA(2); @@ -2721,7 +2725,7 @@ public class SGFParser extends Parser { } } break; - case 46: + case 48: { int LA13_10 = input.LA(2); @@ -2746,8 +2750,8 @@ public class SGFParser extends Parser { } } break; - case 39: case 41: + case 43: { int LA13_11 = input.LA(2); @@ -2822,7 +2826,7 @@ public class SGFParser extends Parser { } } break; - case 51: + case 53: { int LA13_14 = input.LA(2); @@ -2847,8 +2851,8 @@ public class SGFParser extends Parser { } } break; - case 30: case 31: + case 32: { int LA13_15 = input.LA(2); @@ -2898,7 +2902,7 @@ public class SGFParser extends Parser { } } break; - case 57: + case 59: { int LA13_17 = input.LA(2); @@ -2948,7 +2952,7 @@ public class SGFParser extends Parser { } } break; - case 54: + case 56: { int LA13_19 = input.LA(2); @@ -2973,8 +2977,8 @@ public class SGFParser extends Parser { } } break; - case 52: - case 53: + case 54: + case 55: { int LA13_20 = input.LA(2); @@ -3000,6 +3004,7 @@ public class SGFParser extends Parser { } break; case 27: + case 30: { int LA13_21 = input.LA(2); @@ -3133,7 +3138,7 @@ public class SGFParser extends Parser { alt14=1; } break; - case 47: + case 49: { alt14=2; } @@ -3143,25 +3148,25 @@ public class SGFParser extends Parser { alt14=3; } break; - case 55: + case 57: { alt14=4; } break; - case 32: case 33: + case 34: { alt14=5; } break; - case 38: - case 42: + case 40: + case 44: { alt14=6; } break; - case 40: - case 43: + case 42: + case 45: { alt14=7; } @@ -3171,18 +3176,18 @@ public class SGFParser extends Parser { alt14=8; } break; - case 56: + case 58: { alt14=9; } break; - case 46: + case 48: { alt14=10; } break; - case 39: case 41: + case 43: { alt14=11; } @@ -3197,13 +3202,13 @@ public class SGFParser extends Parser { alt14=13; } break; - case 51: + case 53: { alt14=14; } break; - case 30: case 31: + case 32: { alt14=15; } @@ -3213,7 +3218,7 @@ public class SGFParser extends Parser { alt14=16; } break; - case 57: + case 59: { alt14=17; } @@ -3223,18 +3228,19 @@ public class SGFParser extends Parser { alt14=18; } break; - case 54: + case 56: { alt14=19; } break; - case 52: - case 53: + case 54: + case 55: { alt14=20; } break; case 27: + case 30: { alt14=21; } @@ -3451,7 +3457,7 @@ public class SGFParser extends Parser { case 17 : // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:78:11: 'White' { - match(input,57,FOLLOW_57_in_strIdent517); + match(input,59,FOLLOW_59_in_strIdent517); sgfIdent = SGFIdentifier.MOVE_WHITE; @@ -3469,7 +3475,7 @@ public class SGFParser extends Parser { case 19 : // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:80:11: 'W' { - match(input,54,FOLLOW_54_in_strIdent543); + match(input,56,FOLLOW_56_in_strIdent543); sgfIdent = SGFIdentifier.MOVE_WHITE; @@ -3601,24 +3607,24 @@ public class SGFParser extends Parser { // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:93:2: ( fileFormat | game | size | time ) int alt16=4; switch ( input.LA(1) ) { - case 34: + case 35: { alt16=1; } break; - case 35: case 36: + case 37: { alt16=2; } break; - case 48: - case 49: + case 50: + case 51: { alt16=3; } break; - case 50: + case 52: { alt16=4; } @@ -3858,7 +3864,7 @@ public class SGFParser extends Parser { // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:112:2: ( 'FF' ) // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:112:4: 'FF' { - match(input,34,FOLLOW_34_in_fileFormat727); + match(input,35,FOLLOW_35_in_fileFormat727); } @@ -3884,7 +3890,7 @@ public class SGFParser extends Parser { // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:114:7: ( 'GM' | 'GaMe' ) // C:\\Users\\Woody\\Documents\\antlr\\SGF.g: { - if ( (input.LA(1) >= 35 && input.LA(1) <= 36) ) { + if ( (input.LA(1) >= 36 && input.LA(1) <= 37) ) { input.consume(); state.errorRecovery=false; } @@ -3918,7 +3924,7 @@ public class SGFParser extends Parser { // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:116:7: ( 'SZ' | 'SiZe' ) // C:\\Users\\Woody\\Documents\\antlr\\SGF.g: { - if ( (input.LA(1) >= 48 && input.LA(1) <= 49) ) { + if ( (input.LA(1) >= 50 && input.LA(1) <= 51) ) { input.consume(); state.errorRecovery=false; } @@ -3952,7 +3958,7 @@ public class SGFParser extends Parser { // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:118:7: ( 'VW' | 'VieW' ) // C:\\Users\\Woody\\Documents\\antlr\\SGF.g: { - if ( (input.LA(1) >= 52 && input.LA(1) <= 53) ) { + if ( (input.LA(1) >= 54 && input.LA(1) <= 55) ) { input.consume(); state.errorRecovery=false; } @@ -4012,7 +4018,7 @@ public class SGFParser extends Parser { // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:122:8: ( 'SO' ) // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:122:10: 'SO' { - match(input,47,FOLLOW_47_in_source783); + match(input,49,FOLLOW_49_in_source783); } @@ -4064,7 +4070,7 @@ public class SGFParser extends Parser { // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:128:2: ( 'WC' ) // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:128:4: 'WC' { - match(input,55,FOLLOW_55_in_whiteCountry804); + match(input,57,FOLLOW_57_in_whiteCountry804); } @@ -4090,7 +4096,7 @@ public class SGFParser extends Parser { // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:130:7: ( 'EV' | 'EVent' ) // C:\\Users\\Woody\\Documents\\antlr\\SGF.g: { - if ( (input.LA(1) >= 32 && input.LA(1) <= 33) ) { + if ( (input.LA(1) >= 33 && input.LA(1) <= 34) ) { input.consume(); state.errorRecovery=false; } @@ -4124,7 +4130,7 @@ public class SGFParser extends Parser { // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:133:2: ( 'PB' | 'PlayerBlack' ) // C:\\Users\\Woody\\Documents\\antlr\\SGF.g: { - if ( input.LA(1)==38||input.LA(1)==42 ) { + if ( input.LA(1)==40||input.LA(1)==44 ) { input.consume(); state.errorRecovery=false; } @@ -4158,7 +4164,7 @@ public class SGFParser extends Parser { // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:135:2: ( 'PW' | 'PlayerWhite' ) // C:\\Users\\Woody\\Documents\\antlr\\SGF.g: { - if ( input.LA(1)==40||input.LA(1)==43 ) { + if ( input.LA(1)==42||input.LA(1)==45 ) { input.consume(); state.errorRecovery=false; } @@ -4218,7 +4224,7 @@ public class SGFParser extends Parser { // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:140:2: ( 'WR' ) // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:140:5: 'WR' { - match(input,56,FOLLOW_56_in_whiteRank861); + match(input,58,FOLLOW_58_in_whiteRank861); } @@ -4238,13 +4244,21 @@ public class SGFParser extends Parser { // $ANTLR start "komi" - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:142:1: komi : 'KM' ; + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:142:1: komi : ( 'KM' | 'KoMi' ); public final void komi() throws RecognitionException { try { - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:142:7: ( 'KM' ) - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:142:9: 'KM' + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:142:7: ( 'KM' | 'KoMi' ) + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g: { - match(input,37,FOLLOW_37_in_komi871); + if ( (input.LA(1) >= 38 && input.LA(1) <= 39) ) { + input.consume(); + state.errorRecovery=false; + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + throw mse; + } + } @@ -4270,7 +4284,7 @@ public class SGFParser extends Parser { // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:144:9: ( 'RE' | 'REsult' ) // C:\\Users\\Woody\\Documents\\antlr\\SGF.g: { - if ( (input.LA(1) >= 44 && input.LA(1) <= 45) ) { + if ( (input.LA(1) >= 46 && input.LA(1) <= 47) ) { input.consume(); state.errorRecovery=false; } @@ -4304,7 +4318,7 @@ public class SGFParser extends Parser { // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:148:7: ( 'RU' ) // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:148:9: 'RU' { - match(input,46,FOLLOW_46_in_rules897); + match(input,48,FOLLOW_48_in_rules901); } @@ -4330,7 +4344,7 @@ public class SGFParser extends Parser { // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:150:8: ( 'PC' | 'PlaCe' ) // C:\\Users\\Woody\\Documents\\antlr\\SGF.g: { - if ( input.LA(1)==39||input.LA(1)==41 ) { + if ( input.LA(1)==41||input.LA(1)==43 ) { input.consume(); state.errorRecovery=false; } @@ -4364,7 +4378,7 @@ public class SGFParser extends Parser { // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:153:2: ( 'AP' ) // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:153:4: 'AP' { - match(input,21,FOLLOW_21_in_application919); + match(input,21,FOLLOW_21_in_application923); } @@ -4390,7 +4404,7 @@ public class SGFParser extends Parser { // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:155:6: ( 'TM' ) // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:155:8: 'TM' { - match(input,50,FOLLOW_50_in_time928); + match(input,52,FOLLOW_52_in_time932); } @@ -4416,7 +4430,7 @@ public class SGFParser extends Parser { // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:157:7: ( 'DT' | 'DaTe' ) // C:\\Users\\Woody\\Documents\\antlr\\SGF.g: { - if ( (input.LA(1) >= 30 && input.LA(1) <= 31) ) { + if ( (input.LA(1) >= 31 && input.LA(1) <= 32) ) { input.consume(); state.errorRecovery=false; } @@ -4453,7 +4467,7 @@ public class SGFParser extends Parser { // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:160:2: ( 'AB' ) // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:160:4: 'AB' { - match(input,20,FOLLOW_20_in_addBlack954); + match(input,20,FOLLOW_20_in_addBlack958); sgfIdent = SGFIdentifier.ADD_BLACK; @@ -4484,7 +4498,7 @@ public class SGFParser extends Parser { // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:164:2: ( 'AW' ) // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:164:4: 'AW' { - match(input,22,FOLLOW_22_in_addWhite971); + match(input,22,FOLLOW_22_in_addWhite975); sgfIdent = SGFIdentifier.ADD_WHITE; @@ -4512,7 +4526,7 @@ public class SGFParser extends Parser { // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:168:2: ( 'CP' ) // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:168:4: 'CP' { - match(input,29,FOLLOW_29_in_copyright983); + match(input,29,FOLLOW_29_in_copyright987); } @@ -4538,7 +4552,7 @@ public class SGFParser extends Parser { // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:170:9: ( 'US' ) // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:170:11: 'US' { - match(input,51,FOLLOW_51_in_username990); + match(input,53,FOLLOW_53_in_username994); } @@ -4558,13 +4572,21 @@ public class SGFParser extends Parser { // $ANTLR start "comment" - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:172:1: comment : 'C' ; + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:172:1: comment : ( 'C' | 'Comment' ); public final void comment() throws RecognitionException { try { - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:172:9: ( 'C' ) - // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:172:11: 'C' + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:172:9: ( 'C' | 'Comment' ) + // C:\\Users\\Woody\\Documents\\antlr\\SGF.g: { - match(input,27,FOLLOW_27_in_comment998); + if ( input.LA(1)==27||input.LA(1)==30 ) { + input.consume(); + state.errorRecovery=false; + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + throw mse; + } + } @@ -4613,7 +4635,7 @@ public class SGFParser extends Parser { case 1 : // C:\\Users\\Woody\\Documents\\antlr\\SGF.g:175:5: STRVALUE { - match(input,STRVALUE,FOLLOW_STRVALUE_in_strValue1009); + match(input,STRVALUE,FOLLOW_STRVALUE_in_strValue1017); } break; @@ -4657,8 +4679,8 @@ public class SGFParser extends Parser { public static final BitSet FOLLOW_gameTree_in_gameTree67 = new BitSet(new long[]{0x0000000000004200L}); public static final BitSet FOLLOW_RPAREN_in_gameTree72 = new BitSet(new long[]{0x0000000000000002L}); public static final BitSet FOLLOW_node_in_sequence94 = new BitSet(new long[]{0x0000000000008002L}); - public static final BitSet FOLLOW_SEMICOLON_in_node115 = new BitSet(new long[]{0x03FFFFFFFFF00002L}); - public static final BitSet FOLLOW_property_in_node118 = new BitSet(new long[]{0x03FFFFFFFFF00002L}); + public static final BitSet FOLLOW_SEMICOLON_in_node115 = new BitSet(new long[]{0x0FFFFFFFFFF00002L}); + public static final BitSet FOLLOW_property_in_node118 = new BitSet(new long[]{0x0FFFFFFFFFF00002L}); public static final BitSet FOLLOW_numIdent_in_property140 = new BitSet(new long[]{0x0000000000000080L}); public static final BitSet FOLLOW_LBRACKET_in_property146 = new BitSet(new long[]{0x0000000000040000L}); public static final BitSet FOLLOW_numValue_in_property148 = new BitSet(new long[]{0x0000000000002000L}); @@ -4709,9 +4731,9 @@ public class SGFParser extends Parser { public static final BitSet FOLLOW_username_in_strIdent479 = new BitSet(new long[]{0x0000000000000002L}); public static final BitSet FOLLOW_date_in_strIdent491 = new BitSet(new long[]{0x0000000000000002L}); public static final BitSet FOLLOW_26_in_strIdent504 = new BitSet(new long[]{0x0000000000000002L}); - public static final BitSet FOLLOW_57_in_strIdent517 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_59_in_strIdent517 = new BitSet(new long[]{0x0000000000000002L}); public static final BitSet FOLLOW_23_in_strIdent530 = new BitSet(new long[]{0x0000000000000002L}); - public static final BitSet FOLLOW_54_in_strIdent543 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_56_in_strIdent543 = new BitSet(new long[]{0x0000000000000002L}); public static final BitSet FOLLOW_view_in_strIdent556 = new BitSet(new long[]{0x0000000000000002L}); public static final BitSet FOLLOW_comment_in_strIdent570 = new BitSet(new long[]{0x0000000000000002L}); public static final BitSet FOLLOW_addBlack_in_coordIdent616 = new BitSet(new long[]{0x0000000000000002L}); @@ -4724,22 +4746,20 @@ public class SGFParser extends Parser { public static final BitSet FOLLOW_komi_in_realIdent688 = new BitSet(new long[]{0x0000000000000002L}); public static final BitSet FOLLOW_STRVALUE_in_realValue698 = new BitSet(new long[]{0x0000000000000002L}); public static final BitSet FOLLOW_STRVALUE_in_coordValue713 = new BitSet(new long[]{0x0000000000000002L}); - public static final BitSet FOLLOW_34_in_fileFormat727 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_35_in_fileFormat727 = new BitSet(new long[]{0x0000000000000002L}); public static final BitSet FOLLOW_28_in_charEnc775 = new BitSet(new long[]{0x0000000000000002L}); - public static final BitSet FOLLOW_47_in_source783 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_49_in_source783 = new BitSet(new long[]{0x0000000000000002L}); public static final BitSet FOLLOW_24_in_blackCountry793 = new BitSet(new long[]{0x0000000000000002L}); - public static final BitSet FOLLOW_55_in_whiteCountry804 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_57_in_whiteCountry804 = new BitSet(new long[]{0x0000000000000002L}); public static final BitSet FOLLOW_25_in_blackRank850 = new BitSet(new long[]{0x0000000000000002L}); - public static final BitSet FOLLOW_56_in_whiteRank861 = new BitSet(new long[]{0x0000000000000002L}); - public static final BitSet FOLLOW_37_in_komi871 = new BitSet(new long[]{0x0000000000000002L}); - public static final BitSet FOLLOW_46_in_rules897 = new BitSet(new long[]{0x0000000000000002L}); - public static final BitSet FOLLOW_21_in_application919 = new BitSet(new long[]{0x0000000000000002L}); - public static final BitSet FOLLOW_50_in_time928 = new BitSet(new long[]{0x0000000000000002L}); - public static final BitSet FOLLOW_20_in_addBlack954 = new BitSet(new long[]{0x0000000000000002L}); - public static final BitSet FOLLOW_22_in_addWhite971 = new BitSet(new long[]{0x0000000000000002L}); - public static final BitSet FOLLOW_29_in_copyright983 = new BitSet(new long[]{0x0000000000000002L}); - public static final BitSet FOLLOW_51_in_username990 = new BitSet(new long[]{0x0000000000000002L}); - public static final BitSet FOLLOW_27_in_comment998 = new BitSet(new long[]{0x0000000000000002L}); - public static final BitSet FOLLOW_STRVALUE_in_strValue1009 = new BitSet(new long[]{0x0000000000040002L}); + public static final BitSet FOLLOW_58_in_whiteRank861 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_48_in_rules901 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_21_in_application923 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_52_in_time932 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_20_in_addBlack958 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_22_in_addWhite975 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_29_in_copyright987 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_53_in_username994 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_STRVALUE_in_strValue1017 = new BitSet(new long[]{0x0000000000040002L}); } \ No newline at end of file diff --git a/test/net/woodyfolsom/msproj/GameBoardTest.java b/test/net/woodyfolsom/msproj/GameBoardTest.java new file mode 100644 index 0000000..cb007d4 --- /dev/null +++ b/test/net/woodyfolsom/msproj/GameBoardTest.java @@ -0,0 +1,29 @@ +package net.woodyfolsom.msproj; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class GameBoardTest { + @Test + public void testCapture() { + GameConfig gameConfig = new GameConfig(5); + GameState gameState = new GameState(gameConfig); + + assertTrue(gameState.placeStone(Player.BLACK, Action.getInstance("A2"))); + assertTrue(gameState.placeStone(Player.BLACK, Action.getInstance("B3"))); + assertTrue(gameState.placeStone(Player.BLACK, Action.getInstance("B1"))); + assertTrue(gameState.placeStone(Player.BLACK, Action.getInstance("C2"))); + + assertTrue(gameState.isSelfFill(Action.getInstance("B2"), Player.BLACK)); + assertFalse(gameState + .isSelfFill(Action.getInstance("B2"), Player.WHITE)); + assertFalse(gameState + .isSelfFill(Action.getInstance("B4"), Player.BLACK)); + assertFalse(gameState + .isSelfFill(Action.getInstance("B4"), Player.BLACK)); + + System.out.println(gameState); + } +} \ No newline at end of file diff --git a/test/net/woodyfolsom/msproj/GameScoreTest.java b/test/net/woodyfolsom/msproj/GameScoreTest.java index 02adbe6..417b839 100644 --- a/test/net/woodyfolsom/msproj/GameScoreTest.java +++ b/test/net/woodyfolsom/msproj/GameScoreTest.java @@ -1,28 +1,76 @@ package net.woodyfolsom.msproj; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; import net.woodyfolsom.msproj.GameResult; +import net.woodyfolsom.msproj.policy.MonteCarloUCT; +import net.woodyfolsom.msproj.policy.RandomMovePolicy; +import net.woodyfolsom.msproj.policy.RootParallelization; +import net.woodyfolsom.msproj.sgf.SGFLexer; +import net.woodyfolsom.msproj.sgf.SGFNodeCollection; +import net.woodyfolsom.msproj.sgf.SGFParser; +import org.antlr.runtime.ANTLRInputStream; +import org.antlr.runtime.ANTLRStringStream; +import org.antlr.runtime.CommonTokenStream; +import org.antlr.runtime.RecognitionException; import org.junit.Test; public class GameScoreTest { + // public static final String endGameSGF = + // "(;FF[4]GM[1]SZ[9]KM[5.5];B[ef];W[ff];B[dg];W[aa];B[fc];W[da];B[cg];W[ei];B[gf]" + // + + // ";W[fi];B[ag];W[ii];B[bi];W[if];B[db];W[ci];B[cf];W[ih];B[bc];W[hb];B[eb];W[fh];B[ig];W[hc];B[be];W[he];B[gc];" + // + + // "W[id];B[cd];W[df];B[hf];W[ah];B[bh];W[fa];B[bg];W[fe];B[ec];W[eh];B[ee];W[bd];B[hg];W[ie];B[fg];W[ca];B[eg];" + // + + // "W[cb];B[ad];W[ba];B[ch];W[dh];B[gd];W[ic];B[ha];W[ab];B[gh];W[gb];B[ed];W[];B[])"; + + //public static final String endGameSGF = "(;FF[4]GM[1]SZ[9]KM[5.5]RE[W+0.5];B[ef];W[cb];B[fe];W[da];B[cd];W[hh];B[ed];W[cc];B[ci];W[bc];B[cg];W[fi];B[be];W[ea];B[hi];W[df];B[fd];W[bg];B[cf];W[aa];B[gd];W[ch];B[ad];W[dg];B[de];W[ge];B[bh];W[fa];B[ag];W[hd];B[if];W[bi];B[gf];W[bd];B[ah];W[gc];B[ff];W[ca];B[hf];W[dd];B[ce];W[ae];B[ga];W[hc];B[ac];W[gg];B[fg];W[fb];B[ie];W[dh];B[af];W[ec];B[dc];W[id];B[dd];W[eh];B[eb];W[gb];B[ae];W[ic];B[di];W[fh];B[ig];W[ab];B[ha];W[hg];B[hb];W[gi];B[ii];W[ia];B[fc];W[ba];B[eg];W[];B[db];W[];B[])"; + + public static final String endGameSGF = "(;FF[4]GM[1]SZ[6]KM[1.5]RE[B+0.5];B[bb];W[];B[ec];W[ef];B[ac];W[ed];B[ba];W[dc];B[cf];W[];B[])"; @Test public void testGetAggregateScoreZero() { - GameResult gameScore = new GameResult(0,0,19,0, true); - assertEquals(gameScore.getNormalizedZeroScore(), gameScore.getNormalizedScore()); + GameResult gameScore = new GameResult(0, 0, 19, 0, true); + assertEquals(gameScore.getNormalizedZeroScore(), + gameScore.getNormalizedScore()); } - + @Test public void testGetAggregateScoreBlackWinsNoKomi() { - GameResult gameScore = new GameResult(25,2,19,0, true); + GameResult gameScore = new GameResult(25, 2, 19, 0, true); assertEquals(407, gameScore.getNormalizedScore()); } - + @Test public void testGetAggregateScoreWhiteWinsWithKomi() { - GameResult gameScore = new GameResult(10,12,19,6.5, true); + GameResult gameScore = new GameResult(10, 12, 19, 6.5, true); assertEquals(357, gameScore.getNormalizedScore()); } + + @Test + public void testScoreEndGame() throws IOException, RecognitionException { + InputStream is = new ByteArrayInputStream(endGameSGF.getBytes()); + GameRecord gameRecord = Referee.replay(is); + assertEquals(11, gameRecord.getNumTurns()); + + GameState gameState9 = gameRecord.getGameState(9); + + for (int i = 0; i < 5; i++) { + //Action action = new RootParallelization(4, 1000L).getAction(gameRecord.getGameConfig(), gameState9, Player.WHITE); + Action action = new MonteCarloUCT(new RandomMovePolicy(),1000L).getAction(gameRecord.getGameConfig(), gameState9, Player.WHITE); + System.out.println("Suggested action for "+Player.WHITE+": " + action); + } + + gameState9.playStone(Player.WHITE, Action.PASS); + gameState9.playStone(Player.BLACK, Action.PASS); + assertTrue(gameState9.isTerminal()); + System.out.println(gameState9.getResult()); + } } \ No newline at end of file diff --git a/test/net/woodyfolsom/msproj/ann/PassNetworkTest.java b/test/net/woodyfolsom/msproj/ann/PassNetworkTest.java new file mode 100644 index 0000000..ec88c0e --- /dev/null +++ b/test/net/woodyfolsom/msproj/ann/PassNetworkTest.java @@ -0,0 +1,30 @@ +package net.woodyfolsom.msproj.ann; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.neuroph.core.NeuralNetwork; + +public class PassNetworkTest { + + @Test + public void testSavedNetwork() { + NeuralNetwork passFilter = NeuralNetwork.load("data/networks/Pass1.nn"); + passFilter.setInput(0.75,0.25); + passFilter.calculate(); + + PassData passData = new PassData(); + double[] output = passFilter.getOutput(); + System.out.println("Output: " + passData.getOutput(output)); + + assertTrue(output[0] > 0.50); + assertTrue(output[1] < 0.50); + + passFilter.setInput(0.25,0.50); + passFilter.calculate(); + output = passFilter.getOutput(); + System.out.println("Output: " + passData.getOutput(output)); + assertTrue(output[0] < 0.50); + assertTrue(output[1] > 0.50); + } +}