Added connect.bat, made minor changes to kgsGtp.ini. ScratchGo can now easily connect to gokgs.com's server.

It will
look for room whf4cs6999
as whf4human (to avoid creating more accounts)
and will connect to or wait for whf4cs6999.
This commit is contained in:
2012-12-12 19:34:32 -05:00
parent 28dc44b61e
commit 14bc769493
50 changed files with 2462 additions and 264 deletions

0
GoGame.log Normal file
View File

View File

@@ -33,9 +33,16 @@
</target> </target>
<target name="copy-resources"> <target name="copy-resources">
<copy todir="${dist}/data"> <copy todir="${dist}" file="connect.bat" />
<copy todir="${dist}" file="rrt.bat" />
<copy todir="${dist}" file="data/log4j.xml" />
<copy todir="${dist}" file="data/kgsGtp.ini" />
<copy todir="${dist}" file="data/gogame.cfg" />
<!--copy todir="${dist}/data">
<fileset dir="data" /> <fileset dir="data" />
</copy> </copy-->
<copy todir="${build}/net/woodyfolsom/msproj/gui"> <copy todir="${build}/net/woodyfolsom/msproj/gui">
<fileset dir="${src}/net/woodyfolsom/msproj/gui"> <fileset dir="${src}/net/woodyfolsom/msproj/gui">
<exclude name="**/*.java"/> <exclude name="**/*.java"/>

1
connect.bat Normal file
View File

@@ -0,0 +1 @@
java -cp GoGame.jar;antlrworks-1.4.3.jar;kgsGtp.jar;log4j-1.2.16.jar net.woodyfolsom.msproj.GoGame

View File

@@ -1,10 +1,10 @@
PlayerOne=SMAF PlayerOne=ROOT_PAR_AMAF //HUMAN, HUMAN_GUI, ROOT_PAR, UCT, RANDOM, RAVE, SMAF, ROOT_PAR_AMAF
PlayerTwo=RANDOM PlayerTwo=Random
GUIDelay=1000 //1 second GUIDelay=1000 //1 second
BoardSize=9 BoardSize=13 //9, 13 or 19
Komi=6.5 Komi=6.5 //suggested 6.5
NumGames=1 //Games for each color per player NumGames=1 //Games for each color per player
TurnTime=2000 //seconds per player per turn TurnTime=6000 //seconds per player per turn
SpectatorBoardShown=true SpectatorBoardShown=true //set to true for modes which otherwise wouldn't show GUI. false for HUMAN_GUI player.
WhiteMoveLogged=false WhiteMoveLogged=false
BlackMoveLogged=true BlackMoveLogged=true

View File

@@ -1,12 +1,11 @@
engine=java -cp GoGame.jar;log4j-1.2.16.jar net.woodyfolsom.msproj.GoGame montecarlo engine=java -cp GoGame.jar;log4j-1.2.16.jar net.woodyfolsom.msproj.GoGame montecarlo
name=whf4cs6999 name=whf4human
password=6id39p password=t3snxf
room=whf4cs6999 room=whf4cs6999
mode=custom mode=auto
talk=I'm a Monte Carlo tree search bot. talk=I'm a Monte Carlo tree search bot.
opponent=whf4human
reconnect=t reconnect=t
automatch.rank=25k
rules=chinese rules=chinese
rules.boardSize=9 rules.boardSize=9
rules.time=0 rules.time=0
opponent=whf4cs6999

3
gofree.txt Normal file
View File

@@ -0,0 +1,3 @@
UCT-RAVE vs GoFree
level 1 (black) 2/2
level 2 (black) 1/1

11
kgsGtp.ini Normal file
View File

@@ -0,0 +1,11 @@
engine=java -cp GoGame.jar;log4j-1.2.16.jar net.woodyfolsom.msproj.GoGame montecarlo
name=whf4human
password=t3snxf
room=whf4cs6999
mode=auto
talk=I'm a Monte Carlo tree search bot.
reconnect=t
rules=chinese
rules.boardSize=13
rules.time=0
opponent=whf4cs6999

19
log4j.xml Normal file
View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
<appender name="fileAppender" class="org.apache.log4j.RollingFileAppender">
<param name="Threshold" value="INFO" />
<param name="File" value="GoGame.log"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%c{1}] %m %n" />
</layout>
</appender>
<logger name="cs6601.p1" additivity="false" >
<level value="INFO" />
<appender-ref ref="fileAppender"/>
</logger>
</log4j:configuration>

42
pass.net Normal file
View File

@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<multiLayerPerceptron biased="true" name="PassFilter9">
<activationFunction name="Sigmoid"/>
<connections dest="3" src="0" weight="1.9322455294572656"/>
<connections dest="3" src="1" weight="0.0859943747020325"/>
<connections dest="3" src="2" weight="0.8394414489841715"/>
<connections dest="4" src="0" weight="1.5831613048108952"/>
<connections dest="4" src="1" weight="0.8667080746254153"/>
<connections dest="4" src="2" weight="-3.204930958551688"/>
<connections dest="5" src="0" weight="-1.4223906119706369"/>
<connections dest="5" src="3" weight="-2.1292730695450857"/>
<connections dest="5" src="4" weight="-2.5861434868493607"/>
<neurons id="0">
<activationFunction xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="activationFunction" name="Linear"/>
</neurons>
<neurons id="1">
<activationFunction xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="activationFunction" name="Linear"/>
</neurons>
<neurons id="2">
<activationFunction xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="activationFunction" name="Linear"/>
</neurons>
<neurons id="3">
<activationFunction xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="activationFunction" name="Tanh"/>
</neurons>
<neurons id="4">
<activationFunction xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="activationFunction" name="Tanh"/>
</neurons>
<neurons id="5">
<activationFunction name="Sigmoid"/>
</neurons>
<layers>
<neuronIds>1</neuronIds>
<neuronIds>2</neuronIds>
</layers>
<layers>
<neuronIds>3</neuronIds>
<neuronIds>4</neuronIds>
</layers>
<layers>
<neuronIds>5</neuronIds>
</layers>
</multiLayerPerceptron>

1
rrt.bat Normal file
View File

@@ -0,0 +1 @@
java -Xms256m -Xmx4096m -cp GoGame.jar;antlrworks-1.4.3.jar;kgsGtp.jar;log4j-1.2.16.jar net.woodyfolsom.msproj.RoundRobin

View File

@@ -0,0 +1,85 @@
C:\workspace\msproj\dist>java -Xms256m -Xmx4096m -cp GoGame.jar;antlrworks-1.4.3.jar;kgsGtp.jar;log4j-1.2.16.jar net.woodyfolsom.msproj.RoundRobin
Beginning round-robin tournament.
Initializing policies...
Game over. Result: B+5.5
RootParallelization (Black) vs Random (White) : B+5.5
Game over. Result: B+30.5
RootParallelization (Black) vs Random (White) : B+30.5
Game over. Result: B+0.5
RootParallelization (Black) vs Random (White) : B+0.5
Game over. Result: B+18.5
RootParallelization (Black) vs Random (White) : B+18.5
Game over. Result: B+18.5
RootParallelization (Black) vs Random (White) : B+18.5
Game over. Result: B+3.5
RootParallelization (Black) vs Alpha-Beta (White) : B+3.5
Game over. Result: B+0.5
RootParallelization (Black) vs Alpha-Beta (White) : B+0.5
Game over. Result: B+46.5
RootParallelization (Black) vs Alpha-Beta (White) : B+46.5
Game over. Result: B+44.5
RootParallelization (Black) vs Alpha-Beta (White) : B+44.5
Game over. Result: B+53.5
RootParallelization (Black) vs Alpha-Beta (White) : B+53.5
Game over. Result: B+14.5
RootParallelization (Black) vs MonteCarloUCT (White) : B+14.5
Game over. Result: B+30.5
RootParallelization (Black) vs MonteCarloUCT (White) : B+30.5
Game over. Result: B+9.5
RootParallelization (Black) vs MonteCarloUCT (White) : B+9.5
Game over. Result: B+44.5
RootParallelization (Black) vs MonteCarloUCT (White) : B+44.5
Game over. Result: B+29.5
RootParallelization (Black) vs MonteCarloUCT (White) : B+29.5
Game over. Result: B+4.5
RootParallelization (Black) vs UCT-RAVE (White) : B+4.5
Game over. Result: B+27.5
RootParallelization (Black) vs UCT-RAVE (White) : B+27.5
Game over. Result: B+29.5
RootParallelization (Black) vs UCT-RAVE (White) : B+29.5
Game over. Result: B+22.5
RootParallelization (Black) vs UCT-RAVE (White) : B+22.5
Game over. Result: B+36.5
RootParallelization (Black) vs UCT-RAVE (White) : B+36.5
Game over. Result: B+50.5
RootParallelization (Black) vs MonteCarloSMAF (White) : B+50.5
Game over. Result: B+42.5
RootParallelization (Black) vs MonteCarloSMAF (White) : B+42.5
Game over. Result: B+28.5
RootParallelization (Black) vs MonteCarloSMAF (White) : B+28.5
Game over. Result: B+38.5
RootParallelization (Black) vs MonteCarloSMAF (White) : B+38.5
Game over. Result: B+23.5
RootParallelization (Black) vs MonteCarloSMAF (White) : B+23.5
Game over. Result: B+7.5
RootParallelization (Black) vs RootParallelization (White) : B+7.5
Game over. Result: W+16.5
RootParallelization (Black) vs RootParallelization (White) : W+16.5
Game over. Result: B+0.5
RootParallelization (Black) vs RootParallelization (White) : B+0.5
Game over. Result: B+8.5
RootParallelization (Black) vs RootParallelization (White) : B+8.5
Game over. Result: W+19.5
RootParallelization (Black) vs RootParallelization (White) : W+19.5
Game over. Result: B+13.5
RootParallelization (Black) vs RootParallelization-NeuralNet (White) : B+13.5
Game over. Result: B+2.5
RootParallelization (Black) vs RootParallelization-NeuralNet (White) : B+2.5
Game over. Result: B+16.5
RootParallelization (Black) vs RootParallelization-NeuralNet (White) : B+16.5
Game over. Result: B+32.5
RootParallelization (Black) vs RootParallelization-NeuralNet (White) : B+32.5
Game over. Result: B+8.5
RootParallelization (Black) vs RootParallelization-NeuralNet (White) : B+8.5
Tournament Win Rates
====================
RootParallelization (Black) vs Random (White) : 100%
RootParallelization (Black) vs Alpha-Beta (White) : 100%
RootParallelization (Black) vs MonteCarloUCT (White) : 100%
RootParallelization (Black) vs UCT-RAVE (White) : 100%
RootParallelization (Black) vs MonteCarloSMAF (White) : 100%
RootParallelization (Black) vs RootParallelization (White) : 60%
RootParallelization (Black) vs RootParallelization-NeuralNet (White) : 100%
Tournament lasted 1597.948 seconds.

View File

@@ -0,0 +1,84 @@
C:\workspace\msproj\dist>java -Xms256m -Xmx4096m -cp GoGame.jar;antlrworks-1.4.3.jar;kgsGtp.jar;log4j-1.2.16.jar net.woodyfolsom.msproj.RoundRobin
Beginning round-robin tournament.
Initializing policies...
Game over. Result: B+2.5
Alpha-Beta (Black) vs Random (White) : B+2.5
Game over. Result: W+3.5
Alpha-Beta (Black) vs Random (White) : W+3.5
Game over. Result: W+4.5
Alpha-Beta (Black) vs Random (White) : W+4.5
Game over. Result: W+1.5
Alpha-Beta (Black) vs Random (White) : W+1.5
Game over. Result: W+2.5
Alpha-Beta (Black) vs Random (White) : W+2.5
Game over. Result: B+40.5
Alpha-Beta (Black) vs Alpha-Beta (White) : B+40.5
Game over. Result: B+40.5
Alpha-Beta (Black) vs Alpha-Beta (White) : B+40.5
Game over. Result: B+40.5
Alpha-Beta (Black) vs Alpha-Beta (White) : B+40.5
Game over. Result: B+40.5
Alpha-Beta (Black) vs Alpha-Beta (White) : B+40.5
Game over. Result: B+40.5
Alpha-Beta (Black) vs Alpha-Beta (White) : B+40.5
Game over. Result: W+17.5
Alpha-Beta (Black) vs MonteCarloUCT (White) : W+17.5
Game over. Result: W+40.5
Alpha-Beta (Black) vs MonteCarloUCT (White) : W+40.5
Game over. Result: W+18.5
Alpha-Beta (Black) vs MonteCarloUCT (White) : W+18.5
Game over. Result: W+30.5
Alpha-Beta (Black) vs MonteCarloUCT (White) : W+30.5
Game over. Result: W+33.5
Alpha-Beta (Black) vs MonteCarloUCT (White) : W+33.5
Game over. Result: W+32.5
Alpha-Beta (Black) vs UCT-RAVE (White) : W+32.5
Game over. Result: W+41.5
Alpha-Beta (Black) vs UCT-RAVE (White) : W+41.5
Game over. Result: W+36.5
Alpha-Beta (Black) vs UCT-RAVE (White) : W+36.5
Game over. Result: W+40.5
Alpha-Beta (Black) vs UCT-RAVE (White) : W+40.5
Game over. Result: W+34.5
Alpha-Beta (Black) vs UCT-RAVE (White) : W+34.5
Game over. Result: W+6.5
Alpha-Beta (Black) vs MonteCarloSMAF (White) : W+6.5
Game over. Result: W+23.5
Alpha-Beta (Black) vs MonteCarloSMAF (White) : W+23.5
Game over. Result: W+18.5
Alpha-Beta (Black) vs MonteCarloSMAF (White) : W+18.5
Game over. Result: W+33.5
Alpha-Beta (Black) vs MonteCarloSMAF (White) : W+33.5
Game over. Result: W+40.5
Alpha-Beta (Black) vs MonteCarloSMAF (White) : W+40.5
Game over. Result: W+1.5
Alpha-Beta (Black) vs RootParallelization (White) : W+1.5
Game over. Result: W+4.5
Alpha-Beta (Black) vs RootParallelization (White) : W+4.5
Game over. Result: W+0.5
Alpha-Beta (Black) vs RootParallelization (White) : W+0.5
Game over. Result: W+0.5
Alpha-Beta (Black) vs RootParallelization (White) : W+0.5
Game over. Result: W+35.5
Alpha-Beta (Black) vs RootParallelization (White) : W+35.5
Game over. Result: W+3.5
Alpha-Beta (Black) vs RootParallelization-NeuralNet (White) : W+3.5
Game over. Result: W+0.5
Alpha-Beta (Black) vs RootParallelization-NeuralNet (White) : W+0.5
Game over. Result: W+1.5
Alpha-Beta (Black) vs RootParallelization-NeuralNet (White) : W+1.5
Game over. Result: W+4.5
Alpha-Beta (Black) vs RootParallelization-NeuralNet (White) : W+4.5
Game over. Result: W+4.5
Alpha-Beta (Black) vs RootParallelization-NeuralNet (White) : W+4.5
Tournament Win Rates
====================
Alpha-Beta (Black) vs Random (White) : 20%
Alpha-Beta (Black) vs Alpha-Beta (White) : 100%
Alpha-Beta (Black) vs MonteCarloUCT (White) : 00%
Alpha-Beta (Black) vs UCT-RAVE (White) : 00%
Alpha-Beta (Black) vs MonteCarloSMAF (White) : 00%
Alpha-Beta (Black) vs RootParallelization (White) : 00%
Alpha-Beta (Black) vs RootParallelization-NeuralNet (White) : 00%

85
rrt/rrt.amaf.black.txt Normal file
View File

@@ -0,0 +1,85 @@
C:\workspace\msproj\dist>java -Xms256m -Xmx4096m -cp GoGame.jar;antlrworks-1.4.3.jar;kgsGtp.jar;log4j-1.2.16.jar net.woodyfolsom.msproj.RoundRobin
Beginning round-robin tournament.
Initializing policies...
Game over. Result: B+40.5
UCT-RAVE (Black) vs Random (White) : B+40.5
Game over. Result: B+3.5
UCT-RAVE (Black) vs Random (White) : B+3.5
Game over. Result: B+15.5
UCT-RAVE (Black) vs Random (White) : B+15.5
Game over. Result: B+54.5
UCT-RAVE (Black) vs Random (White) : B+54.5
Game over. Result: B+18.5
UCT-RAVE (Black) vs Random (White) : B+18.5
Game over. Result: B+31.5
UCT-RAVE (Black) vs Alpha-Beta (White) : B+31.5
Game over. Result: B+17.5
UCT-RAVE (Black) vs Alpha-Beta (White) : B+17.5
Game over. Result: W+9.5
UCT-RAVE (Black) vs Alpha-Beta (White) : W+9.5
Game over. Result: B+34.5
UCT-RAVE (Black) vs Alpha-Beta (White) : B+34.5
Game over. Result: W+9.5
UCT-RAVE (Black) vs Alpha-Beta (White) : W+9.5
Game over. Result: B+2.5
UCT-RAVE (Black) vs MonteCarloUCT (White) : B+2.5
Game over. Result: B+36.5
UCT-RAVE (Black) vs MonteCarloUCT (White) : B+36.5
Game over. Result: B+9.5
UCT-RAVE (Black) vs MonteCarloUCT (White) : B+9.5
Game over. Result: W+2.5
UCT-RAVE (Black) vs MonteCarloUCT (White) : W+2.5
Game over. Result: B+1.5
UCT-RAVE (Black) vs MonteCarloUCT (White) : B+1.5
Game over. Result: B+22.5
UCT-RAVE (Black) vs UCT-RAVE (White) : B+22.5
Game over. Result: B+5.5
UCT-RAVE (Black) vs UCT-RAVE (White) : B+5.5
Game over. Result: B+2.5
UCT-RAVE (Black) vs UCT-RAVE (White) : B+2.5
Game over. Result: B+11.5
UCT-RAVE (Black) vs UCT-RAVE (White) : B+11.5
Game over. Result: W+11.5
UCT-RAVE (Black) vs UCT-RAVE (White) : W+11.5
Game over. Result: B+7.5
UCT-RAVE (Black) vs MonteCarloSMAF (White) : B+7.5
Game over. Result: B+39.5
UCT-RAVE (Black) vs MonteCarloSMAF (White) : B+39.5
Game over. Result: W+15.5
UCT-RAVE (Black) vs MonteCarloSMAF (White) : W+15.5
Game over. Result: W+22.5
UCT-RAVE (Black) vs MonteCarloSMAF (White) : W+22.5
Game over. Result: W+3.5
UCT-RAVE (Black) vs MonteCarloSMAF (White) : W+3.5
Game over. Result: B+20.5
UCT-RAVE (Black) vs RootParallelization (White) : B+20.5
Game over. Result: B+29.5
UCT-RAVE (Black) vs RootParallelization (White) : B+29.5
Game over. Result: B+41.5
UCT-RAVE (Black) vs RootParallelization (White) : B+41.5
Game over. Result: B+36.5
UCT-RAVE (Black) vs RootParallelization (White) : B+36.5
Game over. Result: B+18.5
UCT-RAVE (Black) vs RootParallelization (White) : B+18.5
Game over. Result: B+54.5
UCT-RAVE (Black) vs RootParallelization-NeuralNet (White) : B+54.5
Game over. Result: B+7.5
UCT-RAVE (Black) vs RootParallelization-NeuralNet (White) : B+7.5
Game over. Result: B+19.5
UCT-RAVE (Black) vs RootParallelization-NeuralNet (White) : B+19.5
Game over. Result: B+9.5
UCT-RAVE (Black) vs RootParallelization-NeuralNet (White) : B+9.5
Game over. Result: B+3.5
UCT-RAVE (Black) vs RootParallelization-NeuralNet (White) : B+3.5
Tournament Win Rates
====================
UCT-RAVE (Black) vs Random (White) : 100%
UCT-RAVE (Black) vs Alpha-Beta (White) : 60%
UCT-RAVE (Black) vs MonteCarloUCT (White) : 80%
UCT-RAVE (Black) vs UCT-RAVE (White) : 80%
UCT-RAVE (Black) vs MonteCarloSMAF (White) : 40%
UCT-RAVE (Black) vs RootParallelization (White) : 100%
UCT-RAVE (Black) vs RootParallelization-NeuralNet (White) : 100%
Tournament lasted 1476.893 seconds.

86
rrt/rrt.random.black.txt Normal file
View File

@@ -0,0 +1,86 @@
C:\workspace\msproj\dist>java -cp GoGame.jar;antlrworks-1.4.3.jar;kgsGtp.jar;log4j-1.2.16.jar net.woodyfolsom.msproj.RoundRobin
Beginning round-robin tournament.
Initializing policies...
Game over. Result: W+6.5
Random (Black) vs Random (White) : W+6.5
Game over. Result: B+1.5
Random (Black) vs Random (White) : B+1.5
Game over. Result: B+7.5
Random (Black) vs Random (White) : B+7.5
Game over. Result: W+0.5
Random (Black) vs Random (White) : W+0.5
Game over. Result: B+1.5
Random (Black) vs Random (White) : B+1.5
Game over. Result: B+28.5
Random (Black) vs Alpha-Beta (White) : B+28.5
Game over. Result: B+1.5
Random (Black) vs Alpha-Beta (White) : B+1.5
Game over. Result: B+29.5
Random (Black) vs Alpha-Beta (White) : B+29.5
Game over. Result: B+47.5
Random (Black) vs Alpha-Beta (White) : B+47.5
Game over. Result: B+22.5
Random (Black) vs Alpha-Beta (White) : B+22.5
Game over. Result: W+22.5
Random (Black) vs MonteCarloUCT (White) : W+22.5
Game over. Result: W+6.5
Random (Black) vs MonteCarloUCT (White) : W+6.5
Game over. Result: W+5.5
Random (Black) vs MonteCarloUCT (White) : W+5.5
Game over. Result: W+12.5
Random (Black) vs MonteCarloUCT (White) : W+12.5
Game over. Result: W+35.5
Random (Black) vs MonteCarloUCT (White) : W+35.5
Game over. Result: W+14.5
Random (Black) vs UCT-RAVE (White) : W+14.5
Game over. Result: W+18.5
Random (Black) vs UCT-RAVE (White) : W+18.5
Game over. Result: W+3.5
Random (Black) vs UCT-RAVE (White) : W+3.5
Game over. Result: W+5.5
Random (Black) vs UCT-RAVE (White) : W+5.5
Game over. Result: W+32.5
Random (Black) vs UCT-RAVE (White) : W+32.5
Game over. Result: W+19.5
Random (Black) vs MonteCarloSMAF (White) : W+19.5
Game over. Result: W+26.5
Random (Black) vs MonteCarloSMAF (White) : W+26.5
Game over. Result: W+19.5
Random (Black) vs MonteCarloSMAF (White) : W+19.5
Game over. Result: W+8.5
Random (Black) vs MonteCarloSMAF (White) : W+8.5
Game over. Result: W+13.5
Random (Black) vs MonteCarloSMAF (White) : W+13.5
Game over. Result: W+9.5
Random (Black) vs RootParallelization (White) : W+9.5
Game over. Result: W+4.5
Random (Black) vs RootParallelization (White) : W+4.5
Game over. Result: W+8.5
Random (Black) vs RootParallelization (White) : W+8.5
Game over. Result: W+39.5
Random (Black) vs RootParallelization (White) : W+39.5
Game over. Result: W+0.5
Random (Black) vs RootParallelization (White) : W+0.5
Game over. Result: W+10.5
Random (Black) vs RootParallelization-NeuralNet (White) : W+10.5
Game over. Result: W+11.5
Random (Black) vs RootParallelization-NeuralNet (White) : W+11.5
Game over. Result: W+1.5
Random (Black) vs RootParallelization-NeuralNet (White) : W+1.5
Game over. Result: W+3.5
Random (Black) vs RootParallelization-NeuralNet (White) : W+3.5
Game over. Result: W+10.5
Random (Black) vs RootParallelization-NeuralNet (White) : W+10.5
Game over. Result: W+40.5
Tournament Win Rates
====================
Random (Black) vs Random (White) : 40%
Random (Black) vs Alpha-Beta (White) : 100%
Random (Black) vs MonteCarloUCT (White) : 00%
Random (Black) vs UCT-RAVE (White) : 00%
Random (Black) vs MonteCarloSMAF (White) : 00%
Random (Black) vs RootParallelization (White) : 00%
Random (Black) vs RootParallelization-NeuralNet (White) : 00%

83
rrt/rrt.rave.black.txt Normal file
View File

@@ -0,0 +1,83 @@
Beginning round-robin tournament.
Initializing policies...
Game over. Result: B+8.5
UCT-RAVE (Black) vs Random (White) : B+8.5
Game over. Result: B+31.5
UCT-RAVE (Black) vs Random (White) : B+31.5
Game over. Result: B+16.5
UCT-RAVE (Black) vs Random (White) : B+16.5
Game over. Result: B+9.5
UCT-RAVE (Black) vs Random (White) : B+9.5
Game over. Result: B+16.5
UCT-RAVE (Black) vs Random (White) : B+16.5
Game over. Result: B+48.5
UCT-RAVE (Black) vs Alpha-Beta (White) : B+48.5
Game over. Result: W+5.5
UCT-RAVE (Black) vs Alpha-Beta (White) : W+5.5
Game over. Result: B+13.5
UCT-RAVE (Black) vs Alpha-Beta (White) : B+13.5
Game over. Result: B+34.5
UCT-RAVE (Black) vs Alpha-Beta (White) : B+34.5
Game over. Result: B+1.5
UCT-RAVE (Black) vs Alpha-Beta (White) : B+1.5
Game over. Result: B+2.5
UCT-RAVE (Black) vs MonteCarloUCT (White) : B+2.5
Game over. Result: B+7.5
UCT-RAVE (Black) vs MonteCarloUCT (White) : B+7.5
Game over. Result: W+4.5
UCT-RAVE (Black) vs MonteCarloUCT (White) : W+4.5
Game over. Result: B+3.5
UCT-RAVE (Black) vs MonteCarloUCT (White) : B+3.5
Game over. Result: B+6.5
UCT-RAVE (Black) vs MonteCarloUCT (White) : B+6.5
Game over. Result: B+3.5
UCT-RAVE (Black) vs UCT-RAVE (White) : B+3.5
Game over. Result: B+2.5
UCT-RAVE (Black) vs UCT-RAVE (White) : B+2.5
Game over. Result: B+9.5
UCT-RAVE (Black) vs UCT-RAVE (White) : B+9.5
Game over. Result: B+0.5
UCT-RAVE (Black) vs UCT-RAVE (White) : B+0.5
Game over. Result: W+13.5
UCT-RAVE (Black) vs UCT-RAVE (White) : W+13.5
Game over. Result: W+0.5
UCT-RAVE (Black) vs MonteCarloSMAF (White) : W+0.5
Game over. Result: B+1.5
UCT-RAVE (Black) vs MonteCarloSMAF (White) : B+1.5
Game over. Result: W+0.5
UCT-RAVE (Black) vs MonteCarloSMAF (White) : W+0.5
Game over. Result: B+9.5
UCT-RAVE (Black) vs MonteCarloSMAF (White) : B+9.5
Game over. Result: W+20.5
UCT-RAVE (Black) vs MonteCarloSMAF (White) : W+20.5
Game over. Result: B+13.5
UCT-RAVE (Black) vs RootParallelization (White) : B+13.5
Game over. Result: W+16.5
UCT-RAVE (Black) vs RootParallelization (White) : W+16.5
Game over. Result: B+28.5
UCT-RAVE (Black) vs RootParallelization (White) : B+28.5
Game over. Result: B+25.5
UCT-RAVE (Black) vs RootParallelization (White) : B+25.5
Game over. Result: B+25.5
UCT-RAVE (Black) vs RootParallelization (White) : B+25.5
Game over. Result: B+48.5
UCT-RAVE (Black) vs RootParallelization-NeuralNet (White) : B+48.5
Game over. Result: B+6.5
UCT-RAVE (Black) vs RootParallelization-NeuralNet (White) : B+6.5
Game over. Result: B+9.5
UCT-RAVE (Black) vs RootParallelization-NeuralNet (White) : B+9.5
Game over. Result: B+55.5
UCT-RAVE (Black) vs RootParallelization-NeuralNet (White) : B+55.5
Game over. Result: B+42.5
UCT-RAVE (Black) vs RootParallelization-NeuralNet (White) : B+42.5
Tournament Win Rates
====================
UCT-RAVE (Black) vs Random (White) : 100%
UCT-RAVE (Black) vs Alpha-Beta (White) : 80%
UCT-RAVE (Black) vs MonteCarloUCT (White) : 80%
UCT-RAVE (Black) vs UCT-RAVE (White) : 80%
UCT-RAVE (Black) vs MonteCarloSMAF (White) : 40%
UCT-RAVE (Black) vs RootParallelization (White) : 80%
UCT-RAVE (Black) vs RootParallelization-NeuralNet (White) : 100%
Tournament lasted 1458.494 seconds.

View File

@@ -0,0 +1,85 @@
C:\workspace\msproj\dist>java -Xms256m -Xmx4096m -cp GoGame.jar;antlrworks-1.4.3.jar;kgsGtp.jar;log4j-1.2.16.jar net.woodyfolsom.msproj.RoundRobin
Beginning round-robin tournament.
Initializing policies...
Game over. Result: B+6.5
RootParallelization-NeuralNet (Black) vs Random (White) : B+6.5
Game over. Result: B+0.5
RootParallelization-NeuralNet (Black) vs Random (White) : B+0.5
Game over. Result: B+5.5
RootParallelization-NeuralNet (Black) vs Random (White) : B+5.5
Game over. Result: B+19.5
RootParallelization-NeuralNet (Black) vs Random (White) : B+19.5
Game over. Result: B+2.5
RootParallelization-NeuralNet (Black) vs Random (White) : B+2.5
Game over. Result: B+21.5
RootParallelization-NeuralNet (Black) vs Alpha-Beta (White) : B+21.5
Game over. Result: W+12.5
RootParallelization-NeuralNet (Black) vs Alpha-Beta (White) : W+12.5
Game over. Result: B+23.5
RootParallelization-NeuralNet (Black) vs Alpha-Beta (White) : B+23.5
Game over. Result: B+23.5
RootParallelization-NeuralNet (Black) vs Alpha-Beta (White) : B+23.5
Game over. Result: W+9.5
RootParallelization-NeuralNet (Black) vs Alpha-Beta (White) : W+9.5
Game over. Result: B+29.5
RootParallelization-NeuralNet (Black) vs MonteCarloUCT (White) : B+29.5
Game over. Result: B+9.5
RootParallelization-NeuralNet (Black) vs MonteCarloUCT (White) : B+9.5
Game over. Result: W+50.5
RootParallelization-NeuralNet (Black) vs MonteCarloUCT (White) : W+50.5
Game over. Result: B+9.5
RootParallelization-NeuralNet (Black) vs MonteCarloUCT (White) : B+9.5
Game over. Result: B+7.5
RootParallelization-NeuralNet (Black) vs MonteCarloUCT (White) : B+7.5
Game over. Result: W+12.5
RootParallelization-NeuralNet (Black) vs UCT-RAVE (White) : W+12.5
Game over. Result: W+9.5
RootParallelization-NeuralNet (Black) vs UCT-RAVE (White) : W+9.5
Game over. Result: W+29.5
RootParallelization-NeuralNet (Black) vs UCT-RAVE (White) : W+29.5
Game over. Result: W+10.5
RootParallelization-NeuralNet (Black) vs UCT-RAVE (White) : W+10.5
Game over. Result: W+27.5
RootParallelization-NeuralNet (Black) vs UCT-RAVE (White) : W+27.5
Game over. Result: W+2.5
RootParallelization-NeuralNet (Black) vs MonteCarloSMAF (White) : W+2.5
Game over. Result: W+22.5
RootParallelization-NeuralNet (Black) vs MonteCarloSMAF (White) : W+22.5
Game over. Result: W+10.5
RootParallelization-NeuralNet (Black) vs MonteCarloSMAF (White) : W+10.5
Game over. Result: W+41.5
RootParallelization-NeuralNet (Black) vs MonteCarloSMAF (White) : W+41.5
Game over. Result: W+18.5
RootParallelization-NeuralNet (Black) vs MonteCarloSMAF (White) : W+18.5
Game over. Result: B+3.5
RootParallelization-NeuralNet (Black) vs RootParallelization (White) : B+3.5
Game over. Result: W+10.5
RootParallelization-NeuralNet (Black) vs RootParallelization (White) : W+10.5
Game over. Result: W+14.5
RootParallelization-NeuralNet (Black) vs RootParallelization (White) : W+14.5
Game over. Result: W+5.5
RootParallelization-NeuralNet (Black) vs RootParallelization (White) : W+5.5
Game over. Result: W+6.5
RootParallelization-NeuralNet (Black) vs RootParallelization (White) : W+6.5
Game over. Result: W+8.5
RootParallelization-NeuralNet (Black) vs RootParallelization-NeuralNet (White) : W+8.5
Game over. Result: W+11.5
RootParallelization-NeuralNet (Black) vs RootParallelization-NeuralNet (White) : W+11.5
Game over. Result: W+6.5
RootParallelization-NeuralNet (Black) vs RootParallelization-NeuralNet (White) : W+6.5
Game over. Result: B+2.5
RootParallelization-NeuralNet (Black) vs RootParallelization-NeuralNet (White) : B+2.5
Game over. Result: B+21.5
RootParallelization-NeuralNet (Black) vs RootParallelization-NeuralNet (White) : B+21.5
Tournament Win Rates
====================
RootParallelization-NeuralNet (Black) vs Random (White) : 100%
RootParallelization-NeuralNet (Black) vs Alpha-Beta (White) : 60%
RootParallelization-NeuralNet (Black) vs MonteCarloUCT (White) : 80%
RootParallelization-NeuralNet (Black) vs UCT-RAVE (White) : 00%
RootParallelization-NeuralNet (Black) vs MonteCarloSMAF (White) : 00%
RootParallelization-NeuralNet (Black) vs RootParallelization (White) : 20%
RootParallelization-NeuralNet (Black) vs RootParallelization-NeuralNet (White) : 40%
Tournament lasted 1400.277 seconds.

85
rrt/rrt.rootpar.black.txt Normal file
View File

@@ -0,0 +1,85 @@
C:\workspace\msproj\dist>java -Xms256m -Xmx4096m -cp GoGame.jar;antlrworks-1.4.3.jar;kgsGtp.jar;log4j-1.2.16.jar net.woodyfolsom.msproj.RoundRobin
Beginning round-robin tournament.
Initializing policies...
Game over. Result: B+4.5
RootParallelization (Black) vs Random (White) : B+4.5
Game over. Result: B+4.5
RootParallelization (Black) vs Random (White) : B+4.5
Game over. Result: B+1.5
RootParallelization (Black) vs Random (White) : B+1.5
Game over. Result: B+1.5
RootParallelization (Black) vs Random (White) : B+1.5
Game over. Result: B+0.5
RootParallelization (Black) vs Random (White) : B+0.5
Game over. Result: B+20.5
RootParallelization (Black) vs Alpha-Beta (White) : B+20.5
Game over. Result: B+23.5
RootParallelization (Black) vs Alpha-Beta (White) : B+23.5
Game over. Result: W+9.5
RootParallelization (Black) vs Alpha-Beta (White) : W+9.5
Game over. Result: W+7.5
RootParallelization (Black) vs Alpha-Beta (White) : W+7.5
Game over. Result: B+25.5
RootParallelization (Black) vs Alpha-Beta (White) : B+25.5
Game over. Result: B+0.5
RootParallelization (Black) vs MonteCarloUCT (White) : B+0.5
Game over. Result: B+11.5
RootParallelization (Black) vs MonteCarloUCT (White) : B+11.5
Game over. Result: W+0.5
RootParallelization (Black) vs MonteCarloUCT (White) : W+0.5
Game over. Result: B+1.5
RootParallelization (Black) vs MonteCarloUCT (White) : B+1.5
Game over. Result: B+0.5
RootParallelization (Black) vs MonteCarloUCT (White) : B+0.5
Game over. Result: W+22.5
RootParallelization (Black) vs UCT-RAVE (White) : W+22.5
Game over. Result: W+63.5
RootParallelization (Black) vs UCT-RAVE (White) : W+63.5
Game over. Result: W+29.5
RootParallelization (Black) vs UCT-RAVE (White) : W+29.5
Game over. Result: W+58.5
RootParallelization (Black) vs UCT-RAVE (White) : W+58.5
Game over. Result: W+30.5
RootParallelization (Black) vs UCT-RAVE (White) : W+30.5
Game over. Result: W+15.5
RootParallelization (Black) vs MonteCarloSMAF (White) : W+15.5
Game over. Result: W+62.5
RootParallelization (Black) vs MonteCarloSMAF (White) : W+62.5
Game over. Result: W+57.5
RootParallelization (Black) vs MonteCarloSMAF (White) : W+57.5
Game over. Result: W+57.5
RootParallelization (Black) vs MonteCarloSMAF (White) : W+57.5
Game over. Result: W+12.5
RootParallelization (Black) vs MonteCarloSMAF (White) : W+12.5
Game over. Result: B+2.5
RootParallelization (Black) vs RootParallelization (White) : B+2.5
Game over. Result: W+6.5
RootParallelization (Black) vs RootParallelization (White) : W+6.5
Game over. Result: B+2.5
RootParallelization (Black) vs RootParallelization (White) : B+2.5
Game over. Result: W+5.5
RootParallelization (Black) vs RootParallelization (White) : W+5.5
Game over. Result: B+2.5
RootParallelization (Black) vs RootParallelization (White) : B+2.5
Game over. Result: W+8.5
RootParallelization (Black) vs RootParallelization-NeuralNet (White) : W+8.5
Game over. Result: W+6.5
RootParallelization (Black) vs RootParallelization-NeuralNet (White) : W+6.5
Game over. Result: W+6.5
RootParallelization (Black) vs RootParallelization-NeuralNet (White) : W+6.5
Game over. Result: B+3.5
RootParallelization (Black) vs RootParallelization-NeuralNet (White) : B+3.5
Game over. Result: W+13.5
RootParallelization (Black) vs RootParallelization-NeuralNet (White) : W+13.5
Tournament Win Rates
====================
RootParallelization (Black) vs Random (White) : 100%
RootParallelization (Black) vs Alpha-Beta (White) : 60%
RootParallelization (Black) vs MonteCarloUCT (White) : 80%
RootParallelization (Black) vs UCT-RAVE (White) : 00%
RootParallelization (Black) vs MonteCarloSMAF (White) : 00%
RootParallelization (Black) vs RootParallelization (White) : 60%
RootParallelization (Black) vs RootParallelization-NeuralNet (White) : 20%
Tournament lasted 1367.523 seconds.

85
rrt/rrt.smaf.black.txt Normal file
View File

@@ -0,0 +1,85 @@
C:\workspace\msproj\dist>java -Xms256m -Xmx4096m -cp GoGame.jar;antlrworks-1.4.3.jar;kgsGtp.jar;log4j-1.2.16.jar net.woodyfolsom.msproj.RoundRobin
Beginning round-robin tournament.
Initializing policies...
Game over. Result: B+8.5
UCT-RAVE (Black) vs Random (White) : B+8.5
Game over. Result: B+31.5
UCT-RAVE (Black) vs Random (White) : B+31.5
Game over. Result: B+16.5
UCT-RAVE (Black) vs Random (White) : B+16.5
Game over. Result: B+9.5
UCT-RAVE (Black) vs Random (White) : B+9.5
Game over. Result: B+16.5
UCT-RAVE (Black) vs Random (White) : B+16.5
Game over. Result: B+48.5
UCT-RAVE (Black) vs Alpha-Beta (White) : B+48.5
Game over. Result: W+5.5
UCT-RAVE (Black) vs Alpha-Beta (White) : W+5.5
Game over. Result: B+13.5
UCT-RAVE (Black) vs Alpha-Beta (White) : B+13.5
Game over. Result: B+34.5
UCT-RAVE (Black) vs Alpha-Beta (White) : B+34.5
Game over. Result: B+1.5
UCT-RAVE (Black) vs Alpha-Beta (White) : B+1.5
Game over. Result: B+2.5
UCT-RAVE (Black) vs MonteCarloUCT (White) : B+2.5
Game over. Result: B+7.5
UCT-RAVE (Black) vs MonteCarloUCT (White) : B+7.5
Game over. Result: W+4.5
UCT-RAVE (Black) vs MonteCarloUCT (White) : W+4.5
Game over. Result: B+3.5
UCT-RAVE (Black) vs MonteCarloUCT (White) : B+3.5
Game over. Result: B+6.5
UCT-RAVE (Black) vs MonteCarloUCT (White) : B+6.5
Game over. Result: B+3.5
UCT-RAVE (Black) vs UCT-RAVE (White) : B+3.5
Game over. Result: B+2.5
UCT-RAVE (Black) vs UCT-RAVE (White) : B+2.5
Game over. Result: B+9.5
UCT-RAVE (Black) vs UCT-RAVE (White) : B+9.5
Game over. Result: B+0.5
UCT-RAVE (Black) vs UCT-RAVE (White) : B+0.5
Game over. Result: W+13.5
UCT-RAVE (Black) vs UCT-RAVE (White) : W+13.5
Game over. Result: W+0.5
UCT-RAVE (Black) vs MonteCarloSMAF (White) : W+0.5
Game over. Result: B+1.5
UCT-RAVE (Black) vs MonteCarloSMAF (White) : B+1.5
Game over. Result: W+0.5
UCT-RAVE (Black) vs MonteCarloSMAF (White) : W+0.5
Game over. Result: B+9.5
UCT-RAVE (Black) vs MonteCarloSMAF (White) : B+9.5
Game over. Result: W+20.5
UCT-RAVE (Black) vs MonteCarloSMAF (White) : W+20.5
Game over. Result: B+13.5
UCT-RAVE (Black) vs RootParallelization (White) : B+13.5
Game over. Result: W+16.5
UCT-RAVE (Black) vs RootParallelization (White) : W+16.5
Game over. Result: B+28.5
UCT-RAVE (Black) vs RootParallelization (White) : B+28.5
Game over. Result: B+25.5
UCT-RAVE (Black) vs RootParallelization (White) : B+25.5
Game over. Result: B+25.5
UCT-RAVE (Black) vs RootParallelization (White) : B+25.5
Game over. Result: B+48.5
UCT-RAVE (Black) vs RootParallelization-NeuralNet (White) : B+48.5
Game over. Result: B+6.5
UCT-RAVE (Black) vs RootParallelization-NeuralNet (White) : B+6.5
Game over. Result: B+9.5
UCT-RAVE (Black) vs RootParallelization-NeuralNet (White) : B+9.5
Game over. Result: B+55.5
UCT-RAVE (Black) vs RootParallelization-NeuralNet (White) : B+55.5
Game over. Result: B+42.5
UCT-RAVE (Black) vs RootParallelization-NeuralNet (White) : B+42.5
Tournament Win Rates
====================
UCT-RAVE (Black) vs Random (White) : 100%
UCT-RAVE (Black) vs Alpha-Beta (White) : 80%
UCT-RAVE (Black) vs MonteCarloUCT (White) : 80%
UCT-RAVE (Black) vs UCT-RAVE (White) : 80%
UCT-RAVE (Black) vs MonteCarloSMAF (White) : 40%
UCT-RAVE (Black) vs RootParallelization (White) : 80%
UCT-RAVE (Black) vs RootParallelization-NeuralNet (White) : 100%
Tournament lasted 1458.494 seconds.

85
rrt/rrt.uct.black Normal file
View File

@@ -0,0 +1,85 @@
C:\workspace\msproj\dist>java -Xms256m -Xmx4096m -cp GoGame.jar;antlrworks-1.4.3.jar;kgsGtp.jar;log4j-1.2.16.jar net.woodyfolsom.msproj.RoundRobin
Beginning round-robin tournament.
Initializing policies...
Game over. Result: B+0.5
MonteCarloUCT (Black) vs Random (White) : B+0.5
Game over. Result: B+9.5
MonteCarloUCT (Black) vs Random (White) : B+9.5
Game over. Result: B+24.5
MonteCarloUCT (Black) vs Random (White) : B+24.5
Game over. Result: B+10.5
MonteCarloUCT (Black) vs Random (White) : B+10.5
Game over. Result: B+4.5
MonteCarloUCT (Black) vs Random (White) : B+4.5
Game over. Result: B+15.5
MonteCarloUCT (Black) vs Alpha-Beta (White) : B+15.5
Game over. Result: B+22.5
MonteCarloUCT (Black) vs Alpha-Beta (White) : B+22.5
Game over. Result: B+32.5
MonteCarloUCT (Black) vs Alpha-Beta (White) : B+32.5
Game over. Result: W+12.5
MonteCarloUCT (Black) vs Alpha-Beta (White) : W+12.5
Game over. Result: B+23.5
MonteCarloUCT (Black) vs Alpha-Beta (White) : B+23.5
Game over. Result: B+0.5
MonteCarloUCT (Black) vs MonteCarloUCT (White) : B+0.5
Game over. Result: W+13.5
MonteCarloUCT (Black) vs MonteCarloUCT (White) : W+13.5
Game over. Result: W+11.5
MonteCarloUCT (Black) vs MonteCarloUCT (White) : W+11.5
Game over. Result: W+8.5
MonteCarloUCT (Black) vs MonteCarloUCT (White) : W+8.5
Game over. Result: W+9.5
MonteCarloUCT (Black) vs MonteCarloUCT (White) : W+9.5
Game over. Result: W+9.5
MonteCarloUCT (Black) vs UCT-RAVE (White) : W+9.5
Game over. Result: W+16.5
MonteCarloUCT (Black) vs UCT-RAVE (White) : W+16.5
Game over. Result: W+8.5
MonteCarloUCT (Black) vs UCT-RAVE (White) : W+8.5
Game over. Result: W+11.5
MonteCarloUCT (Black) vs UCT-RAVE (White) : W+11.5
Game over. Result: W+5.5
MonteCarloUCT (Black) vs UCT-RAVE (White) : W+5.5
Game over. Result: W+8.5
MonteCarloUCT (Black) vs MonteCarloSMAF (White) : W+8.5
Game over. Result: W+9.5
MonteCarloUCT (Black) vs MonteCarloSMAF (White) : W+9.5
Game over. Result: W+15.5
MonteCarloUCT (Black) vs MonteCarloSMAF (White) : W+15.5
Game over. Result: W+14.5
MonteCarloUCT (Black) vs MonteCarloSMAF (White) : W+14.5
Game over. Result: W+13.5
MonteCarloUCT (Black) vs MonteCarloSMAF (White) : W+13.5
Game over. Result: W+15.5
MonteCarloUCT (Black) vs RootParallelization (White) : W+15.5
Game over. Result: W+14.5
MonteCarloUCT (Black) vs RootParallelization (White) : W+14.5
Game over. Result: W+6.5
MonteCarloUCT (Black) vs RootParallelization (White) : W+6.5
Game over. Result: W+6.5
MonteCarloUCT (Black) vs RootParallelization (White) : W+6.5
Game over. Result: W+11.5
MonteCarloUCT (Black) vs RootParallelization (White) : W+11.5
Game over. Result: W+26.5
MonteCarloUCT (Black) vs RootParallelization-NeuralNet (White) : W+26.5
Game over. Result: W+11.5
MonteCarloUCT (Black) vs RootParallelization-NeuralNet (White) : W+11.5
Game over. Result: W+47.5
MonteCarloUCT (Black) vs RootParallelization-NeuralNet (White) : W+47.5
Game over. Result: W+13.5
MonteCarloUCT (Black) vs RootParallelization-NeuralNet (White) : W+13.5
Game over. Result: B+33.5
MonteCarloUCT (Black) vs RootParallelization-NeuralNet (White) : B+33.5
Tournament Win Rates
====================
MonteCarloUCT (Black) vs Random (White) : 100%
MonteCarloUCT (Black) vs Alpha-Beta (White) : 80%
MonteCarloUCT (Black) vs MonteCarloUCT (White) : 20%
MonteCarloUCT (Black) vs UCT-RAVE (White) : 00%
MonteCarloUCT (Black) vs MonteCarloSMAF (White) : 00%
MonteCarloUCT (Black) vs RootParallelization (White) : 00%
MonteCarloUCT (Black) vs RootParallelization-NeuralNet (White) : 20%
Tournament lasted 1355.668 seconds.

View File

@@ -59,6 +59,14 @@ public class GameRecord {
return gameStates.get(0).getGameConfig(); return gameStates.get(0).getGameConfig();
} }
/**
* Gets the game state for the most recent ply.
* @return
*/
public GameState getGameState() {
return gameStates.get(getNumTurns());
}
public GameState getGameState(Integer turn) { public GameState getGameState(Integer turn) {
return gameStates.get(turn); return gameStates.get(turn);
} }

View File

@@ -119,6 +119,14 @@ public class GameState {
return whitePrisoners; return whitePrisoners;
} }
public boolean isPrevPlyPass() {
if (moveHistory.size() == 0) {
return false;
} else {
return moveHistory.get(moveHistory.size()-1).isPass();
}
}
public boolean isSelfFill(Action action, Player player) { public boolean isSelfFill(Action action, Player player) {
return gameBoard.isSelfFill(action, player); return gameBoard.isSelfFill(action, player);
} }

View File

@@ -16,6 +16,7 @@ import net.woodyfolsom.msproj.policy.Minimax;
import net.woodyfolsom.msproj.policy.MonteCarloUCT; import net.woodyfolsom.msproj.policy.MonteCarloUCT;
import net.woodyfolsom.msproj.policy.Policy; import net.woodyfolsom.msproj.policy.Policy;
import net.woodyfolsom.msproj.policy.RandomMovePolicy; import net.woodyfolsom.msproj.policy.RandomMovePolicy;
import net.woodyfolsom.msproj.policy.RootParAMAF;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator; import org.apache.log4j.xml.DOMConfigurator;
@@ -80,10 +81,11 @@ public class GoGame implements Runnable {
public static void main(String[] args) throws IOException { public static void main(String[] args) throws IOException {
configureLogging(); configureLogging();
if (args.length == 0) { if (args.length == 0) {
Policy defaultMoveGenerator = new MonteCarloUCT(new RandomMovePolicy(), 5000L); Policy policy = new RootParAMAF(4, 10000L);
LOGGER.info("No MoveGenerator specified. Using default: " + defaultMoveGenerator.toString()); policy.setLogging(true);
LOGGER.info("No MoveGenerator specified. Using default: " + policy.getName());
GoGame goGame = new GoGame(defaultMoveGenerator, PROPS_FILE); GoGame goGame = new GoGame(policy, PROPS_FILE);
new Thread(goGame).start(); new Thread(goGame).start();
System.out.println("Creating GtpClient"); System.out.println("Creating GtpClient");
@@ -111,7 +113,9 @@ public class GoGame implements Runnable {
} else if ("alphabeta".equals(policyName)) { } else if ("alphabeta".equals(policyName)) {
return new AlphaBeta(); return new AlphaBeta();
} else if ("montecarlo".equals(policyName)) { } else if ("montecarlo".equals(policyName)) {
return new MonteCarloUCT(new RandomMovePolicy(), 5000L); return new MonteCarloUCT(new RandomMovePolicy(), 10000L);
} else if ("root_par_amaf".equals(policyName)) {
return new RootParAMAF(4, 10000L);
} else { } else {
LOGGER.info("Unable to create Policy for unsupported name: " + policyName); LOGGER.info("Unable to create Policy for unsupported name: " + policyName);
System.exit(INVALID_MOVE_GENERATOR); System.exit(INVALID_MOVE_GENERATOR);

View File

@@ -0,0 +1,115 @@
package net.woodyfolsom.msproj;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import net.woodyfolsom.msproj.policy.AlphaBeta;
import net.woodyfolsom.msproj.policy.MonteCarloAMAF;
import net.woodyfolsom.msproj.policy.MonteCarloSMAF;
import net.woodyfolsom.msproj.policy.MonteCarloUCT;
import net.woodyfolsom.msproj.policy.NeuralNetPolicy;
import net.woodyfolsom.msproj.policy.Policy;
import net.woodyfolsom.msproj.policy.RandomMovePolicy;
import net.woodyfolsom.msproj.policy.RootParAMAF;
import net.woodyfolsom.msproj.policy.RootParallelization;
public class RoundRobin {
public static final int EXIT_USER_QUIT = 1;
public static final int EXIT_NOMINAL = 0;
public static final int EXIT_IO_EXCEPTION = -1;
public static void main(String[] args) throws IOException {
long startTime = System.currentTimeMillis();
System.out.println("Beginning round-robin tournament.");
System.out.println("Initializing policies...");
List<Policy> policies = new ArrayList<Policy>();
policies.add(new RandomMovePolicy());
//policies.add(new Minimax(1));
policies.add(new AlphaBeta(1));
policies.add(new MonteCarloUCT(new RandomMovePolicy(), 500L));
policies.add(new MonteCarloAMAF(new RandomMovePolicy(), 500L));
policies.add(new MonteCarloSMAF(new RandomMovePolicy(), 500L, 4));
policies.add(new RootParAMAF(4, 500L));
policies.add(new RootParallelization(4, new NeuralNetPolicy(), 500L));
RoundRobin rr = new RoundRobin();
List<List<Double>> tourneyWinRates = new ArrayList<List<Double>>();
int gamesPerMatch = 5;
for (int i = 0; i < policies.size(); i++) {
List<Double> roundWinRates = new ArrayList<Double>();
if (i != 5) {
tourneyWinRates.add(roundWinRates);
continue;
}
for (int j = 0; j < policies.size(); j++) {
Policy policy1 = policies.get(i);
policy1.setLogging(false);
Policy policy2 = policies.get(j);
policy2.setLogging(false);
List<GameResult> gameResults = rr.playGame(policy1, policy2, 9, 6.5, gamesPerMatch, false, false, false);
double wins = 0.0;
double games = 0.0;
for(GameResult gr : gameResults) {
wins += gr.isWinner(Player.BLACK) ? 1.0 : 0.0;
games += 1.0;
}
roundWinRates.add(100.0 * wins / games);
}
tourneyWinRates.add(roundWinRates);
}
System.out.println("");
System.out.println("Tournament Win Rates");
System.out.println("====================");
DecimalFormat df = new DecimalFormat("00.#");
for (int i = 0; i < policies.size(); i++) {
for (int j = 0; j < policies.size(); j++) {
if (i == 5)
System.out.println(policies.get(i).getName() + " (Black) vs " + policies.get(j).getName() + " (White) : " + df.format(tourneyWinRates.get(i).get(j)) + "%");
}
}
long endTime = System.currentTimeMillis();
System.out.println("Tournament lasted " + (endTime-startTime)/1000.0 + " seconds.");
}
public List<GameResult> playGame(Policy player1Policy, Policy player2Policy, int size,
double komi, int rounds, boolean showSpectatorBoard,
boolean blackMoveLogged, boolean whiteMoveLogged) {
GameConfig gameConfig = new GameConfig(size);
gameConfig.setKomi(komi);
Referee referee = new Referee();
referee.setPolicy(Player.BLACK, player1Policy);
referee.setPolicy(Player.WHITE, player2Policy);
List<GameResult> roundResults = new ArrayList<GameResult>();
boolean logGameRecords = false;
int gameNo = 1;
for (int round = 0; round < rounds; round++) {
gameNo++;
GameResult gameResult = referee.play(gameConfig, gameNo,
showSpectatorBoard, logGameRecords);
roundResults.add(gameResult);
System.out.println(player1Policy.getName() + " (Black) vs "
+ player2Policy.getName() + " (White) : " + gameResult);
roundResults.add(gameResult);
}
return roundResults;
}
}

View File

@@ -17,6 +17,7 @@ import net.woodyfolsom.msproj.policy.MonteCarloSMAF;
import net.woodyfolsom.msproj.policy.MonteCarloUCT; import net.woodyfolsom.msproj.policy.MonteCarloUCT;
import net.woodyfolsom.msproj.policy.Policy; import net.woodyfolsom.msproj.policy.Policy;
import net.woodyfolsom.msproj.policy.RandomMovePolicy; import net.woodyfolsom.msproj.policy.RandomMovePolicy;
import net.woodyfolsom.msproj.policy.RootParAMAF;
import net.woodyfolsom.msproj.policy.RootParallelization; import net.woodyfolsom.msproj.policy.RootParallelization;
public class StandAloneGame { public class StandAloneGame {
@@ -27,13 +28,13 @@ public class StandAloneGame {
private int gameNo = 0; private int gameNo = 0;
enum PLAYER_TYPE { enum PLAYER_TYPE {
HUMAN, HUMAN_GUI, ROOT_PAR, UCT, RANDOM, RAVE, SMAF HUMAN, HUMAN_GUI, ROOT_PAR, UCT, RANDOM, RAVE, SMAF, ROOT_PAR_AMAF
}; };
public static void main(String[] args) throws IOException { public static void main(String[] args) throws IOException {
try { try {
GameSettings gameSettings = GameSettings GameSettings gameSettings = GameSettings
.createGameSetings("data/gogame.cfg"); .createGameSetings("gogame.cfg");
System.out.println("Game Settings: " + gameSettings); System.out.println("Game Settings: " + gameSettings);
System.out.println("Successfully parsed game settings."); System.out.println("Successfully parsed game settings.");
new StandAloneGame().playGame( new StandAloneGame().playGame(
@@ -68,6 +69,8 @@ public class StandAloneGame {
return PLAYER_TYPE.RAVE; return PLAYER_TYPE.RAVE;
} else if ("SMAF".equalsIgnoreCase(playerTypeStr)) { } else if ("SMAF".equalsIgnoreCase(playerTypeStr)) {
return PLAYER_TYPE.SMAF; return PLAYER_TYPE.SMAF;
} else if ("ROOT_PAR_AMAF".equalsIgnoreCase(playerTypeStr)) {
return PLAYER_TYPE.ROOT_PAR_AMAF;
} else { } else {
throw new RuntimeException("Unknown player type: " + playerTypeStr); throw new RuntimeException("Unknown player type: " + playerTypeStr);
} }
@@ -186,11 +189,14 @@ public class StandAloneGame {
case ROOT_PAR: case ROOT_PAR:
policy = new RootParallelization(4, turnLength); policy = new RootParallelization(4, turnLength);
break; break;
case ROOT_PAR_AMAF:
policy = new RootParAMAF(4, turnLength);
break;
case UCT: case UCT:
policy = new MonteCarloUCT(new RandomMovePolicy(), turnLength); policy = new MonteCarloUCT(new RandomMovePolicy(), turnLength);
break; break;
case SMAF: case SMAF:
policy = new MonteCarloSMAF(new RandomMovePolicy(), turnLength, 0); policy = new MonteCarloSMAF(new RandomMovePolicy(), turnLength, 4);
break; break;
case RANDOM: case RANDOM:
policy = new RandomMovePolicy(); policy = new RandomMovePolicy();

View File

@@ -31,11 +31,6 @@ public class Connection {
return dest; return dest;
} }
//@XmlTransient
//public double getLastDelta() {
// return lastDelta;
//}
@XmlAttribute @XmlAttribute
public int getSrc() { public int getSrc() {
return src; return src;

View File

@@ -0,0 +1,292 @@
package net.woodyfolsom.msproj.ann;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import net.woodyfolsom.msproj.Action;
import net.woodyfolsom.msproj.GameConfig;
import net.woodyfolsom.msproj.GameRecord;
import net.woodyfolsom.msproj.GameResult;
import net.woodyfolsom.msproj.GameState;
import net.woodyfolsom.msproj.Player;
import net.woodyfolsom.msproj.policy.NeuralNetPolicy;
import net.woodyfolsom.msproj.policy.Policy;
import net.woodyfolsom.msproj.policy.RandomMovePolicy;
import net.woodyfolsom.msproj.tictactoe.NNDataSetFactory;
public class FusekiFilterTrainer { // implements epsilon-greedy trainer? online
// version of NeuralNetFilter
private boolean training = true;
public static void main(String[] args) throws IOException {
double alpha = 0.50;
double lambda = 0.90;
int maxGames = 1000;
new FusekiFilterTrainer().trainNetwork(alpha, lambda, maxGames);
}
public void trainNetwork(double alpha, double lambda, int maxGames)
throws IOException {
FeedforwardNetwork neuralNetwork;
GameConfig gameConfig = new GameConfig(9);
if (training) {
neuralNetwork = new MultiLayerPerceptron(true, 81, 18, 1);
neuralNetwork.setName("FusekiFilter" + gameConfig.getSize());
neuralNetwork.initWeights();
TrainingMethod trainer = new TemporalDifference(alpha, lambda);
System.out.println("Playing untrained games.");
for (int i = 0; i < 10; i++) {
GameRecord gameRecord = new GameRecord(gameConfig);
System.out.println("" + (i + 1) + ". "
+ playOptimal(neuralNetwork, gameRecord).getResult());
}
System.out.println("Learning from " + maxGames
+ " games of random self-play");
int gamesPlayed = 0;
List<GameResult> results = new ArrayList<GameResult>();
do {
GameRecord gameRecord = new GameRecord(gameConfig);
playEpsilonGreedy(0.50, neuralNetwork, trainer, gameRecord);
System.out.println("Winner: " + gameRecord.getResult());
gamesPlayed++;
results.add(gameRecord.getResult());
} while (gamesPlayed < maxGames);
System.out.println("Results of every 10th training game:");
for (int i = 0; i < results.size(); i++) {
if (i % 10 == 0) {
System.out.println("" + (i + 1) + ". " + results.get(i));
}
}
System.out.println("Learned network after " + maxGames
+ " training games.");
} else {
System.out.println("Loading TicTacToe network from file.");
neuralNetwork = new MultiLayerPerceptron();
FileInputStream fis = new FileInputStream(new File("pass.net"));
if (!new MultiLayerPerceptron().load(fis)) {
System.out.println("Error loading pass.net from file.");
return;
}
fis.close();
}
evalTestCases(gameConfig, neuralNetwork);
System.out.println("Playing optimal games.");
List<GameResult> gameResults = new ArrayList<GameResult>();
for (int i = 0; i < 10; i++) {
GameRecord gameRecord = new GameRecord(gameConfig);
gameResults.add(playOptimal(neuralNetwork, gameRecord).getResult());
}
boolean suboptimalPlay = false;
System.out.println("Optimal game summary: ");
for (int i = 0; i < gameResults.size(); i++) {
GameResult result = gameResults.get(i);
System.out.println("" + (i + 1) + ". " + result);
}
File output = new File("pass.net");
FileOutputStream fos = new FileOutputStream(output);
neuralNetwork.save(fos);
System.out.println("Playing optimal vs random games.");
for (int i = 0; i < 10; i++) {
GameRecord gameRecord = new GameRecord(gameConfig);
System.out.println(""
+ (i + 1)
+ ". "
+ playOptimalVsRandom(neuralNetwork, gameRecord)
.getResult());
}
if (suboptimalPlay) {
System.out.println("Suboptimal play detected!");
}
}
private double[] createBoard(GameConfig gameConfig, Action... actions) {
GameRecord gameRec = new GameRecord(gameConfig);
for (Action action : actions) {
gameRec.play(gameRec.getPlayerToMove(), action);
}
return NNDataSetFactory.createDataPair(gameRec.getGameState(), FusekiFilterTrainer.class).getInput().getValues();
}
private void evalTestCases(GameConfig gameConfig, FeedforwardNetwork neuralNetwork) {
double[][] validationSet = new double[1][];
// start state: black has 0, white has 0 + komi, neither has passed
validationSet[0] = createBoard(gameConfig, Action.getInstance("C3"));
String[] inputNames = NNDataSetFactory.getInputFields(FusekiFilterTrainer.class);
String[] outputNames = NNDataSetFactory.getOutputFields(FusekiFilterTrainer.class);
System.out.println("Output from eval set (learned network):");
testNetwork(neuralNetwork, validationSet, inputNames, outputNames);
}
private GameRecord playOptimalVsRandom(FeedforwardNetwork neuralNetwork,
GameRecord gameRecord) {
NeuralNetPolicy neuralNetPolicy = new NeuralNetPolicy();
neuralNetPolicy.setMoveFilter(neuralNetwork);
Policy randomPolicy = new RandomMovePolicy();
GameConfig gameConfig = gameRecord.getGameConfig();
GameState gameState = gameRecord.getGameState();
Policy[] policies = new Policy[] { neuralNetPolicy, randomPolicy };
int turnNo = 0;
do {
Action action;
GameState nextState;
Player playerToMove = gameState.getPlayerToMove();
action = policies[turnNo % 2].getAction(gameConfig, gameState,
playerToMove);
if (!gameRecord.play(playerToMove, action)) {
throw new RuntimeException("Illegal move: " + action);
}
nextState = gameRecord.getGameState();
//System.out.println("Action " + action + " selected by policy "
// + policies[turnNo % 2].getName());
//System.out.println("Next board state: " + nextState);
gameState = nextState;
turnNo++;
} while (!gameState.isTerminal());
return gameRecord;
}
private GameRecord playOptimal(FeedforwardNetwork neuralNetwork,
GameRecord gameRecord) {
NeuralNetPolicy neuralNetPolicy = new NeuralNetPolicy();
neuralNetPolicy.setMoveFilter(neuralNetwork);
if (gameRecord.getNumTurns() > 0) {
throw new RuntimeException(
"PlayOptimal requires a new GameRecord with no turns played.");
}
GameState gameState;
do {
Action action;
GameState nextState;
Player playerToMove = gameRecord.getPlayerToMove();
action = neuralNetPolicy.getAction(gameRecord.getGameConfig(),
gameRecord.getGameState(), playerToMove);
if (!gameRecord.play(playerToMove, action)) {
throw new RuntimeException("Invalid move played: " + action);
}
nextState = gameRecord.getGameState();
//System.out.println("Action " + action + " selected by policy "
// + neuralNetPolicy.getName());
//System.out.println("Next board state: " + nextState);
gameState = nextState;
} while (!gameState.isTerminal());
return gameRecord;
}
private GameRecord playEpsilonGreedy(double epsilon,
FeedforwardNetwork neuralNetwork, TrainingMethod trainer,
GameRecord gameRecord) {
Policy randomPolicy = new RandomMovePolicy();
NeuralNetPolicy neuralNetPolicy = new NeuralNetPolicy();
neuralNetPolicy.setMoveFilter(neuralNetwork);
if (gameRecord.getNumTurns() > 0) {
throw new RuntimeException(
"PlayOptimal requires a new GameRecord with no turns played.");
}
GameState gameState = gameRecord.getGameState();
NNDataPair statePair;
Policy selectedPolicy;
trainer.zeroTraces(neuralNetwork);
do {
Action action;
GameState nextState;
Player playerToMove = gameRecord.getPlayerToMove();
if (Math.random() < epsilon) {
selectedPolicy = randomPolicy;
action = selectedPolicy
.getAction(gameRecord.getGameConfig(),
gameRecord.getGameState(),
gameRecord.getPlayerToMove());
if (!gameRecord.play(playerToMove, action)) {
throw new RuntimeException("Illegal move played: " + action);
}
nextState = gameRecord.getGameState();
} else {
selectedPolicy = neuralNetPolicy;
action = selectedPolicy
.getAction(gameRecord.getGameConfig(),
gameRecord.getGameState(),
gameRecord.getPlayerToMove());
if (!gameRecord.play(playerToMove, action)) {
throw new RuntimeException("Illegal move played: " + action);
}
nextState = gameRecord.getGameState();
statePair = NNDataSetFactory.createDataPair(gameState, FusekiFilterTrainer.class);
NNDataPair nextStatePair = NNDataSetFactory
.createDataPair(nextState, FusekiFilterTrainer.class);
trainer.iteratePattern(neuralNetwork, statePair,
nextStatePair.getIdeal());
}
gameState = nextState;
} while (!gameState.isTerminal());
// finally, reinforce the actual reward
statePair = NNDataSetFactory.createDataPair(gameState, FusekiFilterTrainer.class);
trainer.iteratePattern(neuralNetwork, statePair, statePair.getIdeal());
return gameRecord;
}
private void testNetwork(FeedforwardNetwork neuralNetwork,
double[][] validationSet, String[] inputNames, String[] outputNames) {
for (int valIndex = 0; valIndex < validationSet.length; valIndex++) {
NNDataPair dp = new NNDataPair(new NNData(inputNames,
validationSet[valIndex]), new NNData(outputNames,
new double[] { 0.0 }));
System.out.println(dp);
System.out.println(" => ");
System.out.println(neuralNetwork.compute(dp));
}
}
}

View File

@@ -148,7 +148,7 @@ public class MultiLayerPerceptron extends FeedforwardNetwork {
Marshaller m = jc.createMarshaller(); Marshaller m = jc.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
m.marshal(this, os); m.marshal(this, os);
m.marshal(this, System.out); //m.marshal(this, System.out);
return true; return true;
} catch (JAXBException je) { } catch (JAXBException je) {
je.printStackTrace(); je.printStackTrace();

View File

@@ -0,0 +1,298 @@
package net.woodyfolsom.msproj.ann;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import net.woodyfolsom.msproj.Action;
import net.woodyfolsom.msproj.GameConfig;
import net.woodyfolsom.msproj.GameRecord;
import net.woodyfolsom.msproj.GameResult;
import net.woodyfolsom.msproj.GameState;
import net.woodyfolsom.msproj.Player;
import net.woodyfolsom.msproj.policy.NeuralNetPolicy;
import net.woodyfolsom.msproj.policy.Policy;
import net.woodyfolsom.msproj.policy.RandomMovePolicy;
import net.woodyfolsom.msproj.tictactoe.NNDataSetFactory;
public class PassFilterTrainer { // implements epsilon-greedy trainer? online
// version of NeuralNetFilter
private boolean training = true;
public static void main(String[] args) throws IOException {
double alpha = 0.50;
double lambda = 0.1;
int maxGames = 1500;
new PassFilterTrainer().trainNetwork(alpha, lambda, maxGames);
}
public void trainNetwork(double alpha, double lambda, int maxGames)
throws IOException {
FeedforwardNetwork neuralNetwork;
GameConfig gameConfig = new GameConfig(9);
if (training) {
neuralNetwork = new MultiLayerPerceptron(true, 2, 2, 1);
neuralNetwork.setName("PassFilter" + gameConfig.getSize());
neuralNetwork.initWeights();
TrainingMethod trainer = new TemporalDifference(alpha, lambda);
System.out.println("Playing untrained games.");
for (int i = 0; i < 10; i++) {
GameRecord gameRecord = new GameRecord(gameConfig);
System.out.println("" + (i + 1) + ". "
+ playOptimal(neuralNetwork, gameRecord).getResult());
}
System.out.println("Learning from " + maxGames
+ " games of random self-play");
int gamesPlayed = 0;
List<GameResult> results = new ArrayList<GameResult>();
do {
GameRecord gameRecord = new GameRecord(gameConfig);
playEpsilonGreedy(0.5, neuralNetwork, trainer, gameRecord);
System.out.println("Winner: " + gameRecord.getResult());
gamesPlayed++;
results.add(gameRecord.getResult());
} while (gamesPlayed < maxGames);
System.out.println("Results of every 10th training game:");
for (int i = 0; i < results.size(); i++) {
if (i % 10 == 0) {
System.out.println("" + (i + 1) + ". " + results.get(i));
}
}
System.out.println("Learned network after " + maxGames
+ " training games.");
} else {
System.out.println("Loading TicTacToe network from file.");
neuralNetwork = new MultiLayerPerceptron();
FileInputStream fis = new FileInputStream(new File("pass.net"));
if (!new MultiLayerPerceptron().load(fis)) {
System.out.println("Error loading pass.net from file.");
return;
}
fis.close();
}
evalTestCases(neuralNetwork);
System.out.println("Playing optimal games.");
List<GameResult> gameResults = new ArrayList<GameResult>();
for (int i = 0; i < 10; i++) {
GameRecord gameRecord = new GameRecord(gameConfig);
gameResults.add(playOptimal(neuralNetwork, gameRecord).getResult());
}
boolean suboptimalPlay = false;
System.out.println("Optimal game summary: ");
for (int i = 0; i < gameResults.size(); i++) {
GameResult result = gameResults.get(i);
System.out.println("" + (i + 1) + ". " + result);
}
File output = new File("pass.net");
FileOutputStream fos = new FileOutputStream(output);
neuralNetwork.save(fos);
System.out.println("Playing optimal vs random games.");
for (int i = 0; i < 10; i++) {
GameRecord gameRecord = new GameRecord(gameConfig);
System.out.println(""
+ (i + 1)
+ ". "
+ playOptimalVsRandom(neuralNetwork, gameRecord)
.getResult());
}
if (suboptimalPlay) {
System.out.println("Suboptimal play detected!");
}
}
private void evalTestCases(FeedforwardNetwork neuralNetwork) {
double[][] validationSet = new double[4][];
//losing, opponent did not pass
//don't pass
//(0.0 1.0 0.0) => 0.0
validationSet[0] = new double[] { -1.0, -1.0 };
//winning, opponent did not pass
//maybe pass?
//(1.0 0.0 0.0) => ?
validationSet[1] = new double[] { 1.0, -1.0 };
//winning, opponent passed
//pass!
//(1.0 0.0 1.0) => 1.0
validationSet[2] = new double[] { 1.0, 1.0 };
//losing, opponent passed
//don't pass!
//(0.0 1.0 1.0) => 1.0
validationSet[3] = new double[] { -1.0, 1.0 };
String[] inputNames = NNDataSetFactory.getInputFields(PassFilterTrainer.class);
String[] outputNames = NNDataSetFactory.getOutputFields(PassFilterTrainer.class);
System.out.println("Output from eval set (learned network):");
testNetwork(neuralNetwork, validationSet, inputNames, outputNames);
}
private GameRecord playOptimalVsRandom(FeedforwardNetwork neuralNetwork,
GameRecord gameRecord) {
NeuralNetPolicy neuralNetPolicy = new NeuralNetPolicy();
neuralNetPolicy.setPassFilter(neuralNetwork);
Policy randomPolicy = new RandomMovePolicy();
GameConfig gameConfig = gameRecord.getGameConfig();
GameState gameState = gameRecord.getGameState();
Policy[] policies = new Policy[] { neuralNetPolicy, randomPolicy };
int turnNo = 0;
do {
Action action;
GameState nextState;
Player playerToMove = gameState.getPlayerToMove();
action = policies[turnNo % 2].getAction(gameConfig, gameState,
playerToMove);
if (!gameRecord.play(playerToMove, action)) {
throw new RuntimeException("Illegal move: " + action);
}
nextState = gameRecord.getGameState();
//System.out.println("Action " + action + " selected by policy "
// + policies[turnNo % 2].getName());
//System.out.println("Next board state: " + nextState);
gameState = nextState;
turnNo++;
} while (!gameState.isTerminal());
return gameRecord;
}
private GameRecord playOptimal(FeedforwardNetwork neuralNetwork,
GameRecord gameRecord) {
NeuralNetPolicy neuralNetPolicy = new NeuralNetPolicy();
neuralNetPolicy.setPassFilter(neuralNetwork);
if (gameRecord.getNumTurns() > 0) {
throw new RuntimeException(
"PlayOptimal requires a new GameRecord with no turns played.");
}
GameState gameState;
do {
Action action;
GameState nextState;
Player playerToMove = gameRecord.getPlayerToMove();
action = neuralNetPolicy.getAction(gameRecord.getGameConfig(),
gameRecord.getGameState(), playerToMove);
if (!gameRecord.play(playerToMove, action)) {
throw new RuntimeException("Invalid move played: " + action);
}
nextState = gameRecord.getGameState();
//System.out.println("Action " + action + " selected by policy "
// + neuralNetPolicy.getName());
//System.out.println("Next board state: " + nextState);
gameState = nextState;
} while (!gameState.isTerminal());
return gameRecord;
}
private GameRecord playEpsilonGreedy(double epsilon,
FeedforwardNetwork neuralNetwork, TrainingMethod trainer,
GameRecord gameRecord) {
Policy randomPolicy = new RandomMovePolicy();
NeuralNetPolicy neuralNetPolicy = new NeuralNetPolicy();
neuralNetPolicy.setPassFilter(neuralNetwork);
if (gameRecord.getNumTurns() > 0) {
throw new RuntimeException(
"PlayOptimal requires a new GameRecord with no turns played.");
}
GameState gameState = gameRecord.getGameState();
NNDataPair statePair;
Policy selectedPolicy;
trainer.zeroTraces(neuralNetwork);
do {
Action action;
GameState nextState;
Player playerToMove = gameRecord.getPlayerToMove();
if (Math.random() < epsilon) {
selectedPolicy = randomPolicy;
action = selectedPolicy
.getAction(gameRecord.getGameConfig(),
gameRecord.getGameState(),
gameRecord.getPlayerToMove());
if (!gameRecord.play(playerToMove, action)) {
throw new RuntimeException("Illegal move played: " + action);
}
nextState = gameRecord.getGameState();
} else {
selectedPolicy = neuralNetPolicy;
action = selectedPolicy
.getAction(gameRecord.getGameConfig(),
gameRecord.getGameState(),
gameRecord.getPlayerToMove());
if (!gameRecord.play(playerToMove, action)) {
throw new RuntimeException("Illegal move played: " + action);
}
nextState = gameRecord.getGameState();
statePair = NNDataSetFactory.createDataPair(gameState, PassFilterTrainer.class);
NNDataPair nextStatePair = NNDataSetFactory
.createDataPair(nextState, PassFilterTrainer.class);
trainer.iteratePattern(neuralNetwork, statePair,
nextStatePair.getIdeal());
}
gameState = nextState;
} while (!gameState.isTerminal());
// finally, reinforce the actual reward
statePair = NNDataSetFactory.createDataPair(gameState, PassFilterTrainer.class);
trainer.iteratePattern(neuralNetwork, statePair, statePair.getIdeal());
return gameRecord;
}
private void testNetwork(FeedforwardNetwork neuralNetwork,
double[][] validationSet, String[] inputNames, String[] outputNames) {
for (int valIndex = 0; valIndex < validationSet.length; valIndex++) {
NNDataPair dp = new NNDataPair(new NNData(inputNames,
validationSet[valIndex]), new NNData(outputNames,
new double[] { 0.0 }));
System.out.println(dp + " => " + neuralNetwork.compute(dp));
}
}
}

View File

@@ -1,34 +0,0 @@
package net.woodyfolsom.msproj.ann;
/**
* Based on sample code from http://neuroph.sourceforge.net
*
* @author Woody
*
*/
public class TTTFilter extends AbstractNeuralNetFilter implements
NeuralNetFilter {
private static final int INPUT_SIZE = 9;
private static final int OUTPUT_SIZE = 1;
public TTTFilter() {
this(0.5,0.0, 1000);
}
public TTTFilter(double alpha, double lambda, int maxEpochs) {
super( new MultiLayerPerceptron(true, INPUT_SIZE, 5, OUTPUT_SIZE),
new TemporalDifference(0.5,0.0), maxEpochs, 0.05);
super.getNeuralNetwork().setName("XORFilter");
}
@Override
public int getInputSize() {
return INPUT_SIZE;
}
@Override
public int getOutputSize() {
return OUTPUT_SIZE;
}
}

View File

@@ -22,8 +22,8 @@ public class TTTFilterTrainer { // implements epsilon-greedy trainer? online
private boolean training = true; private boolean training = true;
public static void main(String[] args) throws IOException { public static void main(String[] args) throws IOException {
double alpha = 0.50; double alpha = 0.025;
double lambda = 0.90; double lambda = .10;
int maxGames = 100000; int maxGames = 100000;
new TTTFilterTrainer().trainNetwork(alpha, lambda, maxGames); new TTTFilterTrainer().trainNetwork(alpha, lambda, maxGames);
@@ -51,7 +51,7 @@ public class TTTFilterTrainer { // implements epsilon-greedy trainer? online
int gamesPlayed = 0; int gamesPlayed = 0;
List<RESULT> results = new ArrayList<RESULT>(); List<RESULT> results = new ArrayList<RESULT>();
do { do {
GameRecord gameRecord = playEpsilonGreedy(0.50, neuralNetwork, GameRecord gameRecord = playEpsilonGreedy(0.9, neuralNetwork,
trainer); trainer);
System.out.println("Winner: " + gameRecord.getResult()); System.out.println("Winner: " + gameRecord.getResult());
gamesPlayed++; gamesPlayed++;

View File

@@ -3,12 +3,11 @@ package net.woodyfolsom.msproj.ann;
import java.util.List; import java.util.List;
public class TemporalDifference extends TrainingMethod { public class TemporalDifference extends TrainingMethod {
private final double alpha; private final double gamma;
// private final double gamma = 1.0;
private final double lambda; private final double lambda;
public TemporalDifference(double alpha, double lambda) { public TemporalDifference(double alpha, double lambda) {
this.alpha = alpha; this.gamma = alpha;
this.lambda = lambda; this.lambda = lambda;
} }
@@ -55,6 +54,7 @@ public class TemporalDifference extends TrainingMethod {
+ derivative + derivative
* (idealValues[i] - outputNeurons[i].getOutput())); * (idealValues[i] - outputNeurons[i].getOutput()));
} }
// walking down the list of Neurons in reverse order, propagate the // walking down the list of Neurons in reverse order, propagate the
// error // error
Neuron[] neurons = neuralNetwork.getNeurons(); Neuron[] neurons = neuralNetwork.getNeurons();
@@ -84,24 +84,10 @@ public class TemporalDifference extends TrainingMethod {
private void updateWeights(FeedforwardNetwork neuralNetwork, private void updateWeights(FeedforwardNetwork neuralNetwork,
double predictionError) { double predictionError) {
for (Connection connection : neuralNetwork.getConnections()) { for (Connection connection : neuralNetwork.getConnections()) {
/*
* Neuron srcNeuron = neuralNetwork.getNeuron(connection.getSrc());
* Neuron destNeuron =
* neuralNetwork.getNeuron(connection.getDest());
*
* double delta = alpha * srcNeuron.getOutput()
* destNeuron.getGradient() * predictionError +
* connection.getTrace() * lambda;
*
* // TODO allow for momentum // double lastDelta =
* connection.getLastDelta(); connection.addDelta(delta);
*/
Neuron srcNeuron = neuralNetwork.getNeuron(connection.getSrc()); Neuron srcNeuron = neuralNetwork.getNeuron(connection.getSrc());
Neuron destNeuron = neuralNetwork.getNeuron(connection.getDest()); Neuron destNeuron = neuralNetwork.getNeuron(connection.getDest());
double delta = alpha * srcNeuron.getOutput() double delta = gamma * srcNeuron.getOutput()
* destNeuron.getGradient() + connection.getTrace() * lambda; * destNeuron.getGradient() + connection.getTrace() * lambda;
// TODO allow for momentum
// double lastDelta = connection.getLastDelta();
connection.addDelta(delta); connection.addDelta(delta);
} }
} }
@@ -121,18 +107,11 @@ public class TemporalDifference extends TrainingMethod {
@Override @Override
protected void iteratePattern(FeedforwardNetwork neuralNetwork, protected void iteratePattern(FeedforwardNetwork neuralNetwork,
NNDataPair statePair, NNData nextReward) { NNDataPair statePair, NNData nextReward) {
// System.out.println("Learningrate: " + alpha);
zeroGradients(neuralNetwork); zeroGradients(neuralNetwork);
// System.out.println("Training with: " + statePair.getInput());
NNData ideal = nextReward; NNData ideal = nextReward;
NNData actual = neuralNetwork.compute(statePair); NNData actual = neuralNetwork.compute(statePair);
// System.out.println("Updating weights. Ideal Output: " + ideal);
// System.out.println("Actual Output: " + actual);
// backpropagate the gradients w.r.t. output error // backpropagate the gradients w.r.t. output error
backPropagate(neuralNetwork, ideal); backPropagate(neuralNetwork, ideal);

View File

@@ -18,7 +18,7 @@ public class XORFilter extends AbstractNeuralNetFilter implements
public XORFilter(double learningRate, double momentum) { public XORFilter(double learningRate, double momentum) {
super( new MultiLayerPerceptron(true, INPUT_SIZE, 2, OUTPUT_SIZE), super( new MultiLayerPerceptron(true, INPUT_SIZE, 2, OUTPUT_SIZE),
new BackPropagation(learningRate, momentum), 1000, 0.01); new BackPropagation(learningRate, momentum), 1000, 0.001);
super.getNeuralNetwork().setName("XORFilter"); super.getNeuralNetwork().setName("XORFilter");
} }

View File

@@ -191,4 +191,9 @@ public class AlphaBeta implements Policy {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@Override
public String getName() {
return "Alpha-Beta";
}
} }

View File

@@ -61,4 +61,9 @@ public class HumanGuiInput implements Policy {
goban.setGameState(gameState); goban.setGameState(gameState);
} }
@Override
public String getName() {
return "HumanGUI";
}
} }

View File

@@ -85,4 +85,9 @@ public class HumanKeyboardInput implements Policy {
} }
@Override
public String getName() {
return "HumanKeyboard";
}
} }

View File

@@ -161,7 +161,10 @@ public class Minimax implements Policy {
@Override @Override
public void setState(GameState gameState) { public void setState(GameState gameState) {
// TODO Auto-generated method stub }
@Override
public String getName() {
return "Minimax";
} }
} }

View File

@@ -85,8 +85,9 @@ public class MonteCarloAMAF extends MonteCarloUCT {
if (bestAction == Action.NONE) { if (bestAction == Action.NONE) {
System.out System.out
.println("MonteCarloUCT failed - no actions were found for the current game state (not even PASS)."); .println(getName() + " failed - no actions were found for the current game state (not even PASS).");
} else { } else {
if (isLogging()) {
System.out.println("Action " + bestAction + " selected for " System.out.println("Action " + bestAction + " selected for "
+ node.getGameState().getPlayerToMove() + node.getGameState().getPlayerToMove()
+ " with simulated win ratio of " + " with simulated win ratio of "
@@ -96,6 +97,7 @@ public class MonteCarloAMAF extends MonteCarloUCT {
+ node.getProperties().getVisits() + " rollouts among " + node.getProperties().getVisits() + " rollouts among "
+ node.getNumChildren() + node.getNumChildren()
+ " valid actions from the current state."); + " valid actions from the current state.");
}
} }
return bestAction; return bestAction;
} }
@@ -132,4 +134,9 @@ public class MonteCarloAMAF extends MonteCarloUCT {
node.addChild(action, newChild); node.addChild(action, newChild);
return newChildren; return newChildren;
} }
@Override
public String getName() {
return "UCT-RAVE";
}
} }

View File

@@ -56,4 +56,8 @@ public class MonteCarloSMAF extends MonteCarloAMAF {
currentNode = currentNode.getParent(); currentNode = currentNode.getParent();
} }
} }
public String getName() {
return "MonteCarloSMAF";
}
} }

View File

@@ -102,8 +102,9 @@ public class MonteCarloUCT extends MonteCarlo {
if (bestAction == Action.NONE) { if (bestAction == Action.NONE) {
System.out System.out
.println("MonteCarloUCT failed - no actions were found for the current game state (not even PASS)."); .println(getName() + " failed - no actions were found for the current game state (not even PASS).");
} else { } else {
if (isLogging()) {
System.out.println("Action " + bestAction + " selected for " System.out.println("Action " + bestAction + " selected for "
+ node.getGameState().getPlayerToMove() + node.getGameState().getPlayerToMove()
+ " with simulated win ratio of " + " with simulated win ratio of "
@@ -113,6 +114,7 @@ public class MonteCarloUCT extends MonteCarlo {
+ node.getProperties().getVisits() + " rollouts among " + node.getProperties().getVisits() + " rollouts among "
+ node.getNumChildren() + node.getNumChildren()
+ " valid actions from the current state."); + " valid actions from the current state.");
}
} }
return bestAction; return bestAction;
} }
@@ -230,4 +232,9 @@ public class MonteCarloUCT extends MonteCarlo {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@Override
public String getName() {
return "MonteCarloUCT";
}
} }

View File

@@ -0,0 +1,144 @@
package net.woodyfolsom.msproj.policy;
import java.util.Collection;
import java.util.List;
import net.woodyfolsom.msproj.Action;
import net.woodyfolsom.msproj.GameConfig;
import net.woodyfolsom.msproj.GameState;
import net.woodyfolsom.msproj.Player;
import net.woodyfolsom.msproj.ann.FeedforwardNetwork;
import net.woodyfolsom.msproj.ann.NNDataPair;
import net.woodyfolsom.msproj.ann.PassFilterTrainer;
import net.woodyfolsom.msproj.tictactoe.NNDataSetFactory;
public class NeuralNetPolicy implements Policy {
private FeedforwardNetwork moveFilter;
private FeedforwardNetwork passFilter;
private ValidMoveGenerator validMoveGenerator = new ValidMoveGenerator();
private Policy randomMovePolicy = new RandomMovePolicy();
public NeuralNetPolicy() {
}
@Override
public Action getAction(GameConfig gameConfig, GameState gameState,
Player player) {
//If passFilter != null, check for a strong PASS signal.
if (passFilter != null) {
GameState stateAfterPass = new GameState(gameState);
if (!stateAfterPass.playStone(player, Action.PASS)) {
throw new RuntimeException("Pass should always be valid, but playStone(" + player +", Action.PASS) failed.");
}
NNDataPair passData = NNDataSetFactory.createDataPair(gameState,PassFilterTrainer.class);
double estimatedValue = passFilter.compute(passData).getValues()[0];
//if losing and opponent passed, never pass
//if (passData.getInput().getValues()[0] == -1.0 && passData.getInput().getValues()[1] == 1.0) {
// estimatedValue = 0.0;
//}
if (player == Player.BLACK && 0.6 < estimatedValue) {
//System.out.println("NeuralNetwork estimates value of PASS at > 0.95 (BLACK) for " + passData.getInput());
return Action.PASS;
}
if (player == Player.WHITE && 0.4 > estimatedValue) {
//System.out.println("NeuralNetwork estimates value of PASS at > 0.95 (BLACK) for " + passData.getInput());
return Action.PASS;
}
}
//If moveFilter != null, calculate action estimates and return the best one.
//max # valid moves is 19x19+2 (any coord plus pass, resign).
List<Action> validMoves = validMoveGenerator.getActions(gameConfig, gameState, player, 363);
if (moveFilter != null) {
if (player == Player.BLACK) {
double bestValue = Double.NEGATIVE_INFINITY;
Action bestAction = Action.NONE;
for (Action actionToTry : validMoves) {
GameState stateAfterAction = new GameState(gameState);
if (!stateAfterAction.playStone(player, actionToTry)) {
throw new RuntimeException("Invalid move: " + actionToTry);
}
NNDataPair passData = NNDataSetFactory.createDataPair(stateAfterAction,PassFilterTrainer.class);
double estimatedValue = passFilter.compute(passData).getValues()[0];
if (estimatedValue > bestValue) {
bestAction = actionToTry;
}
}
if (bestValue > 0.95) {
return bestAction;
}
} else if (player == Player.WHITE) {
double bestValue = Double.POSITIVE_INFINITY;
Action bestAction = Action.NONE;
for (Action actionToTry : validMoves) {
GameState stateAfterAction = new GameState(gameState);
if (!stateAfterAction.playStone(player, actionToTry)) {
throw new RuntimeException("Invalid move: " + actionToTry);
}
NNDataPair passData = NNDataSetFactory.createDataPair(stateAfterAction,PassFilterTrainer.class);
double estimatedValue = passFilter.compute(passData).getValues()[0];
if (estimatedValue > bestValue) {
bestAction = actionToTry;
}
}
if (bestValue > 0.95) {
return bestAction;
}
} else {
throw new RuntimeException("Invalid player: " + player);
}
}
//If no moves make the cutoff, just return a random move.
return randomMovePolicy.getAction(gameConfig, gameState, player);
}
@Override
public Action getAction(GameConfig gameConfig, GameState gameState,
Collection<Action> prohibitedActions, Player player) {
throw new UnsupportedOperationException();
}
@Override
public int getNumStateEvaluations() {
return randomMovePolicy.getNumStateEvaluations();
}
@Override
public void setState(GameState gameState) {
randomMovePolicy.setState(gameState);
}
@Override
public boolean isLogging() {
return randomMovePolicy.isLogging();
}
@Override
public void setLogging(boolean logging) {
randomMovePolicy.setLogging(logging);
}
public void setMoveFilter(FeedforwardNetwork ffn) {
this.moveFilter = ffn;
}
public void setPassFilter(FeedforwardNetwork ffn) {
this.passFilter = ffn;
}
@Override
public String getName() {
return "NeuralNet" + (passFilter != null ? "-" + passFilter.getName() : "")
+ (passFilter != null ? "-" + passFilter.getName() : "");
}
}

View File

@@ -8,15 +8,17 @@ import net.woodyfolsom.msproj.GameState;
import net.woodyfolsom.msproj.Player; import net.woodyfolsom.msproj.Player;
public interface Policy { public interface Policy {
public Action getAction(GameConfig gameConfig, GameState gameState, Action getAction(GameConfig gameConfig, GameState gameState,
Player player); Player player);
public Action getAction(GameConfig gameConfig, GameState gameState, Action getAction(GameConfig gameConfig, GameState gameState,
Collection<Action> prohibitedActions, Player player); Collection<Action> prohibitedActions, Player player);
public int getNumStateEvaluations(); String getName();
public void setState(GameState gameState); int getNumStateEvaluations();
void setState(GameState gameState);
boolean isLogging(); boolean isLogging();

View File

@@ -0,0 +1,14 @@
package net.woodyfolsom.msproj.policy;
public class PolicyFactory {
public static Policy createNew(Policy policyPrototype) {
if (policyPrototype instanceof RandomMovePolicy) {
return new RandomMovePolicy();
} else if (policyPrototype instanceof NeuralNetPolicy) {
return new NeuralNetPolicy();
} else {
throw new UnsupportedOperationException("Can only create new NeuralNetPolicy, not " + policyPrototype.getName());
}
}
}

View File

@@ -123,4 +123,9 @@ public class RandomMovePolicy implements Policy, ActionGenerator {
public void setState(GameState gameState) { public void setState(GameState gameState) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@Override
public String getName() {
return "Random";
}
} }

View File

@@ -0,0 +1,186 @@
package net.woodyfolsom.msproj.policy;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.woodyfolsom.msproj.Action;
import net.woodyfolsom.msproj.GameConfig;
import net.woodyfolsom.msproj.GameState;
import net.woodyfolsom.msproj.Player;
import net.woodyfolsom.msproj.tree.AMAFProperties;
import net.woodyfolsom.msproj.tree.MonteCarloProperties;
public class RootParAMAF implements Policy {
private boolean logging = false;
private int numTrees = 1;
private Policy rolloutPolicy;
public boolean isLogging() {
return logging;
}
public void setLogging(boolean logging) {
this.logging = logging;
}
private long timeLimit = 1000L;
public RootParAMAF(int numTrees, long timeLimit) {
this.numTrees = numTrees;
this.timeLimit = timeLimit;
this.rolloutPolicy = new RandomMovePolicy();
}
public RootParAMAF(int numTrees, Policy policyPrototype, long timeLimit) {
this.numTrees = numTrees;
this.timeLimit = timeLimit;
this.rolloutPolicy = policyPrototype;
}
@Override
public Action getAction(GameConfig gameConfig, GameState gameState,
Player player) {
Action bestAction = Action.NONE;
List<PolicyRunner> policyRunners = new ArrayList<PolicyRunner>();
List<Thread> simulationThreads = new ArrayList<Thread>();
for (int i = 0; i < numTrees; i++) {
MonteCarlo policy = new MonteCarloAMAF(
PolicyFactory.createNew(rolloutPolicy), timeLimit);
//policy.setLogging(true);
PolicyRunner policyRunner = new PolicyRunner(policy, gameConfig, gameState,
player);
policyRunners.add(policyRunner);
Thread simThread = new Thread(policyRunner);
simulationThreads.add(simThread);
}
for (Thread simThread : simulationThreads) {
simThread.start();
}
for (Thread simThread : simulationThreads) {
try {
simThread.join();
} catch (InterruptedException ie) {
System.out
.println("Interrupted while waiting for Monte Carlo simulations to finish.");
}
}
Map<Action,Integer> totalReward = new HashMap<Action,Integer>();
Map<Action,Integer> numSims = new HashMap<Action,Integer>();
for (PolicyRunner policyRunner : policyRunners) {
Map<Action, MonteCarloProperties> qValues = policyRunner.getQvalues();
for (Action action : qValues.keySet()) {
if (totalReward.containsKey(action)) {
totalReward.put(action, totalReward.get(action) + ((AMAFProperties)qValues.get(action)).getAmafWins());
} else {
totalReward.put(action, ((AMAFProperties)qValues.get(action)).getAmafWins());
}
if (numSims.containsKey(action)) {
numSims.put(action, numSims.get(action) + ((AMAFProperties)qValues.get(action)).getAmafVisits());
} else {
numSims.put(action, ((AMAFProperties)qValues.get(action)).getAmafVisits());
}
}
}
double bestValue = 0.0;
int totalRollouts = 0;
int bestWins = 0;
int bestSims = 0;
for (Action action : totalReward.keySet())
{
int totalWins = totalReward.get(action);
int totalSims = numSims.get(action);
totalRollouts += totalSims;
double value = ((double)totalWins) / ((double)totalSims);
if (bestAction.isNone() || bestValue < value) {
bestAction = action;
bestValue = value;
bestWins = totalWins;
bestSims = totalSims;
}
}
if(isLogging()) {
System.out.println("Action " + bestAction + " selected for "
+ player
+ " with simulated win ratio of "
+ (bestValue * 100.0 + "% among " + numTrees + " parallel simulations."));
System.out.println("It won "
+ bestWins + " out of " + bestSims
+ " rollouts among " + totalRollouts
+ " total rollouts (" + totalReward.size()
+ " possible moves evaluated) from the current state.");
}
return bestAction;
}
@Override
public Action getAction(GameConfig gameConfig, GameState gameState,
Collection<Action> prohibitedActions, Player player) {
throw new UnsupportedOperationException(
"Prohibited actions not supported by this class.");
}
@Override
public int getNumStateEvaluations() {
// TODO Auto-generated method stub
return 0;
}
class PolicyRunner implements Runnable {
Map<Action,MonteCarloProperties> qValues;
private GameConfig gameConfig;
private GameState gameState;
private Player player;
private MonteCarlo policy;
public PolicyRunner(MonteCarlo policy, GameConfig gameConfig,
GameState gameState, Player player) {
this.policy = policy;
this.gameConfig = gameConfig;
this.gameState = gameState;
this.player = player;
}
public Map<Action,MonteCarloProperties> getQvalues() {
return qValues;
}
@Override
public void run() {
qValues = policy.getQvalues(gameConfig, gameState, player);
}
}
@Override
public void setState(GameState gameState) {
}
@Override
public String getName() {
if (rolloutPolicy.getName() == "Random") {
return "RootParallelization";
} else {
return "RootParallelization-" + rolloutPolicy.getName();
}
}
}

View File

@@ -0,0 +1,186 @@
package net.woodyfolsom.msproj.policy;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.woodyfolsom.msproj.Action;
import net.woodyfolsom.msproj.GameConfig;
import net.woodyfolsom.msproj.GameState;
import net.woodyfolsom.msproj.Player;
import net.woodyfolsom.msproj.tree.AMAFProperties;
import net.woodyfolsom.msproj.tree.MonteCarloProperties;
public class RootParSMAF implements Policy {
private boolean logging = false;
private int numTrees = 1;
private Policy rolloutPolicy;
public boolean isLogging() {
return logging;
}
public void setLogging(boolean logging) {
this.logging = logging;
}
private long timeLimit = 1000L;
public RootParSMAF(int numTrees, long timeLimit) {
this.numTrees = numTrees;
this.timeLimit = timeLimit;
this.rolloutPolicy = new RandomMovePolicy();
}
public RootParSMAF(int numTrees, Policy policyPrototype, long timeLimit) {
this.numTrees = numTrees;
this.timeLimit = timeLimit;
this.rolloutPolicy = policyPrototype;
}
@Override
public Action getAction(GameConfig gameConfig, GameState gameState,
Player player) {
Action bestAction = Action.NONE;
List<PolicyRunner> policyRunners = new ArrayList<PolicyRunner>();
List<Thread> simulationThreads = new ArrayList<Thread>();
for (int i = 0; i < numTrees; i++) {
MonteCarlo policy = new MonteCarloSMAF(
PolicyFactory.createNew(rolloutPolicy), timeLimit, 4);
//policy.setLogging(true);
PolicyRunner policyRunner = new PolicyRunner(policy, gameConfig, gameState,
player);
policyRunners.add(policyRunner);
Thread simThread = new Thread(policyRunner);
simulationThreads.add(simThread);
}
for (Thread simThread : simulationThreads) {
simThread.start();
}
for (Thread simThread : simulationThreads) {
try {
simThread.join();
} catch (InterruptedException ie) {
System.out
.println("Interrupted while waiting for Monte Carlo simulations to finish.");
}
}
Map<Action,Integer> totalReward = new HashMap<Action,Integer>();
Map<Action,Integer> numSims = new HashMap<Action,Integer>();
for (PolicyRunner policyRunner : policyRunners) {
Map<Action, MonteCarloProperties> qValues = policyRunner.getQvalues();
for (Action action : qValues.keySet()) {
if (totalReward.containsKey(action)) {
totalReward.put(action, totalReward.get(action) + ((AMAFProperties)qValues.get(action)).getAmafWins());
} else {
totalReward.put(action, ((AMAFProperties)qValues.get(action)).getAmafWins());
}
if (numSims.containsKey(action)) {
numSims.put(action, numSims.get(action) + ((AMAFProperties)qValues.get(action)).getAmafVisits());
} else {
numSims.put(action, ((AMAFProperties)qValues.get(action)).getAmafVisits());
}
}
}
double bestValue = 0.0;
int totalRollouts = 0;
int bestWins = 0;
int bestSims = 0;
for (Action action : totalReward.keySet())
{
int totalWins = totalReward.get(action);
int totalSims = numSims.get(action);
totalRollouts += totalSims;
double value = ((double)totalWins) / ((double)totalSims);
if (bestAction.isNone() || bestValue < value) {
bestAction = action;
bestValue = value;
bestWins = totalWins;
bestSims = totalSims;
}
}
if(isLogging()) {
System.out.println("Action " + bestAction + " selected for "
+ player
+ " with simulated win ratio of "
+ (bestValue * 100.0 + "% among " + numTrees + " parallel simulations."));
System.out.println("It won "
+ bestWins + " out of " + bestSims
+ " rollouts among " + totalRollouts
+ " total rollouts (" + totalReward.size()
+ " possible moves evaluated) from the current state.");
}
return bestAction;
}
@Override
public Action getAction(GameConfig gameConfig, GameState gameState,
Collection<Action> prohibitedActions, Player player) {
throw new UnsupportedOperationException(
"Prohibited actions not supported by this class.");
}
@Override
public int getNumStateEvaluations() {
// TODO Auto-generated method stub
return 0;
}
class PolicyRunner implements Runnable {
Map<Action,MonteCarloProperties> qValues;
private GameConfig gameConfig;
private GameState gameState;
private Player player;
private MonteCarlo policy;
public PolicyRunner(MonteCarlo policy, GameConfig gameConfig,
GameState gameState, Player player) {
this.policy = policy;
this.gameConfig = gameConfig;
this.gameState = gameState;
this.player = player;
}
public Map<Action,MonteCarloProperties> getQvalues() {
return qValues;
}
@Override
public void run() {
qValues = policy.getQvalues(gameConfig, gameState, player);
}
}
@Override
public void setState(GameState gameState) {
}
@Override
public String getName() {
if (rolloutPolicy.getName() == "Random") {
return "RootParallelization";
} else {
return "RootParallelization-" + rolloutPolicy.getName();
}
}
}

View File

@@ -15,6 +15,8 @@ import net.woodyfolsom.msproj.tree.MonteCarloProperties;
public class RootParallelization implements Policy { public class RootParallelization implements Policy {
private boolean logging = false; private boolean logging = false;
private int numTrees = 1; private int numTrees = 1;
private Policy rolloutPolicy;
public boolean isLogging() { public boolean isLogging() {
return logging; return logging;
} }
@@ -28,8 +30,15 @@ public class RootParallelization implements Policy {
public RootParallelization(int numTrees, long timeLimit) { public RootParallelization(int numTrees, long timeLimit) {
this.numTrees = numTrees; this.numTrees = numTrees;
this.timeLimit = timeLimit; this.timeLimit = timeLimit;
this.rolloutPolicy = new RandomMovePolicy();
} }
public RootParallelization(int numTrees, Policy policyPrototype, long timeLimit) {
this.numTrees = numTrees;
this.timeLimit = timeLimit;
this.rolloutPolicy = policyPrototype;
}
@Override @Override
public Action getAction(GameConfig gameConfig, GameState gameState, public Action getAction(GameConfig gameConfig, GameState gameState,
Player player) { Player player) {
@@ -40,7 +49,7 @@ public class RootParallelization implements Policy {
for (int i = 0; i < numTrees; i++) { for (int i = 0; i < numTrees; i++) {
PolicyRunner policyRunner = new PolicyRunner(new MonteCarloUCT( PolicyRunner policyRunner = new PolicyRunner(new MonteCarloUCT(
new RandomMovePolicy(), timeLimit), gameConfig, gameState, PolicyFactory.createNew(rolloutPolicy), timeLimit), gameConfig, gameState,
player); player);
policyRunners.add(policyRunner); policyRunners.add(policyRunner);
@@ -103,6 +112,7 @@ public class RootParallelization implements Policy {
} }
if(isLogging()) {
System.out.println("Action " + bestAction + " selected for " System.out.println("Action " + bestAction + " selected for "
+ player + player
+ " with simulated win ratio of " + " with simulated win ratio of "
@@ -112,7 +122,7 @@ public class RootParallelization implements Policy {
+ " rollouts among " + totalRollouts + " rollouts among " + totalRollouts
+ " total rollouts (" + totalReward.size() + " total rollouts (" + totalReward.size()
+ " possible moves evaluated) from the current state."); + " possible moves evaluated) from the current state.");
}
return bestAction; return bestAction;
} }
@@ -156,8 +166,15 @@ public class RootParallelization implements Policy {
} }
@Override @Override
public void setState(GameState gameState) { public void setState(GameState gameState) {
// TODO Auto-generated method stub }
@Override
public String getName() {
if (rolloutPolicy.getName() == "Random") {
return "RootParallelization";
} else {
return "RootParallelization-" + rolloutPolicy.getName();
}
} }
} }

View File

@@ -3,13 +3,35 @@ package net.woodyfolsom.msproj.tictactoe;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import net.woodyfolsom.msproj.GameBoard;
import net.woodyfolsom.msproj.GameConfig;
import net.woodyfolsom.msproj.GameResult;
import net.woodyfolsom.msproj.GameState;
import net.woodyfolsom.msproj.Player;
import net.woodyfolsom.msproj.ann.FusekiFilterTrainer;
import net.woodyfolsom.msproj.ann.NNData; import net.woodyfolsom.msproj.ann.NNData;
import net.woodyfolsom.msproj.ann.NNDataPair; import net.woodyfolsom.msproj.ann.NNDataPair;
import net.woodyfolsom.msproj.ann.PassFilterTrainer;
import net.woodyfolsom.msproj.tictactoe.Game.PLAYER; import net.woodyfolsom.msproj.tictactoe.Game.PLAYER;
public class NNDataSetFactory { public class NNDataSetFactory {
public static final String[] TTT_INPUT_FIELDS = {"00","01","02","10","11","12","20","21","22"}; public static final String[] TTT_INPUT_FIELDS = {"00","01","02","10","11","12","20","21","22"};
public static final String[] TTT_OUTPUT_FIELDS = {"value"}; public static final String[] TTT_OUTPUT_FIELDS = {"VALUE"};
public static final String[] PASS_INPUT_FIELDS = {"WINNING","PREV_PLY_PASS"};
public static final String[] PASS_OUTPUT_FIELDS = {"SHOULD_PASS"};
public static final String[] FUSEKI_INPUT_FIELDS = {
"00","11","22","33","44","55","66","77","88",
"10","11","22","33","44","55","66","77","88",
"20","11","22","33","44","55","66","77","88",
"30","11","22","33","44","55","66","77","88",
"40","11","22","33","44","55","66","77","88",
"50","11","22","33","44","55","66","77","88",
"60","11","22","33","44","55","66","77","88",
"70","11","22","33","44","55","66","77","88",
"70","11","22","33","44","55","66","77","88"};
public static final String[] FUSEKI_OUTPUT_FIELDS = {"VALUE"};
public static List<List<NNDataPair>> createDataSet(List<GameRecord> tttGames) { public static List<List<NNDataPair>> createDataSet(List<GameRecord> tttGames) {
@@ -25,6 +47,26 @@ public class NNDataSetFactory {
return nnDataSet; return nnDataSet;
} }
public static String[] getInputFields(Object clazz) {
if (clazz == PassFilterTrainer.class) {
return PASS_INPUT_FIELDS;
} else if (clazz == FusekiFilterTrainer.class) {
return FUSEKI_INPUT_FIELDS;
} else {
throw new RuntimeException("Don't know how to return inputFields for NeuralNetwork Trainer of type: " + clazz.getClass().getName());
}
}
public static String[] getOutputFields(Object clazz) {
if (clazz == PassFilterTrainer.class) {
return PASS_OUTPUT_FIELDS;
} else if (clazz == FusekiFilterTrainer.class) {
return FUSEKI_OUTPUT_FIELDS;
} else {
throw new RuntimeException("Don't know how to return inputFields for NeuralNetwork Trainer of type: " + clazz.getClass().getName());
}
}
public static List<NNDataPair> createDataPairList(GameRecord gameRecord) { public static List<NNDataPair> createDataPairList(GameRecord gameRecord) {
List<NNDataPair> gameData = new ArrayList<NNDataPair>(); List<NNDataPair> gameData = new ArrayList<NNDataPair>();
@@ -35,6 +77,95 @@ public class NNDataSetFactory {
return gameData; return gameData;
} }
public static NNDataPair createDataPair(GameState goState, Object clazz) {
if (clazz == PassFilterTrainer.class) {
return createPassFilterDataPair(goState);
} else if (clazz == FusekiFilterTrainer.class) {
return createFusekiFilterDataPair(goState);
} else {
throw new RuntimeException("Don't know how to create DataPair for NeuralNetwork Trainer of type: " + clazz.getClass().getName());
}
}
private static NNDataPair createFusekiFilterDataPair(GameState goState) {
double value;
if (goState.isTerminal()) {
if (goState.getResult().isWinner(Player.BLACK)) {
value = 1.0; // win for black
} else if (goState.getResult().isWinner(Player.WHITE)) {
value = 0.0; // loss for black
//value = -1.0;
} else {// tie
value = 0.5;
//value = 0.0; //tie
}
} else {
value = 0.0;
}
int size = goState.getGameConfig().getSize();
double[] inputValues = new double[size * size];
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
//col then row
char symbol = goState.getGameBoard().getSymbolAt(j, i);
switch (symbol) {
case GameBoard.EMPTY_INTERSECTION : inputValues[i*size+j] = 0.0;
break;
case GameBoard.BLACK_STONE : inputValues[i*size+j] = 1.0;
break;
case GameBoard.WHITE_STONE : inputValues[i*size+j] = -1.0;
break;
}
}
}
return new NNDataPair(new NNData(FUSEKI_INPUT_FIELDS,inputValues),new NNData(FUSEKI_OUTPUT_FIELDS,new double[]{value}));
}
private static NNDataPair createPassFilterDataPair(GameState goState) {
double value;
GameResult result = goState.getResult();
if (goState.isTerminal()) {
if (result.isWinner(Player.BLACK)) {
value = 1.0; // win for black
} else if (result.isWinner(Player.WHITE)) {
value = 0.0; // loss for black
} else {// tie
value = 0.5;
//value = 0.0; //tie
}
} else {
value = 0.0;
}
double[] inputValues = new double[4];
inputValues[0] = result.isWinner(goState.getPlayerToMove()) ? 1.0 : -1.0;
//inputValues[1] = result.isWinner(goState.getPlayerToMove()) ? -1.0 : 1.0;
inputValues[1] = goState.isPrevPlyPass() ? 1.0 : 0.0;
return new NNDataPair(new NNData(PASS_INPUT_FIELDS,inputValues),new NNData(PASS_OUTPUT_FIELDS,new double[]{value}));
}
/*
private static double getNormalizedScore(GameState goState, Player player) {
GameResult gameResult = goState.getResult();
GameConfig gameConfig = goState.getGameConfig();
double maxPoints = Math.pow(gameConfig.getSize(),2);
double komi = gameConfig.getKomi();
if (player == Player.BLACK) {
return gameResult.getBlackScore() / maxPoints;
} else if (player == Player.WHITE) {
return gameResult.getWhiteScore() / (maxPoints + komi);
} else {
throw new RuntimeException("Invalid player");
}
}*/
public static NNDataPair createDataPair(State tttState) { public static NNDataPair createDataPair(State tttState) {
double value; double value;
if (tttState.isTerminal()) { if (tttState.isTerminal()) {

View File

@@ -1,100 +0,0 @@
package net.woodyfolsom.msproj.ann;
import java.io.File;
import java.io.IOException;
import java.util.List;
import net.woodyfolsom.msproj.ann.NNData;
import net.woodyfolsom.msproj.ann.NNDataPair;
import net.woodyfolsom.msproj.ann.NeuralNetFilter;
import net.woodyfolsom.msproj.ann.TTTFilter;
import net.woodyfolsom.msproj.tictactoe.GameRecord;
import net.woodyfolsom.msproj.tictactoe.NNDataSetFactory;
import net.woodyfolsom.msproj.tictactoe.Referee;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
public class TTTFilterTest {
private static final String FILENAME = "tttPerceptron.net";
@AfterClass
public static void deleteNewNet() {
File file = new File(FILENAME);
if (file.exists()) {
file.delete();
}
}
@BeforeClass
public static void deleteSavedNet() {
File file = new File(FILENAME);
if (file.exists()) {
file.delete();
}
}
@Test
public void testLearn() throws IOException {
double alpha = 0.5;
double lambda = 0.0;
int maxEpochs = 1000;
NeuralNetFilter nnLearner = new TTTFilter(alpha, lambda, maxEpochs);
// Create trainingSet from a tournament of random games.
// Future iterations will use Epsilon-greedy play from a policy based on
// this network to generate additional datasets.
List<GameRecord> tournament = new Referee().play(1);
List<List<NNDataPair>> trainingSet = NNDataSetFactory
.createDataSet(tournament);
System.out.println("Generated " + trainingSet.size()
+ " datasets from random self-play.");
nnLearner.learnSequences(trainingSet);
System.out.println("Learned network after "
+ nnLearner.getActualTrainingEpochs() + " training epochs.");
double[][] validationSet = new double[7][];
// empty board
validationSet[0] = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0 };
// center
validationSet[1] = new double[] { 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
0.0, 0.0 };
// top edge
validationSet[2] = new double[] { 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0 };
// left edge
validationSet[3] = new double[] { 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
0.0, 0.0 };
// corner
validationSet[4] = new double[] { 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0 };
// win
validationSet[5] = new double[] { 1.0, 1.0, 1.0, -1.0, -1.0, 0.0, 0.0,
-1.0, 0.0 };
// loss
validationSet[6] = new double[] { -1.0, 1.0, 0.0, 1.0, -1.0, 1.0, 0.0,
0.0, -1.0 };
String[] inputNames = new String[] { "00", "01", "02", "10", "11",
"12", "20", "21", "22" };
String[] outputNames = new String[] { "values" };
System.out.println("Output from eval set (learned network):");
testNetwork(nnLearner, validationSet, inputNames, outputNames);
}
private void testNetwork(NeuralNetFilter nnLearner,
double[][] validationSet, String[] inputNames, String[] outputNames) {
for (int valIndex = 0; valIndex < validationSet.length; valIndex++) {
NNDataPair dp = new NNDataPair(new NNData(inputNames,
validationSet[valIndex]), new NNData(outputNames,
validationSet[valIndex]));
System.out.println(dp + " => " + nnLearner.compute(dp));
}
}
}

View File

@@ -81,10 +81,10 @@ public class XORFilterTest {
@Test @Test
public void testLearnSaveLoad() throws IOException { public void testLearnSaveLoad() throws IOException {
NeuralNetFilter nnLearner = new XORFilter(0.5,0.0); NeuralNetFilter nnLearner = new XORFilter(0.05,0.0);
// create training set (logical XOR function) // create training set (logical XOR function)
int size = 2; int size = 1;
double[][] trainingInput = new double[4 * size][]; double[][] trainingInput = new double[4 * size][];
double[][] trainingOutput = new double[4 * size][]; double[][] trainingOutput = new double[4 * size][];
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
@@ -106,7 +106,7 @@ public class XORFilterTest {
trainingSet.add(new NNDataPair(new NNData(inputNames,trainingInput[i]),new NNData(outputNames,trainingOutput[i]))); trainingSet.add(new NNDataPair(new NNData(inputNames,trainingInput[i]),new NNData(outputNames,trainingOutput[i])));
} }
nnLearner.setMaxTrainingEpochs(1); nnLearner.setMaxTrainingEpochs(10000);
nnLearner.learnPatterns(trainingSet); nnLearner.learnPatterns(trainingSet);
System.out.println("Learned network after " + nnLearner.getActualTrainingEpochs() + " training epochs."); System.out.println("Learned network after " + nnLearner.getActualTrainingEpochs() + " training epochs.");

174
ttt.net
View File

@@ -1,62 +1,106 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<multiLayerPerceptron biased="true" name="TicTacToe"> <multiLayerPerceptron biased="true" name="TicTacToe">
<activationFunction name="Sigmoid"/> <activationFunction name="Sigmoid"/>
<connections dest="10" src="0" weight="0.5827629317852295"/> <connections dest="10" src="0" weight="-1.139430876029846"/>
<connections dest="10" src="1" weight="0.49198735902918994"/> <connections dest="10" src="1" weight="3.091584814276022"/>
<connections dest="10" src="2" weight="-0.3019566272377494"/> <connections dest="10" src="2" weight="-0.2551933137016801"/>
<connections dest="10" src="3" weight="0.42204442000472525"/> <connections dest="10" src="3" weight="-0.7615637398659946"/>
<connections dest="10" src="4" weight="-0.26015075178733194"/> <connections dest="10" src="4" weight="-0.6548680752915276"/>
<connections dest="10" src="5" weight="-0.001558299861060293"/> <connections dest="10" src="5" weight="0.08510244492139961"/>
<connections dest="10" src="6" weight="0.07987916348233416"/> <connections dest="10" src="6" weight="-0.8138255062915528"/>
<connections dest="10" src="7" weight="0.07258122647153753"/> <connections dest="10" src="7" weight="-0.2048642154445006"/>
<connections dest="10" src="8" weight="-0.691045501522254"/> <connections dest="10" src="8" weight="0.4118548734860931"/>
<connections dest="10" src="9" weight="0.7118463494749109"/> <connections dest="10" src="9" weight="-0.3418643333437593"/>
<connections dest="11" src="0" weight="-1.8387878977128804"/> <connections dest="11" src="0" weight="0.985258631016843"/>
<connections dest="11" src="1" weight="0.07066242812415906"/> <connections dest="11" src="1" weight="0.5585206829273895"/>
<connections dest="11" src="2" weight="-0.2141385079779094"/> <connections dest="11" src="2" weight="-0.00710478214319128"/>
<connections dest="11" src="3" weight="0.02318115051417748"/> <connections dest="11" src="3" weight="0.4458768855799938"/>
<connections dest="11" src="4" weight="-0.4940158494633454"/> <connections dest="11" src="4" weight="0.699630908274699"/>
<connections dest="11" src="5" weight="0.24951794707397953"/> <connections dest="11" src="5" weight="-0.291692394014361"/>
<connections dest="11" src="6" weight="-0.3422002057868113"/> <connections dest="11" src="6" weight="-0.3968126140382831"/>
<connections dest="11" src="7" weight="-0.34896333718320666"/> <connections dest="11" src="7" weight="1.5110166318959362"/>
<connections dest="11" src="8" weight="0.18236809262087086"/> <connections dest="11" src="8" weight="-0.18225892993024753"/>
<connections dest="11" src="9" weight="-0.39168932467050466"/> <connections dest="11" src="9" weight="-0.7602259764999595"/>
<connections dest="12" src="0" weight="1.5206290139263101"/> <connections dest="12" src="0" weight="1.7429897430035988"/>
<connections dest="12" src="1" weight="-0.4806468102477885"/> <connections dest="12" src="1" weight="-0.28322509888402325"/>
<connections dest="12" src="2" weight="0.21439697155823853"/> <connections dest="12" src="2" weight="0.5040019819001578"/>
<connections dest="12" src="3" weight="0.1226010537695569"/> <connections dest="12" src="3" weight="0.9359376456777513"/>
<connections dest="12" src="4" weight="-0.2957055657777683"/> <connections dest="12" src="4" weight="-0.15284920922664844"/>
<connections dest="12" src="5" weight="0.6130228290778311"/> <connections dest="12" src="5" weight="-3.4788220747438667"/>
<connections dest="12" src="6" weight="0.36875530286236485"/> <connections dest="12" src="6" weight="0.7547569837163356"/>
<connections dest="12" src="7" weight="-0.5171899914088294"/> <connections dest="12" src="7" weight="-0.32085504506413287"/>
<connections dest="12" src="8" weight="0.10837708801339006"/> <connections dest="12" src="8" weight="0.518047606917643"/>
<connections dest="12" src="9" weight="-0.7053746937035315"/> <connections dest="12" src="9" weight="0.8207811849267582"/>
<connections dest="13" src="0" weight="0.002913660858364482"/> <connections dest="13" src="0" weight="0.0768646322526947"/>
<connections dest="13" src="1" weight="-0.7651207747987173"/> <connections dest="13" src="1" weight="0.675759240542896"/>
<connections dest="13" src="2" weight="0.9715970070491731"/> <connections dest="13" src="2" weight="-1.04758516390251"/>
<connections dest="13" src="3" weight="-0.9956453258174628"/> <connections dest="13" src="3" weight="-1.1207097351854434"/>
<connections dest="13" src="4" weight="-0.9408358352747842"/> <connections dest="13" src="4" weight="-1.0663558249243994"/>
<connections dest="13" src="5" weight="-1.008966493202113"/> <connections dest="13" src="5" weight="0.40669746747595964"/>
<connections dest="13" src="6" weight="-0.672355054680489"/> <connections dest="13" src="6" weight="-0.8040553688830026"/>
<connections dest="13" src="7" weight="-0.3367206164565582"/> <connections dest="13" src="7" weight="-0.810063503984392"/>
<connections dest="13" src="8" weight="0.7588693137687637"/> <connections dest="13" src="8" weight="-0.63726821466013"/>
<connections dest="13" src="9" weight="-0.7196453490945308"/> <connections dest="13" src="9" weight="-0.062253116036353605"/>
<connections dest="14" src="0" weight="-1.9439726796836931"/> <connections dest="14" src="0" weight="-0.2569035720861068"/>
<connections dest="14" src="1" weight="-0.2894027034518325"/> <connections dest="14" src="1" weight="-0.23868649547740917"/>
<connections dest="14" src="2" weight="0.2110335238178935"/> <connections dest="14" src="2" weight="0.3319329593778122"/>
<connections dest="14" src="3" weight="-0.009846640898758158"/> <connections dest="14" src="3" weight="0.22285129465763973"/>
<connections dest="14" src="4" weight="0.1568088381509006"/> <connections dest="14" src="4" weight="-1.1932177045246797"/>
<connections dest="14" src="5" weight="-0.18073468038735682"/> <connections dest="14" src="5" weight="-0.8246033698516325"/>
<connections dest="14" src="6" weight="0.3823096688264287"/> <connections dest="14" src="6" weight="-1.1522063213004192"/>
<connections dest="14" src="7" weight="-0.21319807548539116"/> <connections dest="14" src="7" weight="-0.08295162498206299"/>
<connections dest="14" src="8" weight="-0.3736851760400955"/> <connections dest="14" src="8" weight="0.45121422208738693"/>
<connections dest="14" src="9" weight="-0.10659568761110778"/> <connections dest="14" src="9" weight="0.1344210997671879"/>
<connections dest="15" src="0" weight="-3.5802003342217197"/> <connections dest="15" src="0" weight="-0.19080274015172097"/>
<connections dest="15" src="10" weight="-0.520010988494904"/> <connections dest="15" src="1" weight="-0.08751712180997395"/>
<connections dest="15" src="11" weight="2.0607479402794953"/> <connections dest="15" src="2" weight="0.6338301857587448"/>
<connections dest="15" src="12" weight="-1.3810086619100004"/> <connections dest="15" src="3" weight="-0.9971509770232028"/>
<connections dest="15" src="13" weight="-0.024645797466295187"/> <connections dest="15" src="4" weight="0.37406630555233944"/>
<connections dest="15" src="14" weight="2.4372644169618125"/> <connections dest="15" src="5" weight="1.7040252761510988"/>
<connections dest="15" src="6" weight="0.43507827352032896"/>
<connections dest="15" src="7" weight="-1.030255483779959"/>
<connections dest="15" src="8" weight="0.6425158958005772"/>
<connections dest="15" src="9" weight="-0.2768699175127161"/>
<connections dest="16" src="0" weight="0.383162191474126"/>
<connections dest="16" src="1" weight="-0.316758353560207"/>
<connections dest="16" src="2" weight="-0.40398044046890863"/>
<connections dest="16" src="3" weight="-0.4103150897933657"/>
<connections dest="16" src="4" weight="-0.2110512886314012"/>
<connections dest="16" src="5" weight="-0.7537325411227123"/>
<connections dest="16" src="6" weight="-0.277432410233177"/>
<connections dest="16" src="7" weight="0.6523906983042057"/>
<connections dest="16" src="8" weight="0.8237246362854799"/>
<connections dest="16" src="9" weight="0.6450796646675565"/>
<connections dest="17" src="0" weight="-1.3222355951033131"/>
<connections dest="17" src="1" weight="-0.6775300244272042"/>
<connections dest="17" src="2" weight="-0.9101223420136262"/>
<connections dest="17" src="3" weight="-0.8913218057082705"/>
<connections dest="17" src="4" weight="-0.3228919507773142"/>
<connections dest="17" src="5" weight="0.6156397776974011"/>
<connections dest="17" src="6" weight="-0.6008468597628974"/>
<connections dest="17" src="7" weight="-0.3094929421425772"/>
<connections dest="17" src="8" weight="1.4800051973199828"/>
<connections dest="17" src="9" weight="-0.26820420703433634"/>
<connections dest="18" src="0" weight="-0.4724752146627139"/>
<connections dest="18" src="1" weight="-0.17278878268217254"/>
<connections dest="18" src="2" weight="-0.3213530770778259"/>
<connections dest="18" src="3" weight="-0.4343270409319928"/>
<connections dest="18" src="4" weight="0.5864291732809569"/>
<connections dest="18" src="5" weight="0.4944358358169582"/>
<connections dest="18" src="6" weight="0.8432289820265341"/>
<connections dest="18" src="7" weight="0.7294985221790254"/>
<connections dest="18" src="8" weight="0.19741936496860893"/>
<connections dest="18" src="9" weight="1.0649680979002503"/>
<connections dest="19" src="0" weight="2.6635011409263543"/>
<connections dest="19" src="10" weight="2.185963006026185"/>
<connections dest="19" src="11" weight="-1.401987872790659"/>
<connections dest="19" src="12" weight="-2.572264670917092"/>
<connections dest="19" src="13" weight="-2.719351802228293"/>
<connections dest="19" src="14" weight="2.14428000554082"/>
<connections dest="19" src="15" weight="-2.5948425406968325"/>
<connections dest="19" src="16" weight="-2.593589676600079"/>
<connections dest="19" src="17" weight="1.2492257986319857"/>
<connections dest="19" src="18" weight="2.7912530986331845"/>
<neurons id="0"> <neurons id="0">
<activationFunction xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="activationFunction" name="Linear"/> <activationFunction xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="activationFunction" name="Linear"/>
</neurons> </neurons>
@@ -103,6 +147,18 @@
<activationFunction xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="activationFunction" name="Tanh"/> <activationFunction xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="activationFunction" name="Tanh"/>
</neurons> </neurons>
<neurons id="15"> <neurons id="15">
<activationFunction xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="activationFunction" name="Tanh"/>
</neurons>
<neurons id="16">
<activationFunction xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="activationFunction" name="Tanh"/>
</neurons>
<neurons id="17">
<activationFunction xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="activationFunction" name="Tanh"/>
</neurons>
<neurons id="18">
<activationFunction xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="activationFunction" name="Tanh"/>
</neurons>
<neurons id="19">
<activationFunction name="Sigmoid"/> <activationFunction name="Sigmoid"/>
</neurons> </neurons>
<layers> <layers>
@@ -122,8 +178,12 @@
<neuronIds>12</neuronIds> <neuronIds>12</neuronIds>
<neuronIds>13</neuronIds> <neuronIds>13</neuronIds>
<neuronIds>14</neuronIds> <neuronIds>14</neuronIds>
<neuronIds>15</neuronIds>
<neuronIds>16</neuronIds>
<neuronIds>17</neuronIds>
<neuronIds>18</neuronIds>
</layers> </layers>
<layers> <layers>
<neuronIds>15</neuronIds> <neuronIds>19</neuronIds>
</layers> </layers>
</multiLayerPerceptron> </multiLayerPerceptron>