You can subscribe to this list here.
2008 |
Jan
(44) |
Feb
|
Mar
(7) |
Apr
(1) |
May
(2) |
Jun
|
Jul
(2) |
Aug
(8) |
Sep
|
Oct
|
Nov
|
Dec
|
---|---|---|---|---|---|---|---|---|---|---|---|---|
2009 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(1) |
Jun
(10) |
Jul
(2) |
Aug
(1) |
Sep
|
Oct
(2) |
Nov
|
Dec
|
From: <cne...@us...> - 2009-10-08 08:11:40
|
Revision: 45 http://cgos.svn.sourceforge.net/cgos/?rev=45&view=rev Author: cnentwich Date: 2009-10-08 08:11:29 +0000 (Thu, 08 Oct 2009) Log Message: ----------- updated versioning and change history Modified Paths: -------------- trunk/client-python/doc/changes.html trunk/client-python/doc/index.html Modified: trunk/client-python/doc/changes.html =================================================================== --- trunk/client-python/doc/changes.html 2009-10-08 08:06:36 UTC (rev 44) +++ trunk/client-python/doc/changes.html 2009-10-08 08:11:29 UTC (rev 45) @@ -14,6 +14,11 @@ <body> <h1>Python CGOS Client - Changes</h1> + <b>Version 0.3.1</b> + <ul> + <li>Fix for configuration: passing multiple parameters to engine should now work properly on non-Windows sytems + </ul> + <b>Version 0.3.0</b> <ul> Modified: trunk/client-python/doc/index.html =================================================================== --- trunk/client-python/doc/index.html 2009-10-08 08:06:36 UTC (rev 44) +++ trunk/client-python/doc/index.html 2009-10-08 08:11:29 UTC (rev 45) @@ -20,7 +20,7 @@ <h2>Information</h2> - This is version <b>0.3.0</b>. This program is ©2009 Christian Nentwich and <a href="contributors.html">contributors</a> + This is version <b>0.3.1</b>. This program is ©2009 Christian Nentwich and <a href="contributors.html">contributors</a> 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>. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cne...@us...> - 2009-10-08 08:06:46
|
Revision: 44 http://cgos.svn.sourceforge.net/cgos/?rev=44&view=rev Author: cnentwich Date: 2009-10-08 08:06:36 +0000 (Thu, 08 Oct 2009) Log Message: ----------- committing argument parsing fix (need to find contributor's name) Modified Paths: -------------- trunk/client-python/readme.txt trunk/client-python/src/config.py trunk/client-python/src/gtpengine.py Modified: trunk/client-python/readme.txt =================================================================== --- trunk/client-python/readme.txt 2009-07-01 19:04:49 UTC (rev 43) +++ trunk/client-python/readme.txt 2009-10-08 08:06:36 UTC (rev 44) @@ -1,5 +1,5 @@ -------------------------------------------------------------------------- -Copyright (C) 2009 Christian Nentwich +Copyright (C) 2009 Christian Nentwich and contributors This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,6 +17,7 @@ Refer to doc\index.html to get started. + doc\contributors.html lists the contributors. Modified: trunk/client-python/src/config.py =================================================================== --- trunk/client-python/src/config.py 2009-07-01 19:04:49 UTC (rev 43) +++ trunk/client-python/src/config.py 2009-10-08 08:06:36 UTC (rev 44) @@ -1,5 +1,5 @@ ''' -Copyright (C) 2009 Christian Nentwich +Copyright (C) 2009 Christian Nentwich and contributors This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -82,7 +82,7 @@ currentSection = ConfigSection(line[0 : len(line) -1 ]) self._sections.append(currentSection) elif "=" in line and currentSection is not None: - param = line.split("=") + param = line.split("=", 1) currentSection.addValue(param[0].strip(), param[1].strip()) self._validate() Modified: trunk/client-python/src/gtpengine.py =================================================================== --- trunk/client-python/src/gtpengine.py 2009-07-01 19:04:49 UTC (rev 43) +++ trunk/client-python/src/gtpengine.py 2009-10-08 08:06:36 UTC (rev 44) @@ -1,5 +1,5 @@ ''' -Copyright (C) 2009 Christian Nentwich +Copyright (C) 2009 Christian Nentwich and contributors This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -130,7 +130,11 @@ engine. ''' self.logger.info("Starting GTP engine, command line: " + self._programCommandLine) - self._subprocess = subprocess.Popen(self._programCommandLine, stdin=subprocess.PIPE, + if sys.platform == "win32": + args = self._programCommandLine + else: + args = self._programCommandLine.split() + self._subprocess = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=False) time.sleep(1) self._findSupportedCommands(mandatoryCommands) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: Folkert v. H. <fo...@va...> - 2009-08-03 08:54:51
|
Hi, Trying to start the cgos server but it fails: mauer:/usr/local/cgos# ./tclkit cgos.kit cgos.cfg bad switch "-timezone": must be -format or -gmt while executing "clock format [clock seconds] -format "%Y-%m-%d %H:%M:%S" -timezone :UTC" invoked from within "if { $argc < 1 } { puts "Must specify a configuration file." exit 1 } else { set cfg [lindex $argv 0] if { [ catch {source $cfg} ] } {..." (file "/usr/local/cgos/cgos.kit/lib/app-cgos/cgos.tcl" line 11) invoked from within "source /usr/local/cgos/cgos.kit/lib/app-cgos/cgos.tcl" ("package ifneeded" script) invoked from within "package require app-cgos" (file "/usr/local/cgos/cgos.kit/main.tcl" line 4) invoked from within "source /usr/local/cgos/cgos.kit/main.tcl" ("uplevel" body line 1) invoked from within "uplevel [list source [file join $self main.tcl]]" Is there any way I can fix this problem? Thank you. Folkert van Heusden -- MultiTail is a versatile tool for watching logfiles and output of commands. Filtering, coloring, merging, diff-view, etc. http://www.vanheusden.com/multitail/ ---------------------------------------------------------------------- Phone: +31-6-41278122, PGP-key: 1F28D8AE, www.vanheusden.com |
From: Jason H. <jas...@gm...> - 2009-07-06 03:52:33
|
I'm sorry I took so long to approve this message. It was "too big", so I assumed it was another commit touching several files rather than questions to me. Pairing bias can occur because of clients being in sync with each other. Developer A could be running bots A1 and A2, and developer B running bots B1and B2. If they're in sync, A1 could always be offline when B1 is online. The server will never be able to pair those bots against each other. Even a less extreme case of A1 being online 70% of the time as B1 (and 30% of B2) is enough of a bias to be noticable in the summary statistics. Sent from my iPhone On Jun 23, 2009, at 8:14 AM, Christian Nentwich <chr...@mo... > wrote: > Hi Jason, > > I agree with the number of games for one engine. I just did not have > time to do this in this release. I'd probably add a secondary switch > in the common section that says "shut down engines after each has > played its games". > > As for the bias in the pairings, that had not occurred to me. I > would have thought that (given a reasonable number of players), it > is the server's allocation algorithm's problem to eliminate bias as > far as possible? I'd have no problem supporting both mechanisms, > with a switch, in the future. > > Where does the bias come from? I can imagine this.. Suppose I have > two engines X, Y. Suppose X plays engine Z ten times, wins every > time and as a result Z is rated down significantly. It may then > never be selected against engine Y, even though engine Y might lose > every time? > > Is this argument valid given a large enough number of games? > > Christian > > > > On 23/06/2009 13:00, Jason House wrote: >> >> 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: >> >> |
From: <cne...@us...> - 2009-07-01 19:04:55
|
Revision: 43 http://cgos.svn.sourceforge.net/cgos/?rev=43&view=rev Author: cnentwich Date: 2009-07-01 19:04:49 +0000 (Wed, 01 Jul 2009) Log Message: ----------- (Hopefully) fixed the bug where engines playing themselves under similar user names get the wrong name reported - to be tested Applied Brian Sheppard's patch for the new cgos-opponent_rating command Added a section to the documentation about how engines using this client should manage the whole-game lifecycle Modified Paths: -------------- trunk/client-python/doc/index.html trunk/client-python/src/cgosclient.py trunk/client-python/src/gtpengine.py Added Paths: ----------- trunk/client-python/doc/contributors.html Added: trunk/client-python/doc/contributors.html =================================================================== --- trunk/client-python/doc/contributors.html (rev 0) +++ trunk/client-python/doc/contributors.html 2009-07-01 19:04:49 UTC (rev 43) @@ -0,0 +1,23 @@ +<html> + <head> + <title>Python CGOS Client - Contributors</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 - Contributors</h1> + + <p> + <b>Christian Nentwich:</b> Initial implementation. Bulk of server communication and GTP code. + + <p> + <b>Brian Sheppard:</b> <code>cgos-opponent_rating</code>; improvements to game lifecycle logic + </body> +</html> \ No newline at end of file Modified: trunk/client-python/doc/index.html =================================================================== --- trunk/client-python/doc/index.html 2009-06-24 08:58:10 UTC (rev 42) +++ trunk/client-python/doc/index.html 2009-07-01 19:04:49 UTC (rev 43) @@ -20,8 +20,9 @@ <h2>Information</h2> - 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>. + This is version <b>0.3.0</b>. This program is ©2009 Christian Nentwich and <a href="contributors.html">contributors</a> + 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>. @@ -115,6 +116,19 @@ make sure it does not get up anymore </ul> + <h3>Command Ordering and Game Control</h3> + + It can be difficult for a GTP engine to decide when a game has started or a game is over. With the Python CGOS client, + you can infer the following: + <ul> + <li><code>clear_board</code> will be the decisive command indicating that the game has started. All time setup and board + setup happens before it. There <i>may</i> be a list of <code>play</code> commands sent in rapid succession after + <code>clear_board</code>, but only if the connection or server previously crashed and the game needs to be caught up. In + principle, you can trigger any pondering code after <code>clear_board</code>. + <li><code>cgos-gameover</code>, described in the next section, definitively ends the game. You may deallocate + resources in response to this command. + </ul> + <h2 id="ext">GTP Extensions</h2> The following GTP extensions are available. If your engine records its own logs, or writes its own @@ -127,10 +141,16 @@ </tr> <tr> <th>cgos-opponent_name</th> - <td>Between boardsize and first move</td> + <td>Between boardsize and clear_board</td> <td>Gives the name of the opponent engine (the CGOS login name)</td> </tr> <tr> + <th>cgos-opponent_rating</th> + <td>Between boardsize and clear_board</td> + <td>Gives the current CGOS rating of the opponent engine. This will be a + number or a number followed by a question mark</td> + </tr> + <tr> <th>cgos-gameover</th> <td>After two passes, resignation or illegal move</td> <td> Modified: trunk/client-python/src/cgosclient.py =================================================================== --- trunk/client-python/src/cgosclient.py 2009-06-24 08:58:10 UTC (rev 42) +++ trunk/client-python/src/cgosclient.py 2009-07-01 19:04:49 UTC (rev 43) @@ -1,5 +1,6 @@ ''' -Copyright (C) 2009 Christian Nentwich +Copyright for initial code (C) 2009 Christian Nentwich. See contributors +file. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -46,7 +47,7 @@ See _handlerloop for the command dispatcher, mainloop for the reconnect/play loop. ''' - CLIENT_ID = "e1 cgosPython 0.3.0 beta" + CLIENT_ID = "e1 cgosPython 0.3.1 beta" __TIME_CHECKPOINT_FREQUENCY = 60 * 30 ''' How often to output stats, etc., in seconds ''' @@ -226,7 +227,7 @@ engineRank = programBRank self._engineColour = "black" - if self._username in programA: + if self._username == programA: opponent = programB opponentRank = programBRank engineRank = programARank @@ -243,9 +244,10 @@ self._movecount = 0 self._engine.notifyBoardSize(boardSize) self._engine.notifyKomi(komi) - self._engine.notifyClearBoard() self._engine.notifyTimeSettings(gameTimeMSec) self._engine.notifyCGOSOpponentName(opponent) + self._engine.notifyCGOSOpponentRating(opponentRank) + self._engine.notifyClearBoard() if self._observer is not None: self._observer.notifyBoardSize(boardSize) Modified: trunk/client-python/src/gtpengine.py =================================================================== --- trunk/client-python/src/gtpengine.py 2009-06-24 08:58:10 UTC (rev 42) +++ trunk/client-python/src/gtpengine.py 2009-07-01 19:04:49 UTC (rev 43) @@ -208,6 +208,14 @@ if "cgos-opponent_name" in self._supportedCommands: self._sendNoResponseCommand("cgos-opponent_name " + name) + def notifyCGOSOpponentRating(self, rating): + ''' + Send cgos-opponent_rating to engine. + ''' + if "cgos-opponent_rating" in self._supportedCommands: + self._sendNoResponseCommand("cgos-opponent_rating " + rating) + + def notifyCGOSGameover(self, result): ''' Sent cgos-game_over to engine. The calling function must format this This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cne...@us...> - 2009-06-24 08:58:44
|
Revision: 42 http://cgos.svn.sourceforge.net/cgos/?rev=42&view=rev Author: cnentwich Date: 2009-06-24 08:58:10 +0000 (Wed, 24 Jun 2009) Log Message: ----------- Added first implementation of venue handling, and test mode parameter. Also added a new tool, showvenues.py, that will connect to the CGOS 2 and show all available venues. Warning: this code was written BLIND and likely won't work. Modified Paths: -------------- branches/client-python-v2/.pydevproject branches/client-python-v2/sample.cfg branches/client-python-v2/src/cgosclient.py branches/client-python-v2/src/common.py branches/client-python-v2/src/config.py branches/client-python-v2/testdata/local.cfg Added Paths: ----------- branches/client-python-v2/src/showvenues.py Modified: branches/client-python-v2/.pydevproject =================================================================== --- branches/client-python-v2/.pydevproject 2009-06-24 07:53:59 UTC (rev 41) +++ branches/client-python-v2/.pydevproject 2009-06-24 08:58:10 UTC (rev 42) @@ -3,7 +3,8 @@ <pydev_project> <pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH"> -<path>/cgos-python/src</path> +<path>/cgos-python-v2/src</path> +<path>/cgos-python-v2/testsrc</path> </pydev_pathproperty> <pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.5</pydev_property> <pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property> Modified: branches/client-python-v2/sample.cfg =================================================================== --- branches/client-python-v2/sample.cfg 2009-06-24 07:53:59 UTC (rev 41) +++ branches/client-python-v2/sample.cfg 2009-06-24 08:58:10 UTC (rev 42) @@ -2,15 +2,26 @@ Common: KillFile = kill.txt + # If you uncomment the following line, the engines will connect to CGOS + # in test mode. That will pair them with a test player only, and keep them unrated + + # TestMode = true + + # 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 - ServerPort = 1919 + ServerHost = cgos.boardspace.net + ServerPort = 6867 ServerUser = myuser ServerPassword = mypw + + # Server venue to play in - mandatory. Use "python showvenues.py" to display available venues, + # and paste here + Venue = 9-300-7.5 # Play 5 games before switching to next NumberOfGames = 5 @@ -18,16 +29,18 @@ 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 + ServerHost = cgos.boardspace.net + ServerPort = 6867 ServerUser = myuser2 ServerPassword = mypw2 - - # Play 5 games before switching to next + + Venue = 9-300-7.5 + NumberOfGames = 5 SGFDirectory = sgf\Engine2 Modified: branches/client-python-v2/src/cgosclient.py =================================================================== --- branches/client-python-v2/src/cgosclient.py 2009-06-24 07:53:59 UTC (rev 41) +++ branches/client-python-v2/src/cgosclient.py 2009-06-24 08:58:10 UTC (rev 42) @@ -26,6 +26,7 @@ from gtpengine import * from sgf import * from config import * +from common import Venue class CGOSClientError(Exception): def __init__(self, msg): @@ -45,13 +46,17 @@ See _handlerloop for the command dispatcher, mainloop for the reconnect/play loop. ''' + + CLIENT_VERSION = "cgosPython 2.0.0 Alpha" - CLIENT_ID = "e1 cgosPython 0.3.0 beta" + PROTOCOL_RESPONSE = "e2 " + CLIENT_VERSION + TEST_PROTOCOL_RESPONSE = "t2 " + CLIENT_VERSION + __TIME_CHECKPOINT_FREQUENCY = 60 * 30 ''' How often to output stats, etc., in seconds ''' - def __init__(self, engineConfigurationSections, killFileName = "kill.txt"): + def __init__(self, engineConfigurationSections, killFileName = "kill.txt", testMode = False): ''' Initialise the client, without connecting anything yet - engineConfigurationSections is a list of ConfigSection objects containing @@ -59,6 +64,7 @@ - killFileName is the file to look for when deciding whether to shut down ''' self._engineConfigs = engineConfigurationSections + self._testMode = testMode 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 @@ -74,6 +80,7 @@ self._port = None # Server port (engine dependent) self._username = None # User name (engine dependent) self._password = None # Password (engine dependent) + self._venue = None # Current server venue (will be a Venue object) self._gameInProgress = False # Currently between setup and gameover? self._engineColour = "black" # Which colour is the local engine playing in a game? @@ -173,7 +180,11 @@ def _handle_protocol(self, parameters): ''' Event handler: "protocol" command. No parameters. ''' - self._respond(CGOSClient.CLIENT_ID) + if self._testMode: + self._respond(CGOSClient.TEST_PROTOCOL_RESPONSE) + self.logger.warning("Client connecting engine in test mode") + else: + self._respond(CGOSClient.PROTOCOL_RESPONSE) def _handle_username(self, parameters): ''' Event handler: "username" command. No parameters. ''' @@ -394,6 +405,21 @@ self._checkTimeCheckpoint() + def _handle_venues(self, parameters): + ''' + Handle the venues message by responding with the preferred venue for the + current engine. If the venue is unavailable on the server, this will shut down + the client with an error. + ''' + self.logger.info("Available server venues: " + (" ".join(parameters))) + + if not(self._venue.originalString() in parameters): + raise CGOSClientError("Requested engine venue '" + self._venue.originalString() + "' is not available") + + self.logger.info("Requesting " + self._venue.formattedString() + "(" + self._venue.originalString() + ")") + + self._respond(self._venue.originalString()) + def _handlerloop(self): ''' Read from CGOS socket and dispatch to handlers. This uses reflection on the @@ -406,7 +432,7 @@ client error occurs. Calling methods will have to handle this. ''' while not(self._finished) and not(self._engineSwitching): - line = self._socketfile.readline() + line = self._socketfile.read() line = line.strip() self.logger.debug("Server sent: " + line) @@ -564,6 +590,7 @@ self._port = int(newEngineConfig.getValue("ServerPort")) self._username = newEngineConfig.getValue("ServerUser") self._password = newEngineConfig.getValue("ServerPassword") + self._venue = Venue(newEngineConfig.getValue("Venue")) self._engineSwitching = True @@ -585,7 +612,7 @@ def main(argv): - print "Python CGOS client. " + CGOSClient.CLIENT_ID + " (c)2009 Christian Nentwich" + print "Python CGOS client. " + CGOSClient.CLIENT_VERSION + " (c)2009 Christian Nentwich" if len(argv) != 1: print "Usage: python cgosclient.py config.cfg" return 1 @@ -593,9 +620,12 @@ # Here we go. Grab the configuration file config = ConfigFile() config.load(argv[0]) - + + testMode = config.getCommonSection().hasValue("TestMode") and \ + config.getCommonSection().getValue("TestMode") == "true" + engineConfigs = config.getEngineSections() - client = CGOSClient(engineConfigs, config.getCommonSection().getValue("KillFile")) + client = CGOSClient(engineConfigs, config.getCommonSection().getValue("KillFile"), testMode) # Launch observer (e.g. GoGUI) if any observerConfig = config.getObserverSection() Modified: branches/client-python-v2/src/common.py =================================================================== --- branches/client-python-v2/src/common.py 2009-06-24 07:53:59 UTC (rev 41) +++ branches/client-python-v2/src/common.py 2009-06-24 08:58:10 UTC (rev 42) @@ -18,4 +18,39 @@ class Colour(object): EMPTY = 0 BLACK = 1 - WHITE = 2 \ No newline at end of file + WHITE = 2 + + + +class Venue(object): + ''' A CGOS venue. Parses strings in the format size-timeInSeconds-komi ''' + + def __init__(self, cgosVenueString): + self._string = cgosVenueString + + splitString = cgosVenueString.split("-") + if len(splitString) != 3: + raise ValueError("Could not parse CGOS venue string: '" + cgosVenueString + "'") + + try: + self._size = int(splitString[0]) + self._seconds = int(splitString[1]) + self._komi = float(splitString[2]) + except ValueError: + raise ValueError("Could not parse CGOS venue string: '" + cgosVenueString + "'") + + def size(self): + return self._size + + def seconds(self): + return self._seconds + + def komi(self): + return self._komi + + def originalString(self): + return self._string + + def formattedString(self): + return str(self.size()) + "x" + str(self.size()) + ", time " + str(self.seconds()/60) + ":" + str(self.seconds()%60) + \ + ", komi " + self.komi() Modified: branches/client-python-v2/src/config.py =================================================================== --- branches/client-python-v2/src/config.py 2009-06-24 07:53:59 UTC (rev 41) +++ branches/client-python-v2/src/config.py 2009-06-24 08:58:10 UTC (rev 42) @@ -17,6 +17,7 @@ import sys, traceback import os.path +from common import Venue class ConfigSection(object): ''' @@ -76,6 +77,9 @@ for line in lines: line = line.strip() + if '#' in line: + line = line[:line.find('#')] + if len(line) == 0 or line[0] == '#': continue if line[-1] == ':': @@ -108,9 +112,9 @@ if section.name() == ConfigFile.ENGINE_SECTION: hasEngine = True - for req in ["Name", "CommandLine", "ServerHost", "ServerPort", "ServerUser", "ServerPassword", "NumberOfGames"]: + for req in ["Name", "CommandLine", "ServerHost", "ServerPort", "ServerUser", "ServerPassword", "NumberOfGames", "Venue"]: if not(section.hasValue(req)): - raise Exception("Mandatory engine attribute missing: " + req) + raise Exception("Configuration error. Mandatory engine attribute missing: " + req) try: if int(section.getValue("NumberOfGames")) <= 0: @@ -118,8 +122,12 @@ except ValueError: raise Exception("Configuration attribute 'NumberOfGames' must be an integer") + try: + Venue(section.getValue("Venue")) + except ValueError: + raise Exception("Engine attribute 'Venue' is in the wrong format, '" + section.getValue("Venue") + \ + "'. Must be size-timeInSeconds-komi, e.g. 9-300-7.5") - if section.hasValue("SGFDirectory"): dir = section.getValue("SGFDirectory") if not(os.path.exists(dir)) or not(os.path.isdir(dir)): Added: branches/client-python-v2/src/showvenues.py =================================================================== --- branches/client-python-v2/src/showvenues.py (rev 0) +++ branches/client-python-v2/src/showvenues.py 2009-06-24 08:58:10 UTC (rev 42) @@ -0,0 +1,97 @@ +''' +Copyright (C) 2009 Christian Nentwich + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. +''' + +from cgosclient import CGOSClient +from common import Venue +import traceback, sys, socket + +def main(argv): + if len(argv) != 2: + print "Usage: python showvenues.py server port" + print + print " Try 'python showvenues.py cgos.boardspace.net 6867'" + print + print " Up to date servers and ports are at http://cgos.boardspace.net" + + return 1 + + print CGOSClient.CLIENT_VERSION + " (c)2009 Christian Nentwich" + print + + host = argv[0] + try: + port = int(argv[1]) + except: + print "Error: server port must be a number" + return 1 + + print "Connecting to CGOS at " + host + ":" + str(port) + print + + try: + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.connect((host, port)) + + sockfile = sock.makefile() + + msg = sockfile.read() + if msg != "protocol": + print "Expected protocol message from server. Got: " + msg + return 1 + + sockfile.send(CGOSClient.PROTOCOL_RESPONSE) + sockfile.flush() + + msg = sockfile.read() + if not(msg.startswith("venues")): + print "Expected venues response. Got: " + msg + return 1 + + venues = msg.split(None) + if len(venues) == 1: + print "No venues found in server string: " + msg + return 1 + + venues = map(lambda x : Venue(x), venues[1:]) + + print "Available venues:" + for venue in venues: + print " " + venue.formattedString() + + print + print "Use the venue identifier on the left in your engine configuration." + + except Exception, e: + print "Error: " + str(e) + return 1 + + try: + sockfile.send("quit") + sockfile.flush() + sock.close() + except: + pass + + + return 0 + + +if __name__ == "__main__": + try: + main(sys.argv[1:]) + except Exception, e: + traceback.print_exc(file=sys.stderr) Modified: branches/client-python-v2/testdata/local.cfg =================================================================== --- branches/client-python-v2/testdata/local.cfg 2009-06-24 07:53:59 UTC (rev 41) +++ branches/client-python-v2/testdata/local.cfg 2009-06-24 08:58:10 UTC (rev 42) @@ -11,6 +11,7 @@ ServerPort = 1919 ServerUser = localuser ServerPassword = localpw + Venue = 9-300-7.5 NumberOfGames = 1 @@ -24,7 +25,8 @@ ServerPort = 1919 ServerUser = localuser2 ServerPassword = localpw - + Venue = 9-300-7.5 + NumberOfGames = 2 SGFDirectory = ..\testdata\sgfB This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cne...@us...> - 2009-06-24 07:54:15
|
Revision: 41 http://cgos.svn.sourceforge.net/cgos/?rev=41&view=rev Author: cnentwich Date: 2009-06-24 07:53:59 +0000 (Wed, 24 Jun 2009) Log Message: ----------- Created a developer branch of the python client for the new CGOS version Added Paths: ----------- branches/client-python-v2/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cne...@us...> - 2009-06-24 07:45:39
|
Revision: 40 http://cgos.svn.sourceforge.net/cgos/?rev=40&view=rev Author: cnentwich Date: 2009-06-24 07:45:38 +0000 (Wed, 24 Jun 2009) Log Message: ----------- Tagged 0.3.0 release Added Paths: ----------- tags/client-python-0.3.0/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: Christian N. <chr...@mo...> - 2009-06-23 14:54:11
|
Hi Jason, I agree with the number of games for one engine. I just did not have time to do this in this release. I'd probably add a secondary switch in the common section that says "shut down engines after each has played its games". As for the bias in the pairings, that had not occurred to me. I would have thought that (given a reasonable number of players), it is the server's allocation algorithm's problem to eliminate bias as far as possible? I'd have no problem supporting both mechanisms, with a switch, in the future. Where does the bias come from? I can imagine this.. Suppose I have two engines X, Y. Suppose X plays engine Z ten times, wins every time and as a result Z is rated down significantly. It may then never be selected against engine Y, even though engine Y might lose every time? Is this argument valid given a large enough number of games? Christian On 23/06/2009 13:00, Jason House wrote: > 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 >> > > ------------------------------------------------------------------------------ > 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 > > |
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 |
From: <cne...@us...> - 2009-06-23 11:43:46
|
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. |
From: <cne...@us...> - 2009-06-17 15:00:37
|
Revision: 38 http://cgos.svn.sourceforge.net/cgos/?rev=38&view=rev Author: cnentwich Date: 2009-06-17 15:00:32 +0000 (Wed, 17 Jun 2009) Log Message: ----------- Fixed nasty socket bug introduced by writing directly to socket instead of file. client now playing stable again, with multiple engines. Modified Paths: -------------- trunk/client-python/src/cgosclient.py Modified: trunk/client-python/src/cgosclient.py =================================================================== --- trunk/client-python/src/cgosclient.py 2009-06-17 08:53:00 UTC (rev 37) +++ trunk/client-python/src/cgosclient.py 2009-06-17 15:00:32 UTC (rev 38) @@ -162,7 +162,8 @@ def _respond(self, message): if self._socket is not None: self.logger.debug("Responding: " + message) - self._socket.sendall(message) + self._socketfile.write(message) + self._socketfile.flush() def _handle_info(self, parameters): ''' Event handler: "info". Ignored. ''' This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cne...@us...> - 2009-06-17 08:53:02
|
Revision: 37 http://cgos.svn.sourceforge.net/cgos/?rev=37&view=rev Author: cnentwich Date: 2009-06-17 08:53:00 +0000 (Wed, 17 Jun 2009) Log Message: ----------- Added engine switching code Modified Paths: -------------- trunk/client-python/readme.txt trunk/client-python/src/cgosclient.py trunk/client-python/src/config.py trunk/client-python/src/gtpengine.py trunk/client-python/testdata/local.cfg Modified: trunk/client-python/readme.txt =================================================================== --- trunk/client-python/readme.txt 2009-06-16 09:24:37 UTC (rev 36) +++ trunk/client-python/readme.txt 2009-06-17 08:53:00 UTC (rev 37) @@ -17,4 +17,8 @@ Refer to doc\index.html to get started. - \ No newline at end of file + + + + NOTE: This directory is an eclipse project. If you have PyDev installed, + you can check this out directly as a standalone project. \ No newline at end of file Modified: trunk/client-python/src/cgosclient.py =================================================================== --- trunk/client-python/src/cgosclient.py 2009-06-16 09:24:37 UTC (rev 36) +++ trunk/client-python/src/cgosclient.py 2009-06-17 08:53:00 UTC (rev 37) @@ -46,14 +46,34 @@ See _handlerloop for the command dispatcher, mainloop for the reconnect/play loop. ''' - CLIENT_ID = "e1 cgosPython 0.2.1 beta" + CLIENT_ID = "e1 cgosPython 0.3.0 beta" __TIME_CHECKPOINT_FREQUENCY = 60 * 30 ''' How often to output stats, etc., in seconds ''' - def __init__(self, server, port, username, password, engine, killFileName = "kill.txt"): + def __init__(self, engineConfigurationSections, killFileName = "kill.txt"): + ''' + Initialise the client, without connecting anything yet + - engineConfigurationSections is a list of ConfigSection objects containing + engine parameters. An engine will be chosen from there. + - killFileName is the file to look for when deciding whether to shut down + ''' + self._engineConfigs = engineConfigurationSections + self._engine = None # Currently playing engine + self._currentEngineIndex = -1 # Index in configuration sections of current engine + + self._killFileName = killFileName # File that will trigger shutdown + self._finished = False # Should the main loop quit + self._engineSwitching = False # Should the handler loop quit to allow an engine switch + + self._socketfile = None + self._server = None # Server host name (engine dependent) + self._port = None # Server port (engine dependent) + self._username = None # User name (engine dependent) + self._password = None # Password (engine dependent) + self._gameInProgress = False # Currently between setup and gameover? self._engineColour = "black" # Which colour is the local engine playing in a game? @@ -63,14 +83,9 @@ self._timeStarted = time.localtime() # Will not change self._timeCheckPoint = time.localtime() # Last time checkpoint for outputting stats, mail, etc. - self._server = server # Host name - self._port = port # Host port - self._username = username # User name - self._password = password # Password - self._engine = engine # Engine - already connected self._observer = None # GTP observer, if any - already connected self._sgfDirectory = None # Directory to store SGF. Leave None to disable. - self._killFileName = killFileName # File that will trigger shutdown + # movecount is only used for periodically outputting information messages self._movecount = 0 @@ -112,12 +127,43 @@ self._finished = False self.logger.info("Connected") + + def disconnect(self): + self.logger.info("Disconnecting") + if self._socketfile is not None: + self._socketfile.close() + self._socket.close() - def _respond(self, message): - self.logger.debug("Responding: " + message) - self._socketfile.write(message) - self._socketfile.flush() + 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: + self.logger.debug("Responding: " + message) + self._socket.sendall(message) + def _handle_info(self, parameters): ''' Event handler: "info". Ignored. ''' self.logger.info("Server info: " + (" ".join(parameters))) @@ -185,7 +231,8 @@ self._engineColour = "white" self.logger.info("Starting game against " + opponent + "("+opponentRank+ - "). Local engine (rated " + engineRank+ ") is playing " + self._engineColour + ".") + "). Local engine (\"" + self._engine.getName() + "\", rated " + + engineRank+ ") is playing " + self._engineColour + ".") if len(parameters) > 6: self.logger.info("This is a restart. Catching up " + str((len(parameters)-6) / 2) + " moves") @@ -259,7 +306,7 @@ self._movecount += 1 if self._movecount % 10 == 0: - self.logger.info("Engine playing " + self._engineColour+". " + + self.logger.info("Engine \"" + self._engine.getName() + "\" playing " + self._engineColour+". " + str(self._movecount) + " moves generated. " + "Time left: " + str(int(parameters[1]) / 1000) + " sec") @@ -339,8 +386,10 @@ # Have to check kill file here too - so we don't tell the server we are ready # before quitting self._checkKillFile() - if not(self._finished): self._respond("ready") + if not(self._finished): self.pickNewEngine() + if not(self._finished) and not(self._engineSwitching): self._respond("ready") + self._checkTimeCheckpoint() def _handlerloop(self): @@ -354,7 +403,7 @@ This loop will exit with an exception if the socket fails or an engine or client error occurs. Calling methods will have to handle this. ''' - while not(self._finished): + while not(self._finished) and not(self._engineSwitching): line = self._socketfile.readline() line = line.strip() @@ -389,7 +438,11 @@ raise if not(self._gameInProgress): self._checkKillFile() - + + if self._engineSwitching: + self._respond("quit") + self.disconnect() + def _checkKillFile(self): ''' Check if the kill file exists and set _finished to true if yes. @@ -415,9 +468,12 @@ duration = currentTime - time.mktime(self._timeStarted) self.logger.info("Client up for " + str(int(duration)/3600) + " hours, " + str((int(duration)/60)%60) + " mins, " + str(int(duration)%60) + " seconds. " + - "Local engine won " + str(self._wonGames) + " games, lost " + + "Local engines won " + str(self._wonGames) + " games, lost " + str(self._lostGames) + ".") + def isConnected(self): + return self._server is not None + def mainloop(self): ''' Main loop - keep trying to connect to CGOS, with reasonable wait times. Once connected, @@ -428,7 +484,10 @@ an orderly shutdown is performed. ''' self._finished = False + while not(self._finished): + self._engineSwitching = False + connected = False retries = 1 while not(connected): @@ -444,7 +503,7 @@ self._handlerloop() except socket.error: self.logger.error("Socket error. CGOS connection lost.") - self.shutdown() + self.disconnect() except CGOSClientError, e: self.logger.error(str(e)) return @@ -455,6 +514,48 @@ self._respond("quit") if os.path.exists(self._killFileName): os.remove(self._killFileName) + + def pickNewEngine(self): + ''' + 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._engine is not None: + self._engine.shutdown() + + newEngineConfig = self._engineConfigs[newEngineIndex] + + self.logger.info("Chose engine " + str(newEngineIndex+1) + " (\"" + newEngineConfig.getValue("Name") + + "\") as next player. Switching and re-connecting.") + + try: + newEngine = EngineConnector(newEngineConfig.getValue("CommandLine"), + newEngineConfig.getValue("Name"), + logger="EngineConnector"+str(newEngineIndex)) + 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") + else: + self._sgfDirectory = None + + self._server = newEngineConfig.getValue("ServerHost") + self._port = int(newEngineConfig.getValue("ServerPort")) + self._username = newEngineConfig.getValue("ServerUser") + self._password = newEngineConfig.getValue("ServerPassword") + + self._engineSwitching = True + def setObserver(self, engine): self._observer = engine @@ -465,10 +566,13 @@ def shutdown(self): self.logger.info("Shutting down CGOS connection") - self._socketfile.close() - self._socket.close() + if self._socketfile is not None: + self._socketfile.close() + self._socket.close() + if self._engine is not None: self._engine.shutdown() + def main(argv): print "Python CGOS client. " + CGOSClient.CLIENT_ID + " (c)2009 Christian Nentwich" if len(argv) != 1: @@ -479,41 +583,23 @@ config = ConfigFile() config.load(argv[0]) - engineConfig = config.getEngineSections() - if len(engineConfig) != 1: - print "Exactly one engine is required by this version" - return 1 + engineConfigs = config.getEngineSections() + client = CGOSClient(engineConfigs, config.getCommonSection().getValue("KillFile")) - # Initialize the engine - engine = EngineConnector(engineConfig[0].getValue("CommandLine")) - engine.connect() - - - # Initialize server (without connecting) - client = CGOSClient(engineConfig[0].getValue("ServerHost"), - int(engineConfig[0].getValue("ServerPort")), - engineConfig[0].getValue("ServerUser"), - engineConfig[0].getValue("ServerPassword"), - engine, - config.getCommonSection().getValue("KillFile")) - - if engineConfig[0].hasValue("SGFDirectory"): - client.setSGFDirectory(engineConfig[0].getValue("SGFDirectory")) - # Launch observer (e.g. GoGUI) if any observerConfig = config.getObserverSection() observerEngine = None if observerConfig is not None: - observerEngine = EngineConnector(observerConfig.getValue("CommandLine"), logger="ObserverLogger", logfile="observer.log") + observerEngine = EngineConnector(observerConfig.getValue("CommandLine"), "Observer", logger="ObserverLogger", logfile="observer.log") observerEngine.connect(EngineConnector.MANDATORY_OBSERVE_COMMANDS) - client.setObserver(observerEngine) - + client.setObserver(observerEngine) + # And play until done try: + client.pickNewEngine() client.mainloop() finally: - engine.shutdown() client.shutdown() if observerEngine is not None: observerEngine.shutdown() Modified: trunk/client-python/src/config.py =================================================================== --- trunk/client-python/src/config.py 2009-06-16 09:24:37 UTC (rev 36) +++ trunk/client-python/src/config.py 2009-06-17 08:53:00 UTC (rev 37) @@ -97,26 +97,6 @@ result = filter(lambda x: x.name() == ConfigFile.OBSERVER_SECTION, self._sections) if len(result) > 0: return result[0] - def getServerHost(self): - for section in self._sections: - if section.name() == ConfigFile.SERVER_SECTION: - return section.getValue("Host") - - def getServerPort(self): - for section in self._sections: - if section.name() == ConfigFile.SERVER_SECTION: - return int(section.getValue("Port")) - - def getServerUser(self): - for section in self._sections: - if section.name() == ConfigFile.SERVER_SECTION: - return int(section.getValue("User")) - - def getServerPassword(self): - for section in self._sections: - if section.name() == ConfigFile.SERVER_SECTION: - return int(section.getValue("Password")) - def sections(self): return self._sections @@ -128,10 +108,18 @@ if section.name() == ConfigFile.ENGINE_SECTION: hasEngine = True - for req in ["CommandLine", "ServerHost", "ServerPort", "ServerUser", "ServerPassword", "Priority"]: + for req in ["Name", "CommandLine", "ServerHost", "ServerPort", "ServerUser", "ServerPassword", "Priority"]: 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") + except ValueError: + raise Exception("Configuration attribute 'Priority' must be an integer") + + if section.hasValue("SGFDirectory"): dir = section.getValue("SGFDirectory") if not(os.path.exists(dir)) or not(os.path.isdir(dir)): Modified: trunk/client-python/src/gtpengine.py =================================================================== --- trunk/client-python/src/gtpengine.py 2009-06-16 09:24:37 UTC (rev 36) +++ trunk/client-python/src/gtpengine.py 2009-06-17 08:53:00 UTC (rev 37) @@ -93,30 +93,32 @@ MANDATORY_OBSERVE_COMMANDS = ["boardsize", "clear_board", "komi", "play", "quit"] ''' Mandatory commands for an engine that can observe a game (like GoGUI). ''' - def __init__(self, programCommandLine, logger="EngineConnector", logfile = "engine.log"): + def __init__(self, programCommandLine, name, logger="EngineConnector", logfile = "engine.log"): self._programCommandLine = programCommandLine + self._name = name self._subprocess = None self._supportedCommands = [] self.logger = logging.getLogger(logger) self.logger.setLevel(logging.DEBUG) - self.handler = logging.FileHandler(logfile) - self.handler.setLevel(logging.DEBUG) + if len(self.logger.handlers) == 0: + self.handler = logging.FileHandler(logfile) + self.handler.setLevel(logging.DEBUG) - self.formatter = logging.Formatter("%(asctime)s - %(levelname)s: %(message)s") - self.handler.setFormatter(self.formatter) + self.formatter = logging.Formatter("%(asctime)s - %(levelname)s: %(message)s") + self.handler.setFormatter(self.formatter) - self.logger.addHandler(self.handler) + self.logger.addHandler(self.handler) - # Log info output to console - handler = logging.StreamHandler(sys.stdout) - handler.setLevel(logging.INFO) + # Log info output to console + handler = logging.StreamHandler(sys.stdout) + handler.setLevel(logging.INFO) - formatter = logging.Formatter("%(asctime)s: %(message)s") - handler.setFormatter(formatter) + formatter = logging.Formatter("%(asctime)s: %(message)s") + handler.setFormatter(formatter) - self.logger.addHandler(handler) + self.logger.addHandler(handler) def __del__(self): self.shutdown() @@ -133,6 +135,9 @@ time.sleep(1) self._findSupportedCommands(mandatoryCommands) + def getName(self): + return self._name + def shutdown(self): ''' Shut down the GTP engine using the 'quit' command, or kill it if it does not Modified: trunk/client-python/testdata/local.cfg =================================================================== --- trunk/client-python/testdata/local.cfg 2009-06-16 09:24:37 UTC (rev 36) +++ trunk/client-python/testdata/local.cfg 2009-06-17 08:53:00 UTC (rev 37) @@ -4,6 +4,7 @@ # Multiple engines GTPEngine: + Name = UCT Player CommandLine = C:\Users\nentwich\Documents\Visual Studio 2008\Projects\Owari\x64\Release\Main.exe --engine tree ServerHost = 127.0.0.1 @@ -11,10 +12,23 @@ ServerUser = localuser ServerPassword = localpw - Priority = 5 + Priority = 1 - SGFDirectory = ..\testdata + SGFDirectory = ..\testdata\sgfA +GTPEngine: + Name = Simple Random Play + CommandLine = C:\Users\nentwich\Documents\Visual Studio 2008\Projects\Owari\x64\Release\Main.exe --engine simple + + ServerHost = 127.0.0.1 + ServerPort = 1919 + ServerUser = localuser2 + ServerPassword = localpw + + Priority = 1 + + 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 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cne...@us...> - 2009-06-16 09:24:44
|
Revision: 36 http://cgos.svn.sourceforge.net/cgos/?rev=36&view=rev Author: cnentwich Date: 2009-06-16 09:24:37 +0000 (Tue, 16 Jun 2009) Log Message: ----------- Tagged python client 0.2.1 release Added Paths: ----------- tags/client-python-0.2.1/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cne...@us...> - 2009-06-16 09:22:47
|
Revision: 35 http://cgos.svn.sourceforge.net/cgos/?rev=35&view=rev Author: cnentwich Date: 2009-06-16 09:22:44 +0000 (Tue, 16 Jun 2009) Log Message: ----------- Added Paths: ----------- branches/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: Christian N. <chr...@mo...> - 2009-05-13 08:23:07
|
Hi all, first of all, thank you for the work you have been doing with CGOS. The last time I looked at computer go was in 2000, and the difference this is making is incredible. I started running a test program (owari) on CGOS recently, and like others, I locally persist the games as SGF. Googling around, it seems that others also would quite like to know who they are playing against. I seems Don looked at the problem - I found an old post on the GTP mailing list about reporting opponent names. I checked out the CGOS client source code, and got to this: set mvlist [lassign $s ignore gid boardsize komi timeLeft white black] set msg [eCmd $inout "boardsize $boardsize"] set msg [eCmd $inout "clear_board"] set msg [eCmd $inout "komi $komi"] Unfortunately, I've never used TCL, but I'd quite like to add: set msg [eCmd $inout "cgos-white_name $white"] set msg [eCmd $inout "cgos-black_name $black"] In the gameover section it's temping to add: set msg [eCmd $inout "cgos-game_over $res $err"] But, you guys must have thought all this through. Is this a good way of doing it? Any reason why you would not do something like that in the release package? Thanks! Christian |
From: <don...@us...> - 2008-08-09 22:54:43
|
Revision: 24 http://cgos.svn.sourceforge.net/cgos/?rev=24&view=rev Author: dondailey Date: 2008-08-09 22:54:39 +0000 (Sat, 09 Aug 2008) Log Message: ----------- Informational message sent every minute or so. Modified Paths: -------------- server/cgos.vfs/lib/app-cgos/cgos.tcl server/cgos.vfs/lib/sqlite3/pkgIndex.tcl Modified: server/cgos.vfs/lib/app-cgos/cgos.tcl =================================================================== --- server/cgos.vfs/lib/app-cgos/cgos.tcl 2008-07-31 17:30:03 UTC (rev 23) +++ server/cgos.vfs/lib/app-cgos/cgos.tcl 2008-08-09 22:54:39 UTC (rev 24) @@ -1210,8 +1210,8 @@ global killFile global last_round_time global leeway + global last_est - set RANGE 500.0 ;# minmum elo range allowed # determine if all games are complete @@ -1259,23 +1259,24 @@ } - # let's turn off this annoying message for now. - # --------------------------------------------- - if { 0 } { - if { $count > 0 } { - - set est [estimateRoundTimeLeft] - set estMin [expr $est / 60] - set estSec [expr $est % 60] - - if { $est > 15 } { - infoMsg [format "Maximum time until next round: %02d:%02d" $estMin $estSec] - } - } + # send progress message + # --------------------- + if { 1 } { + + set est [estimateRoundTimeLeft] + set estMin [expr $est / 60] + set estSec [expr $est % 60] + + set curTime [clock seconds] + if { $curTime - $last_est > 60 } { + if { $est > 2 } { + infoMsg [format "Maximum time until next round: %02d:%02d" $estMin $estSec] + } + set last_est $curTime + } } - # should we begin another round of scheduling? # -------------------------------------------- if { $count == 0 } { @@ -1454,6 +1455,7 @@ } +set last_est [clock seconds] # Create our server on the expected port Modified: server/cgos.vfs/lib/sqlite3/pkgIndex.tcl =================================================================== --- server/cgos.vfs/lib/sqlite3/pkgIndex.tcl 2008-07-31 17:30:03 UTC (rev 23) +++ server/cgos.vfs/lib/sqlite3/pkgIndex.tcl 2008-08-09 22:54:39 UTC (rev 24) @@ -37,5 +37,4 @@ return "$plat-$mach" } -package ifneeded sqlite3 3.0 [list load [file join $dir tclsqlite3-[platform][info sharedlibextension]] tclsqlite3] -package ifneeded sqlite3 3.3.5 [list load [file join $dir tclsqlite3-[platform][info sharedlibextension]] tclsqlite3] +package ifneeded sqlite3 3.3.4 [list load [file join $dir tclsqlite3-[platform][info sharedlibextension]] tclsqlite3] This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: Jason H. <jas...@gm...> - 2008-08-01 14:50:25
|
Sent from my iPhone On Aug 1, 2008, at 10:34 AM, Don Dailey <drd...@co...> wrote: > On Fri, 2008-08-01 at 09:22 -0400, Jason House wrote: >> What if boardspace linked to sourceforge? That'd allow either of us >> to >> make releases. > > > On boardspace I have no power to create accounts or anything like > that, > it's Dave Dyers server and I can do only what he lets me. What I can > do is ask him for permission to put your public ssh key in the > authorized_keys file so that you can help administer the server if > that > is what you are willing to do. > > Explain to me what linking to sourceforge does so that I understand it > before I respond to the specific idea of "linking to sourceforge." http://www.sourceforge.com/project/showfiles.php?group_id=209690 > - Don > > > |
From: Don D. <drd...@co...> - 2008-08-01 14:34:56
|
On Fri, 2008-08-01 at 09:22 -0400, Jason House wrote: > What if boardspace linked to sourceforge? That'd allow either of us > to > make releases. On boardspace I have no power to create accounts or anything like that, it's Dave Dyers server and I can do only what he lets me. What I can do is ask him for permission to put your public ssh key in the authorized_keys file so that you can help administer the server if that is what you are willing to do. Explain to me what linking to sourceforge does so that I understand it before I respond to the specific idea of "linking to sourceforge." - Don |
From: Don D. <drd...@co...> - 2008-08-01 13:27:28
|
Hi Joshua, I updated the cgosGtp clients - go the web site and upload the latest version and you will get Jason's fixed version. - Don On Fri, 2008-08-01 at 02:05 -0400, Joshua Shriver wrote: > Anyone have a sample config file? I did some digging and this is the > best I've found. > > %section server > server cgos.boardspace.net > port 6867 > > %section player > name gnugo > password whatever > invoke gnugo --mode gtp --chinese-rules --capture-all-dead > priority 7 > > > but when I try this I get: > > Priority values do not allow any players on server. Aborting ... > > > -Josh > > ------------------------------------------------------------------------- > This SF.Net email is sponsored by the Moblin Your Move Developer's challenge > Build the coolest Linux based applications with Moblin SDK & win great prizes > Grand prize is a trip for two to an Open Source event anywhere in the world > http://moblin-contest.org/redirect.php?banner_id=100&url=/ > _______________________________________________ Cgos-developers mailing list Cgo...@li... https://lists.sourceforge.net/lists/listinfo/cgos-developers |
From: Jason H. <jas...@gm...> - 2008-08-01 13:22:54
|
On Aug 1, 2008, at 8:53 AM, Don Dailey <drd...@co...> wrote: > On Fri, 2008-08-01 at 08:23 -0400, Jason House wrote: >> cgosGtp had a command-line argument (might be -s) to generate a >> sample >> config file. >> >> >> That being said, I've found many bugs in cgosGtp. I took advantage of >> the sourceforge repository and fixed them. >> >> >> I did not do a release because Don needs to do it. I have access to >> and now how to do releases on the sourceforge site, but not for the >> boardspace site. >> >> >> As far as I can tell, I'm practically the only user of the >> sourceforge >> site I set up. For example, I made repeated requests to the 19x19 >> CGOS >> owner to join the site. I had wanted to set up support requests and >> get "CGOS is down" messages off the computer go mailing list. >> Eventually, I stopped worrying about it. > > However I noticed that there were a substantial number of downloads of > the software. I have been using it mainly as the subversion > repository > but I look at the feature request too - it's just that I don't spend > much time on the software. > > I'll see about making sure the client software is up to date on the > main > web site at boardspace. What if boardspace linked to sourceforge? That'd allow either of us to make releases. > > > - Don > > >> >> Sent from my iPhone >> >> On Aug 1, 2008, at 2:05 AM, "Joshua Shriver" <jsh...@gm...> >> wrote: >> >> >> >>> Anyone have a sample config file? I did some digging and this is the >>> best I've found. >>> >>> %section server >>> server cgos.boardspace.net >>> port 6867 >>> >>> %section player >>> name gnugo >>> password whatever >>> invoke gnugo --mode gtp --chinese-rules --capture-all-dead >>> priority 7 >>> >>> >>> but when I try this I get: >>> >>> Priority values do not allow any players on server. Aborting ... >>> >>> >>> -Josh >>> >>> --- >>> --- >>> ------------------------------------------------------------------- >>> This SF.Net email is sponsored by the Moblin Your Move Developer's >>> challenge >>> Build the coolest Linux based applications with Moblin SDK & win >>> great prizes >>> Grand prize is a trip for two to an Open Source event anywhere in >>> the world >>> http://moblin-contest.org/redirect.php?banner_id=100&url=/ >>> _______________________________________________ >>> Cgos-developers mailing list >>> Cgo...@li... >>> https://lists.sourceforge.net/lists/listinfo/cgos-developers >>> >> --- >> --- >> ------------------------------------------------------------------- >> This SF.Net email is sponsored by the Moblin Your Move Developer's >> challenge >> Build the coolest Linux based applications with Moblin SDK & win >> great prizes >> Grand prize is a trip for two to an Open Source event anywhere in >> the world >> http://moblin-contest.org/redirect.php?banner_id=100&url=/ >> _______________________________________________ Cgos-developers >> mailing list Cgo...@li... https://lists.sourceforge.net/lists/listinfo/cgos-developers > > > --- > ---------------------------------------------------------------------- > This SF.Net email is sponsored by the Moblin Your Move Developer's > challenge > Build the coolest Linux based applications with Moblin SDK & win > great prizes > Grand prize is a trip for two to an Open Source event anywhere in > the world > http://moblin-contest.org/redirect.php?banner_id=100&url=/ > _______________________________________________ > Cgos-developers mailing list > Cgo...@li... > https://lists.sourceforge.net/lists/listinfo/cgos-developers |
From: Don D. <drd...@co...> - 2008-08-01 12:53:58
|
On Fri, 2008-08-01 at 08:23 -0400, Jason House wrote: > cgosGtp had a command-line argument (might be -s) to generate a sample > config file. > > > That being said, I've found many bugs in cgosGtp. I took advantage of > the sourceforge repository and fixed them. > > > I did not do a release because Don needs to do it. I have access to > and now how to do releases on the sourceforge site, but not for the > boardspace site. > > > As far as I can tell, I'm practically the only user of the sourceforge > site I set up. For example, I made repeated requests to the 19x19 CGOS > owner to join the site. I had wanted to set up support requests and > get "CGOS is down" messages off the computer go mailing list. > Eventually, I stopped worrying about it. However I noticed that there were a substantial number of downloads of the software. I have been using it mainly as the subversion repository but I look at the feature request too - it's just that I don't spend much time on the software. I'll see about making sure the client software is up to date on the main web site at boardspace. - Don > > Sent from my iPhone > > On Aug 1, 2008, at 2:05 AM, "Joshua Shriver" <jsh...@gm...> > wrote: > > > > > Anyone have a sample config file? I did some digging and this is the > > best I've found. > > > > %section server > > server cgos.boardspace.net > > port 6867 > > > > %section player > > name gnugo > > password whatever > > invoke gnugo --mode gtp --chinese-rules --capture-all-dead > > priority 7 > > > > > > but when I try this I get: > > > > Priority values do not allow any players on server. Aborting ... > > > > > > -Josh > > > > ------------------------------------------------------------------------- > > This SF.Net email is sponsored by the Moblin Your Move Developer's > > challenge > > Build the coolest Linux based applications with Moblin SDK & win > > great prizes > > Grand prize is a trip for two to an Open Source event anywhere in > > the world > > http://moblin-contest.org/redirect.php?banner_id=100&url=/ > > _______________________________________________ > > Cgos-developers mailing list > > Cgo...@li... > > https://lists.sourceforge.net/lists/listinfo/cgos-developers > > > ------------------------------------------------------------------------- > This SF.Net email is sponsored by the Moblin Your Move Developer's challenge > Build the coolest Linux based applications with Moblin SDK & win great prizes > Grand prize is a trip for two to an Open Source event anywhere in the world > http://moblin-contest.org/redirect.php?banner_id=100&url=/ > _______________________________________________ Cgos-developers mailing list Cgo...@li... https://lists.sourceforge.net/lists/listinfo/cgos-developers |
From: Jason H. <jas...@gm...> - 2008-08-01 12:23:47
|
cgosGtp had a command-line argument (might be -s) to generate a sample config file. That being said, I've found many bugs in cgosGtp. I took advantage of the sourceforge repository and fixed them. I did not do a release because Don needs to do it. I have access to and now how to do releases on the sourceforge site, but not for the boardspace site. As far as I can tell, I'm practically the only user of the sourceforge site I set up. For example, I made repeated requests to the 19x19 CGOS owner to join the site. I had wanted to set up support requests and get "CGOS is down" messages off the computer go mailing list. Eventually, I stopped worrying about it. Sent from my iPhone On Aug 1, 2008, at 2:05 AM, "Joshua Shriver" <jsh...@gm...> wrote: > Anyone have a sample config file? I did some digging and this is the > best I've found. > > %section server > server cgos.boardspace.net > port 6867 > > %section player > name gnugo > password whatever > invoke gnugo --mode gtp --chinese-rules --capture-all-dead > priority 7 > > > but when I try this I get: > > Priority values do not allow any players on server. Aborting ... > > > -Josh > --- > ---------------------------------------------------------------------- > This SF.Net email is sponsored by the Moblin Your Move Developer's > challenge > Build the coolest Linux based applications with Moblin SDK & win > great prizes > Grand prize is a trip for two to an Open Source event anywhere in > the world > http://moblin-contest.org/redirect.php?banner_id=100&url=/ > _______________________________________________ > Cgos-developers mailing list > Cgo...@li... > https://lists.sourceforge.net/lists/listinfo/cgos-developers |
From: Joshua S. <jsh...@gm...> - 2008-08-01 06:05:34
|
Anyone have a sample config file? I did some digging and this is the best I've found. %section server server cgos.boardspace.net port 6867 %section player name gnugo password whatever invoke gnugo --mode gtp --chinese-rules --capture-all-dead priority 7 but when I try this I get: Priority values do not allow any players on server. Aborting ... -Josh |
From: <don...@us...> - 2008-07-31 17:30:06
|
Revision: 23 http://cgos.svn.sourceforge.net/cgos/?rev=23&view=rev Author: dondailey Date: 2008-07-31 17:30:03 +0000 (Thu, 31 Jul 2008) Log Message: ----------- webuild fails due to database locking. Hopefully this is solved by using "db transaction" Modified Paths: -------------- server/webuild.vfs/lib/app-webuild/webuild.tcl Modified: server/webuild.vfs/lib/app-webuild/webuild.tcl =================================================================== --- server/webuild.vfs/lib/app-webuild/webuild.tcl 2008-05-14 00:38:09 UTC (rev 22) +++ server/webuild.vfs/lib/app-webuild/webuild.tcl 2008-07-31 17:30:03 UTC (rev 23) @@ -54,8 +54,10 @@ puts "building for $who" - set wgms [cgi eval {SELECT gid, b, br, res FROM games WHERE w=$who ORDER BY gid} ] - set bgms [cgi eval {SELECT gid, w, wr, res FROM games WHERE b=$who ORDER BY gid} ] + db transaction { + set wgms [cgi eval {SELECT gid, b, br, res FROM games WHERE w=$who ORDER BY gid} ] + set bgms [cgi eval {SELECT gid, w, wr, res FROM games WHERE b=$who ORDER BY gid} ] + } foreach {gid opp r res} $wgms { if { [catch { incr count($opp) }] } { @@ -434,7 +436,9 @@ proc update_ratings {} { global rating - set nrk [db eval {SELECT name, rating, K from password}] + db transaction { + set nrk [db eval {SELECT name, rating, K from password}] + } foreach {nme rat k} $nrk { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |