From: Jason H. <jas...@gm...> - 2009-06-23 12:01:04
|
Deterministic player selection does not achieve the goals of CGOS... That introduces bias in the pairings. Randomness is important. It may be good to honor NumberOfGames with only one engine. It provides an easy way to limit memory growth. Maybe zero could mean play forever without restarting? Sent from my iPhone On Jun 23, 2009, at 7:43 AM, cne...@us... wrote: > Revision: 39 > http://cgos.svn.sourceforge.net/cgos/?rev=39&view=rev > Author: cnentwich > Date: 2009-06-23 11:43:43 +0000 (Tue, 23 Jun 2009) > > Log Message: > ----------- > Updated docs for 0.3.0 release > > Multiple engines no longer play using probabilistic selection; round- > robin selection is used now, to keep reconnects down > > Modified Paths: > -------------- > trunk/client-python/doc/index.html > trunk/client-python/sample.cfg > trunk/client-python/src/cgosclient.py > trunk/client-python/src/config.py > trunk/client-python/testdata/local.cfg > > Added Paths: > ----------- > trunk/client-python/doc/changes.html > > Added: trunk/client-python/doc/changes.html > =================================================================== > --- trunk/client-python/doc/changes.html > (rev 0) > +++ trunk/client-python/doc/changes.html 2009-06-23 11:43:43 UTC > (rev 39) > @@ -0,0 +1,30 @@ > +<html> > + <head> > + <title>Python CGOS Client - Change Log</title> > + <style type="text/css"> > + h1 { font-size: 160%; font-weight: bold; margin-top: 1.5em; > background: #eee; padding: 0.3em; } > + h2 { font-size: 140%; font-weight: normal; margin-top: > 1.5em; background: #eee; padding: 0.3em; } > + pre { background-color: #eee; padding: 0.2em; } > + table { board: 1px solid black; border-collapse: collapse; } > + td, th { border: 1px solid black; padding: 0.3em; } > + th { text-align: left; background: #eee } > + > + </style> > + </head> > + <body> > + <h1>Python CGOS Client - Changes</h1> > + > + <b>Version 0.3.0</b> > + > + <ul> > + <li>Support for multiple engines > + <li>Backwards-incompatible configuration file changes: > + <ul> > + <li>New mandatory attribute <b>Name</b> for each > engine, giving display name > + <li>New mandatory attribute <b>NumberOfGames</b> > for each engine, indicating how many games it plays > + before switching to next > + </ul> > + </ul> > + > + </body> > +</html> > \ No newline at end of file > > Modified: trunk/client-python/doc/index.html > =================================================================== > --- trunk/client-python/doc/index.html 2009-06-17 15:00:32 UTC > (rev 38) > +++ trunk/client-python/doc/index.html 2009-06-23 11:43:43 UTC > (rev 39) > @@ -2,8 +2,8 @@ > <head> > <title>Python CGOS Client</title> > <style type="text/css"> > - h1 { font-size: 160%; font-weight: bold; margin-top: 1em; > background: #eee; padding: 0.3em; } > - h2 { font-size: 140%; font-weight: normal; margin-top: 1em; > background: #eee; padding: 0.3em; } > + h1 { font-size: 160%; font-weight: bold; margin-top: 1.5em; > background: #eee; padding: 0.3em; } > + h2 { font-size: 140%; font-weight: normal; margin-top: > 1.5em; background: #eee; padding: 0.3em; } > pre { background-color: #eee; padding: 0.2em; } > table { board: 1px solid black; border-collapse: collapse; } > td, th { border: 1px solid black; padding: 0.3em; } > @@ -15,30 +15,40 @@ > <h1>Python CGOS Client</h1> > > This client connects Go programs that implement the <a href="http://www.lysator.liu.se/~gunnar/gtp/ > ">GTP</a> > - protocol to the <a href="cgos.boardspace.net/">Computer > Go Server</a> (CGOS). If you downloaded this, > - you know what they are. > + protocol to the <a href="cgos.boardspace.net/">Computer > Go Server</a> (CGOS). If you downloaded this, you know what they are. > + <i>Any</i> GTP engine is supported, not just those written > in Python. > > <h2>Information</h2> > > - This is version <b>0.2.1</b>. This program is ©2009 > Christian Nentwich and is licensed to you under > + This is version <b>0.3.0</b>. This program is ©2009 > Christian Nentwich and is licensed to you under > the terms of the <a href="http://www.opensource.org/licenses/gpl-3.0.html > ">GNU General Public License version 3 (GPLv3)</a>. > > + <p> > + Please read the <a href="changes.html">change log</a>. > + > <p>For the avoidance of doubt:</b> this licence makes no > claim <i>whatsoever</i> about the Go programs > used with this client, in particular any programs using this > client to connect to CGOS shall <b>not</b> > meet the definition of a "covered work", or derivative work, > under this license. > > <p> > - The CGOS server and client are © Don Daily and others > and are not included here. > + The CGOS server and TCL client are © Don Daily and > others and are not included here. > > <ul> > <li><a href="#features">Features</a> > <li><a href="#usage">Usage</a> > - <li><a href="#gtp">GTP Commands</a> > - <li><a href="#ext">GTP Extensions</a> > - <li><a href="#logging">Logging</a> > - <li><a href="#observer">Displaying Games using GoGUI</a> > - <li><a href="#samplecfg">Sample Configuration</a> > + <li>GTP > + <ul> > + <li><a href="#gtp">GTP Commands</a> > + <li><a href="#ext">GTP Extensions</a> > </ul> > + <li>Configuration > + <ul> > + <li><a href="#logging">Logging</a> > + <li><a href="#observer">Displaying Games using GoGUI</a> > + <li><a href="#multipleengines">Alternating Between > Multiple Engines</a> > + <li><a href="#samplecfg">Sample Configuration</a> > + </ul> > + </ul> > > <h2 id="features">Features</h2> > > @@ -48,6 +58,7 @@ > <li>Waits for server restart when server crashes or is > unreachable (checks every 30 seconds + small random amount) > <li>Supports resume if the engine crashes. Just restart the > client and it will catch up the game. > <li>Kill file to terminate connections > + <li>Supports multiple engines, and automatic switching (but > <a href="#multipleengines">the behaviour</a> is slightly different) > </ul> > > <p> > @@ -179,27 +190,86 @@ > If you wish to stop displaying, put a kill file in place (see > above), then start the client > again without an observer. > > + <h2 id="multipleengines">Alternating Between Multiple > Engines</h2> > + > + In the <a href="#samplecfg">configuration file</a>, each > GTP engine has an attribute called > + <code>NumberOfGames</code>. This attribute is mandatory in > this version of the client, even if there > + is only one engine, though in the case of one engine it is > ignored. > + Multiple GTP engines are played sequentially in a round- > robin fashion. For example, if > + <code>NumberOfGames</code> is set to 2 for <b>EngineA</b> > and to 3 for <b>EngineB</b>, the client > + will play the engines as follows: > + > + <p> > + <table> > + <tr> > + <th>Game</th><th>Engine</th> > + </tr> > + <tr><td>1</td><td>EngineA</td></tr> > + <tr><td>2</td><td>EngineA</td></tr> > + <tr><td>3</td><td>EngineB</td></tr> > + <tr><td>4</td><td>EngineB</td></tr> > + <tr><td>5</td><td>EngineB</td></tr> > + <tr><td>6</td><td>EngineA</td></tr> > + <tr><td>7</td><td>EngineA</td></tr> > + <tr><td>8</td><td>EngineB</td></tr> > + <tr><td>9</td><td>...</td></tr> > + </table> > + > + <p> > + Recommendations: > + <ul> > + <li>If you are planning to play for a long time (e.g. a > day or longer of 9x9), set the > + game counts to five or higher. This minimises the > number of reconnects and restarts that have to be > + performed. > + <li>If your engines leak memory, set it lower - but set > up at least two engines or the > + attribute will be ignored. > + </ul> > + > <h2 id="samplecfg">Sample Configuration</h2> > > This sample configuration shows how <a href="http://www.gnu.org/software/gnugo/ > ">GNU Go</a> > can be connected to play on CGOS, 9x9 board size, and with > GoGUI running locally to view all > games. > > + In addition, the client will play round-robin between two > engine configurations, running the > + engine at level 8 for 5 games, followed by level 10 for 2 > games, and then starting over. > + > <p> > <pre>Common: > KillFile = kill.txt > > GTPEngine: > + # Name to display on console / in logs > + Name = Gnugo Level 8 > + > CommandLine = gnugo.exe --mode gtp --score aftermath --capture-all- > dead --chinese-rules --level 8 > > ServerHost = cgos.boardspace.net > ServerPort = 6867 > ServerUser = myuser > ServerPassword = mypw > - > - Priority = 5 > > + # Switch to next engine after this many games > + NumberOfGames = 5 > + > + # Optional: persist games here > SGFDirectory = ..\sgf9x9 > + > +GTPEngine: > + Name = Gnugo Level 10 > + CommandLine = gnugo.exe --mode gtp --score aftermath --capture- > all-dead --chinese-rules --level 10 > + > + ServerHost = cgos.boardspace.net > + ServerPort = 6867 > + ServerUser = myuser-level10 > + ServerPassword = mypw-level10 > + > + # Switch back to first engine after this many games > + NumberOfGames = 2 > + > + # Optional: persist games here > + SGFDirectory = ..\sgf9x9 > + > > # Observer engine (e.g. GoGUI) > GTPObserver: > > Modified: trunk/client-python/sample.cfg > =================================================================== > --- trunk/client-python/sample.cfg 2009-06-17 15:00:32 UTC (rev 38) > +++ trunk/client-python/sample.cfg 2009-06-23 11:43:43 UTC (rev 39) > @@ -2,8 +2,9 @@ > Common: > KillFile = kill.txt > > -# Multiple engines > +# First engine > GTPEngine: > + Name = Gnugo Level 8 > CommandLine = gnugo-3.8.exe --mode gtp --score aftermath --capture- > all-dead --chinese-rules --level 8 > > ServerHost = 127.0.0.1 > @@ -11,10 +12,26 @@ > ServerUser = myuser > ServerPassword = mypw > > - Priority = 5 > + # Play 5 games before switching to next > + NumberOfGames = 5 > > - SGFDirectory = sgf > + SGFDirectory = sgf\Engine1 > > +# Second engine > +GTPEngine: > + Name = Gnugo Level 10 > + CommandLine = gnugo-3.8.exe --mode gtp --score aftermath -- > capture-all-dead --chinese-rules --level 8 > + > + ServerHost = 127.0.0.1 > + ServerPort = 1919 > + ServerUser = myuser2 > + ServerPassword = mypw2 > + > + # Play 5 games before switching to next > + NumberOfGames = 5 > + > + SGFDirectory = sgf\Engine2 > + > # Observer engine (e.g. GoGUI) > GTPObserver: > CommandLine = C:\Program Files\Java\jdk1.6.0_13\bin\java.exe -jar > C:\path\to\gogui-1.1.9\lib\gogui-display.jar > \ No newline at end of file > > Modified: trunk/client-python/src/cgosclient.py > =================================================================== > --- trunk/client-python/src/cgosclient.py 2009-06-17 15:00:32 UTC > (rev 38) > +++ trunk/client-python/src/cgosclient.py 2009-06-23 11:43:43 UTC > (rev 39) > @@ -61,6 +61,7 @@ > self._engineConfigs = engineConfigurationSections > self._engine = None # Currently playing > engine > self._currentEngineIndex = -1 # Index in > configuration sections of current engine > + self._currentEngineGamesLeft = 0 # Number of games the > current engine has left before switching > > self._killFileName = killFileName # File that will trigger > shutdown > > @@ -134,30 +135,30 @@ > self._socketfile.close() > self._socket.close() > > - def _chooseEngineIndexAtRandom(self): > - ''' > - Pick an engine from the configuration file at random, given > the weights of > - all engines. > - ''' > - if len(self._engineConfigs) == 1: return 0 > - > - # Normalise weights to [0.0, 1.0] > - priorities = map(lambda x : int(x.getValue("Priority")), > self._engineConfigs) > - totalPriorities = reduce(lambda x,y: x+y, priorities) > - > - normalisedPriorities = map(lambda x : float(x)/ > totalPriorities, priorities) > - > - chosenEngineIndex = 0 > - cumulativeSum = 0.0 > - randomIndex = random.random() > - > - for idx in xrange(len(normalisedPriorities)): > - if randomIndex > cumulativeSum and randomIndex <= > cumulativeSum + normalisedPriorities[idx]: > - chosenEngineIndex = idx > - break > - cumulativeSum += normalisedPriorities[idx] > - > - return chosenEngineIndex > +# def _chooseEngineIndexAtRandom(self): > +# ''' > +# Pick an engine from the configuration file at random, > given the weights of > +# all engines. > +# ''' > +# if len(self._engineConfigs) == 1: return 0 > +# > +# # Normalise weights to [0.0, 1.0] > +# priorities = map(lambda x : int(x.getValue("Priority")), > self._engineConfigs) > +# totalPriorities = reduce(lambda x,y: x+y, priorities) > +# > +# normalisedPriorities = map(lambda x : float(x)/ > totalPriorities, priorities) > +# > +# chosenEngineIndex = 0 > +# cumulativeSum = 0.0 > +# randomIndex = random.random() > +# > +# for idx in xrange(len(normalisedPriorities)): > +# if randomIndex > cumulativeSum and randomIndex <= > cumulativeSum + normalisedPriorities[idx]: > +# chosenEngineIndex = idx > +# break > +# cumulativeSum += normalisedPriorities[idx] > +# > +# return chosenEngineIndex > > def _respond(self, message): > if self._socket is not None: > @@ -521,29 +522,38 @@ > Choose a different engine and reconnect. If the engine fails > to start, > this throws an exception > ''' > - > - newEngineIndex = self._chooseEngineIndexAtRandom() > - if newEngineIndex == self._currentEngineIndex: return > > + if self._currentEngineIndex == -1: > + self._currentEngineIndex = 0 > + elif len(self._engineConfigs) == 1: > + return > + else: > + self._currentEngineGamesLeft -= 1 > + > + if self._currentEngineGamesLeft > 0: > + return > + > + self._currentEngineIndex = (self._currentEngineIndex + > 1) % len(self._engineConfigs) > + > if self._engine is not None: > self._engine.shutdown() > > - newEngineConfig = self._engineConfigs[newEngineIndex] > + newEngineConfig = self._engineConfigs > [self._currentEngineIndex] > + self._currentEngineGamesLeft = int(newEngineConfig.getValue > ("NumberOfGames")) > > - self.logger.info("Chose engine " + str(newEngineIndex+1) + > " (\"" + newEngineConfig.getValue("Name") + > + self.logger.info("Chose engine " + str > (self._currentEngineIndex+1) + " (\"" + newEngineConfig.getValue > ("Name") + > "\") as next player. Switching and re- > connecting.") > > try: > newEngine = EngineConnector(newEngineConfig.getValue > ("CommandLine"), > newEngineConfig.getValue > ("Name"), > - logger="EngineConnector"+str > (newEngineIndex)) > + logger="EngineConnector"+str > (self._currentEngineIndex)) > newEngine.connect() > except Exception,e: > self.logger.error("Switch failed. Engine failed to > start: " + str(e)) > raise > > self._engine = newEngine > - self._currentEngineIndex = newEngineIndex > > if newEngineConfig.hasValue("SGFDirectory"): > self._sgfDirectory = newEngineConfig.getValue > ("SGFDirectory") > > Modified: trunk/client-python/src/config.py > =================================================================== > --- trunk/client-python/src/config.py 2009-06-17 15:00:32 UTC > (rev 38) > +++ trunk/client-python/src/config.py 2009-06-23 11:43:43 UTC > (rev 39) > @@ -108,15 +108,15 @@ > if section.name() == ConfigFile.ENGINE_SECTION: > hasEngine = True > > - for req in ["Name", "CommandLine", "ServerHost", > "ServerPort", "ServerUser", "ServerPassword", "Priority"]: > + for req in ["Name", "CommandLine", "ServerHost", > "ServerPort", "ServerUser", "ServerPassword", "NumberOfGames"]: > if not(section.hasValue(req)): > raise Exception("Mandatory engine attribute > missing: " + req) > > try: > - if int(section.getValue("Priority")) <= 0: > - raise Exception("Configuration attribute > 'Priority' must be greater than zero") > + if int(section.getValue("NumberOfGames")) <= 0: > + raise Exception("Configuration attribute > 'NumberOfGames' must be greater than zero") > except ValueError: > - raise Exception("Configuration attribute > 'Priority' must be an integer") > + raise Exception("Configuration attribute > 'NumberOfGames' must be an integer") > > > > > Modified: trunk/client-python/testdata/local.cfg > =================================================================== > --- trunk/client-python/testdata/local.cfg 2009-06-17 15:00:32 > UTC (rev 38) > +++ trunk/client-python/testdata/local.cfg 2009-06-23 11:43:43 > UTC (rev 39) > @@ -12,7 +12,7 @@ > ServerUser = localuser > ServerPassword = localpw > > - Priority = 1 > + NumberOfGames = 1 > > SGFDirectory = ..\testdata\sgfA > > @@ -25,10 +25,10 @@ > ServerUser = localuser2 > ServerPassword = localpw > > - Priority = 1 > + NumberOfGames = 2 > > SGFDirectory = ..\testdata\sgfB > > # Observer engine (e.g. GoGUI) > -GTPObserver: > - CommandLine = C:\Program Files\Java\jdk1.6.0_13\bin\java.exe -jar > C:\Users\nentwich\Documents\Go\gogui-1.1.9\lib\gogui-display.jar > \ No newline at end of file > +#GTPObserver: > +# CommandLine = C:\Program Files\Java\jdk1.6.0_13\bin\java.exe - > jar C:\Users\nentwich\Documents\Go\gogui-1.1.9\lib\gogui-display.jar > \ No newline at end of file > > > This was sent by the SourceForge.net collaborative development > platform, the world's largest Open Source development site. > > --- > --- > --- > --------------------------------------------------------------------- > Are you an open source citizen? Join us for the Open Source Bridge > conference! > Portland, OR, June 17-19. Two days of sessions, one day of > unconference: $250. > Need another reason to go? 24-hour hacker lounge. Register today! > http://ad.doubleclick.net/clk;215844324;13503038;v?http://opensourcebridge.org > _______________________________________________ > Cgos-developers mailing list > Cgo...@li... > https://lists.sourceforge.net/lists/listinfo/cgos-developers |