Programmer's Introduction
GNU Go Internals
utils.c and printutils.c
Appendices
Indices
This is GNU Go 3.2, a Go program. Development versions of GNU Go may be
found at <http://www.gnu.org/software/gnugo/devel.html>. Contact
us at gnugo@gnu.org if you are interested in helping.
The challenge of Computer Go is not to beat the computer, but to program the computer.
In Computer Chess, strong programs are capable of playing at the highest level, even challenging such a player as Garry Kasparov. No Go program even as strong as amateur shodan exists. The challenge is to write such a program.
To be sure, existing Go programs are strong enough to be interesting as opponents, and the hope exists that some day soon a truly strong program can be written.
GNU Go is getting stronger. For one thing, we've paid a lot of attention to life and death. GNU Go 3.0 can consistently give GNU Go 2.6 a four stone handicap. In a four stone game against GNU Go 2.6, GNU Go 3.0 very often kills a group. GNU Go 3.2 is even stronger than 3.0.
Until now, Go programs have always been distributed as binaries only. The algorithms in these proprietary programs are secret. No-one but the programmer can examine them to admire or criticise. As a consequence, anyone who wished to work on a Go program usually had to start from scratch. This may be one reason that Go programs have not reached a higher level of play.
Unlike most Go programs, GNU Go is Free Software. Its algorithms and source code are open and documented. They are free for any one to inspect or enhance. We hope this freedom will give GNU Go's descendents a certain competetive advantage.
Here is GNU Go's Manual. There are doubtless inaccuracies. The ultimate documentation is in the commented source code itself.
The first three chapters of this manual are for the general user. Chapter 3 is the User's Guide. The rest of the book is for programmers, or persons curious about how GNU Go works. Chapter 4 is a general overview of the engine. Chapter 5 introduces various tools for looking into the GNU Go engine and finding out why it makes a certain move, and Chapters 6-7 form a general programmer's reference to the GNU Go API. The remaining chapters are more detailed explorations of different aspects of GNU Go's internals.
Copyright 1999, 2000, 2001, 2002 by the Free Software Foundation except as noted below.
All files are under the GNU General Public License (see GPL),
except gmp.c, gmp.h, gtp.c, gtp.h, the files
interface/html/* and win/makefile.win.
The files gtp.c and gtp.h are copyright the Free Software
Foundation. In the interests of promoting the Go Text Protocol these
two files are licensed under a less restrictive license than the GPL
and are free for unrestricted use (see GTP License).
The two files gmp.c and gmp.h were placed in the public domain
by William Shubert, their author, and are free for unrestricted use.
The files interface/html/* are not part of GNU Go but are a separate
program and are included in the distribution for the convenience of anyone
looking for a CGI interface to GNU Go. They were placed in the public domain
by their author, Douglas Ridgway, and are free for unrestricted use.
The files regression/games/golois/*sgf are copyright Tristan
Cazenave and are included with his permission.
The SGF files in regression/games/handtalk/ are copyright Jessie Annala
and are used with permission.
The SGF files in regression/games/mertin13x13/ are copyright Stefan
Mertin and are used with permission.
The remaining SGF files are either copyright by the FSF or are in the public domain.
GNU Go maintainers are Daniel Bump and Gunnar Farnebäck. GNU Go authors (in chronological order of contribution) are Man Li, Daniel Bump, David Denholm, Gunnar Farnebäck, Nils Lohner, Jerome Dumonteil, Tommy Thorn, Nicklas Ekstrand, Inge Wallin, Thomas Traber, Douglas Ridgway, Teun Burgers, Tanguy Urvoy, Thien-Thi Nguyen, Heikki Levanto, Mark Vytlacil, Adriaan van Kessel, Wolfgang Manner, Jens Yllman, Don Dailey, Måns Ullerstam, Arend Bayer and Trevor Morris.
We would like to thank Arthur Britto, Tim Hunt, Piotr Lakomy, Paul Leonard, Jean-Louis Martineau, Andreas Roever and Pierce Wetter for helpful correspondence. Thanks to everyone who stepped on a bug (and sent us a report)!
Thanks to Gary Boos, Peter Gucwa, Martijn van der Kooij, Michael Margolis, Trevor Morris, Måns Ullerstam, Don Wagner and Yin Zheng for help with Visual C++.
Thanks to Alan Crossman, Stephan Somogyi, Pierce Wetter and Mathias Wagner for help with Macintosh. And thanks to Marco Scheurer and Shigeru Mabuchi for helping us find various problems.
Thanks to Jessie Annala for the Handtalk games.
Special thanks to Ebba Berggren for creating our logo, based on a
design by Tanguy Urvoy and comments by Alan Crossman. The old
GNU Go logo was adapted from Jamal Hannah's typing GNU:
<http://www.gnu.org/graphics/atypinggnu.html>.
Both logos can be found in doc/newlogo.* and doc/oldlogo.*.
We would like to thank Stuart Cracraft, Richard Stallman and Man Lung Li for their interest in making this program a part of GNU, William Shubert for writing CGoban and gmp.c, Rene Grothmann for Jago and Erik van Riper and his collaborators for NNGS.
You can help make GNU Go the best Go program.
This is a task-list for anyone who is interested in helping with GNU Go. If you want to work on such a project you should correspond with us until we reach a common vision of how the feature will work!
A note about copyright. The Free Software Foundation has the copyright to GNU Go. For this reason, before any code can be accepted as a part of the official release of GNU Go, the Free Software Foundation will want you to sign a copyright assignment.
Of course you could work on a forked version without signing such a disclaimer. You can also distribute such a forked version of the program so long as you also distribute the source code to your modifications under the GPL (see GPL). But if you want your changes to the program to be incorporated into the version we distribute we need you to assign the copyright.
Please contact the GNU Go maintainers, Daniel Bump (bump@math.stanford.edu) and Gunnar Farnebäck (gf@isy.liu.se), to get more information and the papers to sign.
Below is a list of things YOU could work on. We are already working on some of these tasks, but don't let that stop you. Please contact us or the person assigned to task for further discussion.
These issues are of tactical nature, i.e. they concern some specific feature or the infrastructure of the engine. Some of these are quiet small, maybe doable in a day for an experienced GNU Go programmer. They might also be useful project to start with for a new project member. Some of them are bigger and demand a deeper knowledge of the engine internals. The issues are presented here in an approximate order of perceived difficulty.
These issues are strategic in nature. They will help us to improve the playing strength of the program and/or enhance certain aspects of it.
These are some ideas that have been floated on the mailing list. Some of them are down-to-earth, and some are just blue sky ramblings. They are presented here for inspiration.
You can get the most recent version of GNU Go ftp.gnu.org or a mirror
(see <http://www.gnu.org/order/ftp.html> for a list). You can read
about newer versions and get other information at
<http://www.gnu.org/software/gnugo/>.
Untar the sources, change to the directory gnugo-3.2. Now do:
./configure [OPTIONS] make
Several configure options will be explained in detail in the next section (see Configure Options). You do not need to set these unless you are dissatisfied with GNU Go's performance or wish to vary the experimental options.
As an example,
./configure --enable-experimental-semeai --enable-owl-threats
turns on two experimental options.
You have now made a binary called interface/gnugo. Now
(running as root) type
make install
to install gnugo in /usr/local/bin.
There are different methods of using GNU Go. You may run it from the command line by just typing:
gnugo
but it is nicer to run it using CGoban 1 (under X-Windows) or Jago (on any platform with a Java runtime environment).
You can get the most recent version of CGoban 1 from Bill Shubert's web site:
<http://www.igoweb.org/~wms/comp/cgoban/index.html> The CGoban version
number MUST be 1.9.1 at least or it won't work. CGoban 2 will not work.
See CGoban, for instructions on how to run GNU Go from Cgoban, or See Jago, for Jago.
There are three options which you should consider configuring, particularly if you are dissatisfied with GNU Go's performance.
By default, GNU Go makes a cache of 16 Megabytes in RAM for its internal use. The cache is used to store intermediate results during its analysis of the position.
Increasing the cache size will often give a modest speed improvement. If your system has lots of RAM, consider increasing the cache size. But if the cache is too large, swapping will occur, causing hard drive accesses and degrading performance. If your hard drive seems to be running excessively your cache may be too large. On GNU/Linux systems, you may detect swapping using the program 'top'. Use the 'f' command to toggle SWAP display.
You may override the size of the default cache at compile time by running one of:
./configure --enable-cache-size=n
to set the cache size to n megabytes. For example
./configure --enable-cache-size=32
creates a cache of size 32 megabytes. If you omit this, your default
cache size will be 8 MB. You must recompile and reinstall
GNU Go after reconfiguring it by running make and
make install.
You may override the compile-time defaults by running gnugo with the
option --cache-size n, where n is the size in
megabytes of the cache you want, and --level where n is the
level desired. We will discuss setting these parameters next in detail.
GNU Go can play at different levels. Up to level 10 is supported. At level 10 GNU Go is much more accurate but takes an average of about 1.6 times longer to play than at level 8.
The level can be set at run time using the --level option.
If you don't set this, the default level will be used. You
can set the default level with the configure option
--enable-level=n. For example
./configure --enable-level=9
sets the default level to 9. If you omit this parameter, the compiler sets the default level to 10. We recommend using level 10 unless you find it too slow. If you decide you want to change the default you may rerun configure and recompile the program.
There are two distinct implementations of the pattern matcher in GNU
Go. The DFA (Discrete Finite-state Automata) option was considered
experimental in GNU Go 3.0 but is now standard. You can disable it by
with the configure option ./configure --disable-dfa. The
option is harder to debug than the old matcher but significantly
faster (see DFA).
There are a number of experimental configure options. For example
you can ./configure --enable-experimental-semeai or
./configure --disable-experimental-semeai to turn
the experimental reading module on or off. If you want to
find out what experimental options were compiled into your
GNU Go binary you can run gnugo --options to find
out.
experimental-semeai. Use the new semeai module based on
the owl code.
experimental-influence. Use the experimental influence
module. Enabled by default.
experimental-connections. Use the experimental connection
analysis. Enabled by default.
alternate-connections. Use in conjunction with
experimental-connections. Uses an alternative implementation of
the experimental connection analysis. Enabled by default.
owl-threats. Compute owl threats. This makes GNU Go
stronger but can make the program slower. Enable this option if you have a
fast CPU.
GNU Go is being developed on Unix variants. GNU Go is easy to build and install on those platforms. GNU Go 3.2 has support for building on MS-DOS, Windows 3.x, Windows NT/2000 and Windows 95/98.
There are two approaches to building GNU Go on Microsoft platforms.
One benefit of this approach is that it is easier to participate in Gnu Go's development. These unix environments come for instance with the `diff' and `patch' programs necessary to generate and apply patches.
Another benefit of the unix environments is that development versions (which may be stronger than the latest stable version) can be built too. The supporting files for VC are not always actively worked on and consequently are often out of sync for development versions, so that VC will not build cleanly.
The rest of this section gives more details on the various ways to compile GNU go for Microsoft platforms.
On these platforms DJGPP can be used. GNU Go installation has been tested in a DOS-Box with long filenames on Windows 95/98. GNU Go compiles out-of-the box with the DJGPP port of GCC using the standard Unix build and install procedure.
Some URLs for DJGPP:
DJGPP home page: <http://www.delorie.com/djgpp/>
DJGPP ftp archive on simtel:
<ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2/>
<ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/>
Once you have a working DJGPP environment and you have downloaded the gnugo source available as gnugo-3.2.tar.gz you can build the executable as follows:
tar zxvf gnugo-3.2.tar.gz
cd gnugo-3.2
./configure
make
Optionally you can download glib for DJGPP to get a working version of snprintf.
On these platforms the Cygwin environment can be installed. Recent
versions of Cygwin install very easily with the setup program available
from the cygwin homepage. <<http://sourceware.cygnus.com/cygwin/>.
GNU Go compiles out-of-the box using the standard Unix build procedure
on the Cygwin environment. After installation of cygwin and fetching
gnugo-3.2.tar.gz you can type:
tar zxvf gnugo-3.2.tar.gz cd gnugo-3.2 ./configure make
The generated executable is not a stand-alone executable: it needs cygwin1.dll that comes with the Cygwin environment. cygwin1.dll contains the emulation layer for Unix.
Cygwin Home page: <http://sourceware.cygnus.com/cygwin/>
Optionally you can use glib to get a working version of snprintf. Glib builds out of the box on cygwin.
The Cygwin environment also comes with MinGW32. This generates an executable that relies only on Microsoft DLLs. This executable is thus completely comparable to a Visual C executable and easier to distribute than the Cygwin executable. To build on cygwin an executable suitable for the win32 platform type the following at your cygwin prompt:
tar zxvf gnugo-3.2.tar.gz cd gnugo-3.2 env CC='gcc -mno-cygwin' ./configure make
We assume that you do not want to change any configure options.
If you do, you should edit the file config.vc. Note that
when configure is run, this file is overwritten with
the contents of config.vcin, so you may also want to edit
config.vcin, though the instructions below do not have
you running configure.
Notes:
msdev gnugo.dsw /make "gnugo - Win32 Release"
FILE MKPAT OPTIONS INPUT FILES
conn.c mkpat -c conn conn.db
patterns.c mkpat -b pat patterns.db, patterns2.db
apatterns.c mkpat -X attpat attack.db
dpatterns.c mkpat defpat defense.db
influence.c mkpat -c influencepat influence.db
endgame.c mkpat -b endpat endgame.db
owl_attackpat.c mkpat -b owl_attackpat owl_attackpats.db
owl_vital_apat.c mkpat -b owl_vital_apat owl_vital_apats.db
owl_defendpat.c mkpat -b owl_defendpat owl_defendpats.db
fuseki9.c mkpat -b -f fuseki9 fuseki9.db
fuseki19.c mkpat -b -f fuseki19 fuseki19.db
josekidb.c mkpat -b joseki hoshi.db, komoku.db,
sansan.db, takamoku.db
mokuhazushi.db
GNU Go does not come with its own graphical user interface. The Java client jago can be used.
To run Jago you need a Java Runtime Environment (JRE). This can
be obtained from <http://www.javasoft.com/>. This is the runtime
part of the Java Development Kit (JDK) and consists of the Java
virtual machine, Java platform core classes, and supporting files.
The Java virtual machine that comes with I.E. 5.0 works also.
Jago: <http://www.rene-grothmann.de/jago/>
gnugo --quiet --mode gmp
gnugo --help from a cygwin or DOS window for a list of
options
--level <level> to make the game faster
Jago works well with both the Cygwin and MinGW32 executables. The DJGPP executable also works, but has some problems in the interaction with jago after the game has been finished and scored.
If you have Mac OS X you can build GNU Go using Apple's compiler, which is derived from GCC. We recommend adding the flag -no-cpp-precom to CFLAGS.
You can obtain a printed copy of the manual by running
make gnugo.ps in the doc/directory, then printing the
resulting postscript file. The manual contains a great deal of information
about the algorithms of GNU Go.
On platforms supporting info documentation, you can usually
install the manual by executing `make install' (running as
root) from the doc/ directory. The info documentation can
be read conveniently from within Emacs by executing the
command Control-h i.
Documentation in doc/ consists of a man page gnugo.6, the
info files gnugo.info, gnugo.info-1, ... and the
Texinfo files from which the info files are built. The Texinfo
documentation contains this User's Guide and extensive information
about the algorithms of GNU Go, for developers.
If you want a typeset copy of the Texinfo documentation, you can
make gnugo.dvi or make gnugo.ps in the doc/
directory.
You can make an HTML version with the command makeinfo
--html gnugo.texi. Better HTML documentation may be obtained
using texi2html -split_chapter gnugo.texi. You can
obtain the texi2html utility (version 1.61 or later) from
<http://www.mathematik.uni-kl.de/~obachman/Texi2html/>. (See also
<http://texinfo.org/texi2html/>.)
User documentation can be obtained by running gnugo --help
or man gnugo from any terminal, or from the Texinfo
documentation.
Documentation for developers is in the Texinfo documentation, and in comments throughout the source. Contact us at gnugo@gnu.org if you are interested in helping to develop this program.
This is an extremely nice way to run GNU Go. CGoban provides a beautiful graphic user interface under X-Windows.
Start CGoban. When the CGoban Control panel comes up, select "Go Modem". You will get the Go Modem Protocol Setup. Choose one (or both) of the players to be "Program," and fill out the box with the path to gnugo. After clicking OK, you get the Game Setup window. Choose "Rules Set" to be Japanese (otherwise handicaps won't work). Set the board size and handicap if you want.
If you want to play with a komi, you should bear in mind that
the GMP does not have any provision for communicating the komi.
Because of this misfeature, unless you set the komi at the command
line GNU Go will have to guess it. It assumes the komi is 5.5 for
even games, 0.5 for handicap games. If this is not what you want,
you can specify the komi at the command line with the
--komi option, in the Go Modem Protocol Setup window.
You have to set the komi again in the Game Setup window, which
comes up next.
Click OK and you are ready to go.
In the Go Modem Protocol Setup window, when you specify the path to
GNU Go, you can give it command line options, such as --quiet to
suppress most messages. Since the Go Modem Protocol preempts standard
I/O other messages are sent to stderr, even if they are not error
messages. These will appear in the terminal from which you started
CGoban.
Even if you do not have CGoban installed you can play with GNU Go
using its default Ascii interface. Simply type gnugo
at the command line, and GNU Go will draw a board. Typing
help will give a list of options. At the end of the
game, pass twice, and GNU Go will prompt you through the
counting. You and GNU Go must agree on the dead groups--you
can toggle the status of groups to be removed, and when you
are done, GNU Go will report the score.
You can save the game at any point using the save filename
command. You can reload the game from the resulting SGF file with
the command gnugo -l filename --mode ascii. Reloading
games is not supported when playing with CGoban. However you can
use CGoban to save a file, then reload it in ascii mode.
You can run GNU Go from Emacs. This has the advantage that you place the stones using the cursor arrow keys. This may require Emacs 20.4 or later--it has been tested with Emacs 20.4 but does not work with Emacs 19 or Emacs 20.2.
Load interface/gnugo.el, either by M-x load-file,
or by copying the file into your site-lisp directory and
adding a line
(autoload 'gnugo "gnugo" "GNU Go" t)
in your .emacs file.
Now you may start GNU Go by M-x gnugo. You will be prompted for
command line options see Invoking GNU Go. Using these, you may set the
handicap, board size, color and komi.
You can enter commands from the GNU Go ASCII interface after
typing :. For example, to take a move back, type
:back, or to list all commands, type :help.
Here are the default keybindings:
Return or Space
Select point as the next move. An error is signalled for invalid locations. Illegal locations, on the other hand, show up in the GNUGO Console buffer.
q or Q
Quit. Both Board and Console buffers are deleted.
R
Resign.
C-l
Refresh. Includes restoring default window configuration.
M-_
Bury both Board and Console buffers (when the boss is near).
p
Pass; i.e., select no location for your move.
:
Extended command. After typing the : you can type a
command for GNU Go. The possible commands are as in See Ascii.
Jago, like CGoban is a client capable of providing GNU Go with a graphical user interface. Unlike CGoban, it does not require X-Windows, so it is an attractive alternative under Windows. You will need a Java runtime environment. Obtain Jago at
<http://www.rene-grothmann.de/jago/>
and follow the links there for the Java runtime environment.
The Go Modem Protocol (GMP) was developed by Bruce Wilcox with input from
David Fotland, Anders Kierulf and others, according to the history in
<http://www.britgo.org/tech/gmp.html>.
Any Go program should support this protocol since it is a standard. Since CGoban supports this protocol, the user interface for any Go program can be done entirely through CGoban. The programmer can concentrate on the real issues without worrying about drawing stones, resizing the board and other distracting issues.
GNU Go 3.0 introduced a new protocol, the Go Text Protocol (see GTP) which we hope can serve the functions currently used by the GMP.
Computer Tournaments currently use the Go Modem Protocol.
The current method followed in such tournaments is to connect
the serial ports of the two computers by a "null modem" cable.
If you are running GNU/Linux it is convenient to use CGoban.
If your program is black, set it up in the Go Modem Protocol
Setup window as usual. For White, select "Device" and set
the device to /dev/cua0 if your serial port is COM1
and /dev/cua1 if the port is COM2.
The Smart Go Format (SGF), is the standard format for storing Go games.
GNU Go supports both reading and writing SGF files. The SGF specification
(FF[4]) is at:
<http://www.red-bean.com/sgf/>
--help, -h
Print a help message describing the options. This will also tell you the defaults of various parameters, most importantly the level and cache size. The default values of these parameters can be set before compiling byconfigure. If you forget the defaults you can find out using--help.
--boardsize size
Set the board size
--komi num
Set the komi
--level level
GNU Go can play with different strengths and speeds. Level 10 is the default. Decreasing the level will make GNU Go faster but less accurate in its reading.
--quiet, --silent
Don't print copyright and other messages. Messages specifically
requested by other command line options, such as --trace,
are not supressed.
-l, --infile filename
Load the named SGF file. GNU Go will generate a move for the player who is about to move. If you want to override this and generate a move for the other player you may add the optioncolor <color>where <color> isblackorwhite.
--orientation n
Combine with-l. The Go board can be oriented in 8 different ways, counting reflections and rotations of the position; this option selects an orientation (default 0). The parameternis an integer between 0 and 7.
-L, --until move
Stop loading just before the indicated move is played. move can be either the move number or location.
-o, --outfile filename
Write sgf output to file
--mode mode
Force the playing mode ('ascii', 'emacs,' 'gmp' or 'gtp'). The default is ASCII, but if no terminal is detected GMP (Go Modem Protocol) will be assumed. In practice this is usually what you want, so you may never need this option.
-M, --cache-size megs
Memory in megabytes used for caching of read results. The default size is 8 unless you configure gnugo with the commandconfigure --enable-cache-size=sizebefore compiling to make size the default (see Installation). GNU Go stores results of its reading calculations in a Hash table (see Hashing). If the Hash table is filled, it is emptied and the reading continues, but some reading may have to be repeated that was done earlier, so a larger cache size will make GNU Go run faster, provided the cache is not so large that swapping occurs. Swapping may be detected on GNU/Linux machines using the programtop. However, if you have ample memory or if performance seems to be a problem you may want to increase the size of the cache using this option.
--chinese-rules
Use Chinese rules. This means that the Chinese or Area Counting is followed. It may affect the score of the game by one point in even games, more if there is a handicap (since in Chinese Counting the handicap stones count for Black).
--japanese-rules
Use Japanese Rules. This is the default unless you specify
--enable-chinese-rules as a configure option.
--copyright: Display the copyright notice
--version or -v: Print the version number
--printsgf filename:
Create an SGF file
containing a diagram of the board. Useful with -L to
create diagrams from games.
--options
Print which experimental configure options were compiled into the program (see Experimental Options).
--level amount
The higher the level, the deeper GNU Go reads. Level 10 is the default. If GNU Go plays too slowly on your machine, you may want to decrease it.
This single parameter --level is the best way of
choosing whether to play stronger or faster. It controls
a host of other parameters which may themselves be set
individually at the command line. The default values of
these parameters may be found by running gnugo --help.
Unless you are working on the program you probably don't
need these options. Instead, just adjust the single
variable --level. The remaining options are of
use to developers tuning the program for performance and
accuracy.
-D, --depth depth
Deep reading cutoff. When reading beyond this depth (default 16) GNU Go assumes that any string which can obtain 3 liberties is alive. Thus GNU Go can read ladders to an arbitrary depth, but will miss other types of capturing moves.
--branch-depth
This sets thebranch_depth, typically a little below thedepth. Betweenbranch_depthanddepth, attacks on strings with 3 liberties are considered but branching is inhibited, so fewer variations are considered.
-B, --backfill-depth depth
Deep reading cutoff. Beyond this depth (default 12) GNU Go will no longer try backfilling moves in its reading.
--backfill2-depth depth
Another depth controlling how deeply GNU Go looks for backfilling moves. The moves tried belowbackfill2_depthare generally more obscure and time intensive than those controlled bybackfill_depth, so this parameter has a lower default.
-F, --fourlib-depth depth
Deep reading cutoff. When reading beyond this depth (default 7) GNU Go assumes that any string which can obtain 4 liberties is alive.
-K, --ko-depth depth
Deep reading cutoff. Beyond this depth (default 8) GNU Go no longer tries very hard to analyze kos.
--branch-depth depth
Deep reading cutoff. Below this depth (default 8), GNU Go still tries to attack strings with only 3 liberties, but only tries one move at each node.
--aa_depth depth
The reading functionatari_atarilooks for combinations beginning with a series of ataris, and culminating with some string having an unexpected change in status (e.g. alive to dead or critical). This command line optio sets the parameteraa_depthwhich determines how deeply this function looks for combinations.
--superstring-depth
A superstring (see Superstrings) is an amalgamation of
tightly strings. Sometimes the best way to attack or defend a
string is by attacking or defending an element of the superstring.
Such tactics are tried below superstring_depth and this
command line option allows this parameter to be set.
The preceeding options are documented with the reading code (see Reading Basics).
--owl-branch Below this depth Owl only considers one move. Default 8.
--owl-reading Below this depth Owl assumes the dragon has escaped.
Default 20.
--owl-node-limit
If the number of variations exceeds this limit, Owl assumes the dragon can
make life. Default 1000. We caution the user that increasing
owl_node_limit does not necessarily increase the strength of the
program.
--color color
Choose your color ('black' or 'white').
--handicap number
Choose the number of handicap stones (0-9)
--replay color
Replay all moves in a game for either or both colors. If used with the-ooption the game record is annotated with move values. This option requires-l filename. The color can be:When the move found by genmove differs from the move in the sgf file the values of both moves are reported thus:
- white: replay white moves only
- black: replay black moves only
- both: replay all moves
Move 13 (white): GNU Go plays C6 (20.60) - Game move F4 (20.60)This option is useful if one wants to confirm that a change such as a speedup or other optimization has not affected the behavior of the engine. Note that when several moves have the same top value (or nearly equal) the move generated is not deterministic (though it can be made deterministic by starting with the same random seed). Thus a few deviations from the move in the sgf file are to be expected. Only if the two reported values differ should we conclude that the engine plays differently from the engine which generated the sgf file. See Regression.
-a, --allpats
Test all patterns, even those smaller in value than the largest move
found so far. This should never affect GNU Go's final move, and it
will make it run slower. However this can be very useful when "tuning"
GNU Go. It causes both the traces and the output file (-o) to
be more informative.
-T, --printboard: colored display of dragons.
Use rxvt, xterm or Linux Console. (see Colored Display)
-E: colored display of eye spaces
Use rxvt, xterm or Linux Console. (see Colored Display)
-d, --debug level
Produce debugging output. The debug level is given in hexadecimal, using the bits defined in the following table fromengine/gnugo.h. A list of these may be produced using--debug-flags. Here they are in hexadecimal:DEBUG_INFLUENCE 0x0001 DEBUG_EYES 0x0002 DEBUG_OWL 0x0004 DEBUG_ESCAPE 0x0008 DEBUG_MATCHER 0x0010 DEBUG_DRAGONS 0x0020 DEBUG_SEMEAI 0x0040 DEBUG_LOADSGF 0x0080 DEBUG_HELPER 0x0100 DEBUG_READING 0x0200 DEBUG_WORMS 0x0400 DEBUG_MOVE_REASONS 0x0800 DEBUG_OWL_PERFORMANCE 0x1000 DEBUG_LIFE 0x2000 DEBUG_FILLLIB 0x4000 DEBUG_READING_PERFORMANCE 0x8000 DEBUG_SCORING 0x010000 DEBUG_AFTERMATH 0x020000 DEBUG_ATARI_ATARI 0x040000 DEBUG_READING_CACHE 0x080000 DEBUG_TERRITORY 0x100000 DEBUG_OWL_PERSISTENT_CACHE 0X200000These debug flags are additive. If you want to turn on both dragon and worm debugging you can use
-d0x420.
-H, --hash level
hash (see engine/gnugo.h for bits).
-w, --worms
Print more information about worm data.
-m, --moyo level
moyo debugging, show moyo board. The level is fully documented elsewhere (see Influential Display).
-b, --benchmark number
benchmarking mode - can be used with -l.
-S, --statistics
Print statistics (for debugging purposes).
-t, --trace
Print debugging information. Use twice for more detail.
-r, --seed seed
Set random number seed. This can be used to guarantee that GNU Go will make
the same decisions on multiple runs through the same game. If seed is
zero, GNU Go will play a different game each time.
--decide-string location
Invoke the tactical reading code (see Tactical Reading to decide
whether the string at location can be captured, and if so, whether it
can be defended. If used with -o, this will produce a variation tree
in SGF.
--decide-dragon location
Invoke the owl code (see The Owl Code) to decide whether the dragon at
location can be captured, and whether it can be defended. If used with
-o, this will produce a variation tree in SGF.
--score method
Requires-l. method can be "end", "last", "aftermath" or a move. "end" and "aftermath" are appropriate when the game is complete, or nearly so, and both try to supply an accurate final score. The other options may be used to get an estimate during the middle of the game. Any of these options may be combined with--chinese-ruleif you want to use Chinese (Area) counting.
- last
load the sgf file up to the last move, then estimate territory using the Bouzy 5/21 algorithm (see Moyo).- end
finish the game by selfplaying from the end of the file until two passes, then estimate territory using the Bouzy 5/21 algorithm (see Moyo).- aftermath
finish the game by selfplaying from the end of the file until two passes, then estimate territory using the most accurate scoring algorithm available. Slower than--score last, and while these algorithms usually agree, if they differ,--score aftermathis most likely to be correct.- move, e.g.
--score J17load file until move is reached and estimate territorial balance using the Bouzy 5/21 algorithm. The--score endand--score aftermathoptions are only useful at or near the end of the game, so if you want an estimate of the score in the middle, use this method.
--printsgf output file
load SGF file, output final position (requires-l) as another SGF file. Illegal moves are indicated with the privateILproperty. This property is not used in the FF4 SGF specification, so we are free to preempt it. This feature is used in the CGI interface ininterface/html/gg.cgi.
This chapter is an overview of the GNU Go internals. Further documentation of how any one module or routine works may be found in later chapters or comments in the source files.
examine_position() does.
genmove().
A worm is a maximal set of vertices on the board which are connected
along the horizontal and vertical lines, and are of the same color,
which can be BLACK, WHITE or EMPTY. The term
EMPTY applied to a worm means that the worm consists of empty
(unoccupied) vertices. It does not mean that that the worm is the
empty set. A string is a nonempty worm. An empty worm is called a
cavity. If a subset of vertices is contained in a worm, there is a unique
worm containing it; this is its worm closure. (see Worms.)
A dragon is a union of strings of the same color which will be treated as a unit. If two strings are in the same dragon, it is the computer's working hypothesis that they will live or die together and are effectively connected. (see Dragons.)
A superstring is a less commonly used unit which is the union
of several strings but generally smaller than a dragon. The superstring
code is in engine/utils.c. The definition of a superstring is
slightly different if the code is called from owl.c or from
reading.c.
GNU Go represents the board in a one-dimensional array called
board. For some purposes a two dimensional indexing of the
board by parameters (i,j) might be used.
The board array includes out-of-board markers around the
board. To make the relation to the old two-dimensional board
representation clear, this figure shows how the 1D indices correspond
to the 2D indices when MAX_BOARD is 7.
j -1 0 1 2 3 4 5 6 i +---------------------------------- -1| 0 1 2 3 4 5 6 7 0| 8 9 10 11 12 13 14 15 1| 16 17 18 19 20 21 22 23 2| 24 25 26 27 28 29 30 31 3| 32 33 34 35 36 37 38 39 4| 40 41 42 43 44 45 46 47 5| 48 49 50 51 52 53 54 55 6| 56 57 58 59 60 61 62 63 7| 64 65 66 67 68 69 70 71 72
To convert between a 1D index pos and a 2D index (i,j),
the macros POS, I, and J are provided, defined as
below:
#define POS(i, j) ((MAX_BOARD + 2) + (i) * (MAX_BOARD + 1) + (j)) #define I(pos) ((pos) / (MAX_BOARD + 1) - 1) #define J(pos) ((pos) % (MAX_BOARD + 1) - 1)
All 1D indices not corresponding to points on the board have the out
of board marker value GRAY. Thus if board_size and
MAX_BOARD both are 7, this looks like
j -1 0 1 2 3 4 5 6 i +---------------------------------- -1| # # # # # # # # 0| # . . . . . . . 1| # . . . . . . . 2| # . . . . . . . 3| # . . . . . . . 4| # . . . . . . . 5| # . . . . . . . 6| # . . . . . . . 7| # # # # # # # # #
The indices marked # have value GRAY.
If MAX_BOARD is 7 and board_size is only 5:
j -1 0 1 2 3 4 5 6 i +---------------------------------- -1| # # # # # # # # 0| # . . . . . # # 1| # . . . . . # # 2| # . . . . . # # 3| # . . . . . # # 4| # . . . . . # # 5| # # # # # # # # 6| # # # # # # # # 7| # # # # # # # # #
Navigation on the board is done by the SOUTH, WEST,
NORTH, and EAST macros,
#define NS (MAX_BOARD + 1) #define WE 1 #define SOUTH(pos) ((pos) + NS) #define WEST(pos) ((pos) - 1) #define NORTH(pos) ((pos) - NS) #define EAST(pos) ((pos) + 1)
There are also shorthand macros SW, NW, NE,
SE, SS, WW, NN, EE for two step
movements.
Any movement from a point on the board to an adjacent or diagonal vertex is guaranteed to produce a valid index into the board array, and the color found is GRAY if it is not on the board. To do explicit tests for out of board there are two macros
#define ON_BOARD(pos) (board[pos] != GRAY) #define ON_BOARD1(pos) (((unsigned) (pos) < BOARDSIZE) && board[pos] != GRAY)
where the first one should be used in the algorithms and the second one is useful for assertion tests.
Important: The 2D coordinate (-1,-1), which is used for
pass and sometimes to indicate no point, maps to the 1D coordinate
0, not to -1. Instead of a plain 0, use one of the
macros NO_MOVE or PASS_MOVE.
A loop over multiple directions is straightforwardly written:
for (k = 0; k < 4; k++) {
int d = delta[k];
do_something(pos + d);
}
The following constants are useful for loops over the entire board and allocation of arrays with a 1-1 mapping to the board.
#define BOARDSIZE ((MAX_BOARD + 2) * (MAX_BOARD + 1) + 1) #define BOARDMIN (MAX_BOARD + 2) #define BOARDMAX (MAX_BOARD + 1) * (MAX_BOARD + 1)
BOARDSIZE is the actual size of the 1D board array,
BOARDMIN is the first index corresponding to a point on the
board, and BOARDMAX is one larger than the last index corresponding to
a point on the board.
Often one wants to traverse the board, carrying out some function at every vertex. Here are two possible ways of doing this:
int m, n;
for (m = 0; m < board_size; m++)
for (n = 0; n < board_size; n++) {
do_something(POS(m, n));
}
Or:
int pos;
for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
if (ON_BOARD(pos))
do_something(pos);
}
The engine of GNU Go takes a position and a color to move and
generates the (supposedly) optimal move. This is done by the function
genmove() in engine/genmove.c.
The move generation is done in three passes:
The information gathering is done by a function examine_position(),
which will be discussed in greater detail in the next section.
Such information could be life and death of the groups, information
about moyos, connection of groups and so on. Information gathering is
performed by examine_position(), which in turn calls:
make_worms()
Collect information about all connected sets of stones
(strings) and cavities. This information is stored in
the worm[] array. (see Worms)
compute_initial_influence()
Decides which areas of the board are influenced by which
player. This function is run a second time later at
the end of make_dragons(), since GNU Go's opinion
about the safety of groups may change, and it is
important to have the influence function as accurate as
possible. see Influence
make_dragons()
Collect information about connected strings, which are called dragons. Important information here is number of eyes, life status, and connectedness between string. (see Dragons.)
A more detailed
Once we have found out all about the position it is time to generate the best move. Moves are proposed by a number of different modules called move generators. The move generators themselves do not set the values of the moves, but enumerate justifications for them, called move reasons. The valuation of the moves comes last, after all moves and their reasons have been generated.
The move generators in version 3.2 are:
fuseki()
Generate a move in the early fuseki.
semeai()
Find out if two dead groups of opposite colors are next to each other and, if so, try to kill the other group. This module will eventually be rewritten along the lines of the owl code.
shapes()
Find patterns frompatterns/patterns.dbin the current position. Each pattern is matched in each of the 8 possible orientations obtainable by rotation and reflection. If the pattern matches, a so called "constraint" may be tested which makes use of reading to determine if the pattern should be used in the current situation. Such constraints can make demands on number of liberties of strings, life and death status, and reading out ladders, etc. The patterns may call helper functions, which may be hand coded (inpatterns/helpers.c) or autogenerated.The patterns can be of a number of different classes with different goals. There are e.g. patterns which try to attack or defend groups, patterns which try to connect or cut groups, and patterns which simply try to make good shape. In addition to the large pattern database called by
shapes(), pattern matching is used by other modules for different tasks throughout the program. See Patterns, for a complete documentation of patterns.
atari_atari()
See if there are any combination threats and either propose them or defend against them.
owl_reasons()
The Owl Code (see The Owl Code) which has been run duringexamine_position), beforeowl_reasons()executes, has decided whether different groups can be attacked. The modulereview_owl_reasonsreviews the statuses of every dragon and assigns move reasons for attack and defense. Unlike the other move generation modules, this one is called fromexamine_position().
endgame_shapes()
If no move is found with a value greater than 6.0, this module matches a
set of extra patterns which are designed for the endgame. The endgame
patterns can be found in patterns/endgame.db.
revise_semeai()
If no move is found, this module changes the status of opponent groups involved in a semeai fromDEADtoUNKNOWN. After this, genmove runsshapesandendgame_shapesagain to see if a new move turns up.
fill_liberty()
Fill a common liberty. This is only used at the end of the game. If necessary a backfilling or backcapturing move is generated.
After the move generation modules have run, the best ten moves
are selected by the function review_move_reasons. This
function also does some analysis to try to turn up other moves
which may have been missed. The modules revise_semeai() and
fill_liberty() are only run if no good move has been
discovered by the other modules.
In this section we summarize the sequence of events when
examine_position() is run from genmove(). This
is for reference only. Don't try to memorize it.
purge persistent reading cache (see Persistent Cache)make_worms()(see Worms):build_worms()finds and identifies the worms compute effective size of each wormunconditional_life()find_worm_attacks_and_defenses(): for each attackable worm: setworm.attackadd_attack_move()find_attack_patterns()to find a few more attacks for each defensible worm setworm.defendadd_defense_moveif point of attack is not adjacent to worm see if it defendsfind_defense_patterns()to find a few more defenses for each attackable worm try each liberty if it attacksadd_attack_moveif it defendsadd_defense_movefind kos. for each worm find higher order liberties find cutting points (worm.cutstone) for each worm compute the genus (see Worms)small_semeai()try to improve values of worm.attack and worm.defend try to repair situations where adjacent worms can be both attacked and defended find worm lunches find worm threatscompute_initial_influence()(see Influence)compute_influence()find_influence_patterns()at each intersectionaccumulate_influence()segment_influence()make_dragons()(see Dragons) initialize dragon data find the inessential wormsmake_domains()initialize eye datacompute_primary_domains()fill out arrays black_eye and white_eye describing eyeshapes find_cuts() for every eyespaceoriginate_eye()count_neighbors()find_connections()amalgamate dragons sharing an eyespaceinitialize_supplementary_dragon_data()find adjacent worms which can be captured (dragon lunches) find topological half eyes and false eyesmodify_eye_spaces()for each eye spacecompute_eyes()store the results in black_eye, white_eye arrays compute the genus of each dragon for each dragoncompute_escape()resegment_initial_influence()for each dragoninfluence_get_moyo_size()for each dragoncompute_dragon_status()find_neighbor_dragons()purge_persistent_owl_cache()for each dragon which seems surrounded tryowl_attack()andowl_defend()if appropriate find owl threats for each dragon set dragon.matcher_status for each dragon set dragon2.safetysemeai()revise opinion of which worms are inessential count non-dead dragons of each colorowl_reasons()(see The Owl Code)compute_initial_influence()again (see Influence)
In this section we summarize the sequence of events during the
move generation and selection phases of genmove(), which
take place after the information gathering phase has been completed.
fuseki()shapes()review_move_reasons()find_more_attack_and_defense_moves()remove_opponent_attack_and_defense_moves()do_remove_false_attack_and_defense_moves()examine_move_safety()induce_secondary_move_reasons()value_moves()find the ten best moves if the value of the best move is < 6.0endgame_shapes()if no move found yetrevise_semeai()shapes()endgame_shapes()if still no move foundfill_liberty()if still no move found pass
The GNU Go engine is contained in two directories, engine/ and
patterns/. Code related to the user interface, reading and
writing of smart go format files, and testing are found in the
directories interface/, sgf/, and regression/. Code
borrowed from other GNU programs is contained in utils/. That
directory also includes some code developed within GNU Go which is not
go specific. Documentation is in doc/.
In this document we will describe some of the individual files comprising
the engine code in engine/ and patterns/. In interface/
we mention two files:
gmp.c
This is the Go Modem Protocol interface (courtesy of William Shubert and others). This takes care of all the details of exchanging setup and moves with Cgoban, or any other driving program recognizing the Go Modem Protocol.
main.c
This containsmain(). Thegnugotarget is thus built in theinterface/directory.
engine/In engine/ there are the following files:
aftermath.c
Contains algorithms which may be called at the end of the game to generate moves that will generate moves to settle the position, if necessary playing out a position to determine exactly the status of every group on the board, which GNU Go can get wrong, particularly if there is a seki. This module is the basis for the most accurate scoring algorithm available in GNU Go.
board.c
This file contains code for the maintenance of the board. For example it contains the important functiontrymove()which tries a move on the board, andpopgo()which removes it by popping the move stack. At the same time vital information such as the number of liberties for each string and their location is updated incrementally.
clock.c
Clock code, including code allowing GNU Go to automatically adjust its level in order to avoid losing on time in tournaments.
dragon.c
This containsmake_dragons(). This function is executed before the move-generating modulesshapes()semeai()and the other move generators but aftermake_worms. It tries to connect worms into dragons and collect important information about them, such as how many liberties each has, whether (in GNU Go's opinion) the dragon can be captured, if it lives, etc.
fuseki.c
Generates fuseki (opening) moves from a database.
filllib.c
Code to force filling of dame (backfilling if necessary) at the end of the game.
genmove.c
This file containsgenmove()and its supporting routines, particularlyexamine_position().
globals.c
This contains the principal global variables used by GNU Go.
gnugo.h
This file contains declarations forming the public interface to the engine.
hash.c and cache.c
Hashing code implementing Zobrist hashing. (see Hashing) The code inhash.cprovides a way to hash board positions into compact descriptions which can be efficiently compared. The code incache.cimplements a kind of database for storing reading results, so they can be quickly retrieved. The caching code uses the board hashes as keys to the database. They are split since these functionalities are sufficiently demarked that either file could be reimplemented without affecting the other one. Note also thatmatchpat()uses the hashing code without also using the caching code.
hash.h and cache.h
Header files forhash.candcache.c.
influence.c and influence.h.
This code determines which regions of the board are under the influence of either player. (see Influence)
liberty.h
Header file for the engine. The name "liberty" connotes freedom (see Copying).
life.c
The code in this file contains an alternative approach to life and death based on reading instead of the static approach inoptics.c. This code is experimental. It is reasonably accurate but too slow. It is activated when gnugo is invoked with the--lifeoption.
matchpat.c
This file contains the pattern matchermatchpat(), which looks for patterns at a particular board location. The actual patterns are in thepatterns/directory. The functionmatchpat()is called by every module which does pattern matching, notablyshapes.
move_reasons.c
This file contains the code which assigns values to every move after all the move reasons are gen
optics.c
This file contains the code to recognize eye shapes, documented in See Eyes.
owl.c
This file does life and death reading. The paradigm is that moves are played by both players trying to expand and shrink the eyespace until a static configuration is reached where it can be analyzed by the code inoptics.corlife.c.
printutils.c
Print utilities
reading.c
This file contains code to determine whether any given string can be attacked or defended. See Tactical Reading, for details.
score.c
Implements the Bouzy algorithms (see Moyo) and contains code for scoring the game.
semeai.c
This file contains semeai(), the module which tries to
win capturing races. This module does not work particularly
well and will eventually be replaced.
shapes.c
This file containsshapes(), the module called bygenmove()which tries to find moves which match a pattern (see Patterns).
showbord.c
This file contains showboard(), which draws an ASCII
representation of the board, depicting dragons (stones
with same letter) and status (color). This was the
primary interface in GNU Go 1.2, but is now a debugging
aid.
worm.c
This file containsmake_worms(), code which is run at the beginning of each move cycle, before the code indragon.c, to determine the attributes of every string. These attributes are things like liberties, wether the string can be captured (and how), etc
utils.c
An assortment of utilities, described in greater detail below.
patterns/The directory patterns/ contains files related to pattern matching.
Currently there are several types of patterns. A partial list:
patterns.db and patterns2.db
hoshi.db etc. which are
automatically build from the files hoshi.sgf etc. These comprise
our small Joseki library.
owl_attackpats.db, owl_defendpats.db
and owl_vital_apats.db. These generate moves for the owl
code (see The Owl Code).
conn.db (see Connections Database)
influence.db and barriers.db
(see Influence)
eyes.db (see Eyes).
The following list contains, in addition to distributed source files
some intermediate automatically generated files such as patterns.c.
These are C source files produced by "compiling" various pattern
databases, or in some cases (such as hoshi.db) themselves
automatically generated pattern databases produced by "compiling"
joseki files in Smart Go Format.
conn.db
Database of connection patterns.
conn.c
Automatically generated file, containing connection patterns in form of struct arrays, compiled bymkpatfromconn.db.
eyes.c
Automatically generated file, containing eyeshape patterns in form of struct arrays, compiled bymkpatfromeyes.db.
eyes.h
Header file for eyes.c.
eyes.db
Database of eyeshape patterns. See Eyes, for details.
helpers.c
These are helper functions to assist in evaluating moves by matchpat.
hoshi.sgf
Smart Go Format file containing 4-4 point openings
hoshi.db
Automatically generated database of 4-4 point opening
patterns, make by compiling hoshi.sgf
joseki.c
Joseki compiler, which takes a joseki file in Smart Go Format, and produces a pattern database.
komoku.sgf
Smart Go Format file containing 3-4 point openings
komoku.db
Automatically generated database of 3-4 point opening
patterns, make by compiling komoku.sgf
mkeyes.c
Pattern compiler for the eyeshape databases. This program takeseyes.dbas input and produceseyes.cas output.
mkpat.c
Pattern compiler for the move generation and connection databases. Takes the filepatterns.dbtogether with the autogenerated Joseki pattern fileshoshi.db,komoku.db,sansan.db,mokuhadzushi.db,takamoku.dband producespatterns.c, or takesconn.dband producesconn.c.
mokuhazushi.sgf
Smart Go Format file containing 5-3 point openings
mokuhazushi.db
Pattern database compiled from mokuhadzushi.sgf
sansan.sgf
Smart Go Format file containing 3-3 point openings
sansan.db
Pattern database compiled from sansan.sgf
takamoku.sgf
Smart Go Format file containing 5-4 point openings
takamoku.db
Pattern database compiled from takamoku.sgf.
patterns.c
Pattern data, compiled from patterns.db by mkpat.
patterns.h
Header file relating to the pattern databases.
patterns.db and patterns2.db
These contain pattern databases in human readable form.
Please follow the coding conventions at:
<http://www.gnu.org/prep/standards_toc.html>
Please preface every function with a brief description of its usage.
Please help to keep this Texinfo documentation up-to-date.
A function gprintf() is provided. It is a cut-down
printf, supporting only %c, %d,
%s, and without field widths, etc. It does, however,
add some useful facilities:
%m
Takes two parameters, and displays a formatted board co-ordinate.
Trace messages are automatically indented to reflect the current stack depth, so it is clear during read-ahead when it puts a move down or takes one back.
format string suppresses the indentation.
A variant mprintf sends output to stderr. Normally
gprintf() is wrapped in one of the following:
TRACE(fmt, ...):
Print the message if the 'verbose' variable > 0.
(verbose is set by -t on the command line)
DEBUG(flags, fmt, ...):
WhileTRACEis intended to afford an overview of what GNU Go is considering,DEBUGallows occasional in depth study of a module, usually needed when something goes wrong.flagsis one of theDEBUG_*symbols inengine/gnugo.h. TheDEBUGmacro tests to see if that bit is set in thedebugvariable, and prints the message if it is. The debug variable is set using the-dcommand-line option.
The variable verbose controls the tracing. It
can equal 0 (no trace), 1, 2, 3 or 4 for increasing
levels of tracing. You can set the trace level at
the command line by -t for verbose=1,
-t -t for verbose=2, etc. But in
practice if you want more verbose tracing than level
1 it is better to use gdb to reach the point where
you want the tracing; you will often find that the
variable verbose has been temporarily set to zero
and you can use the gdb command set var verbose=1
to turn the tracing back on.
Related to tracing are assertions. Developers are strongly encouraged to pepper their code with assertions to ensure that data structures are as they expect. For example, the helper functions make assertions about the contents of the board in the vicinity of the move they are evaluating.
ASSERT() is a wrapper around the standard C assert()
function. In addition to the test, it takes an extra pair of parameters
which are the co-ordinates of a "relevant" board position. If an
assertion fails, the board position is included in the trace output, and
showboard() and popgo() are called to unwind and display
the stack.
We have adopted the convention of putting the word FIXME in comments to denote known bugs, etc.
If you are using Emacs, you may find it fast and convenient to use
Emacs' built-in facility for navigating the source. Switch to the
root directory gnugo-3.2.x/ and execute the command:
find . -print|grep "\.[ch]$" | xargs etags
This will build a file called gnugo-3.2.x/TAGS. Now to
find any GNU Go function, type M-. and enter the
command which you wish to find, or just RET if
the cursor is at the name of the function sought.
The first time you do this you will be prompted for the location
of the TAGS table. Enter the path to gnugo-3.2.x/TAGS, and
henceforth you will be able to find any function with a minimum
of keystrokes.
In this chapter we will discuss methods of finding out how GNU Go understands a given position. These methods will be of interest to anyone working on the program, or simply curious about its workings.
In practice, most tuning of GNU Go is done in conjunction
with maintaining the regression/ directory
(see Regression).
We assume that you have a game GNU Go played saved as an sgf file, and you want to know why it made a certain move.
A quick way to find out roughly the reason for a move is to run
gnugo -l filename -t -L move number
(You may also want to add --quiet to suppress the copyright
message.) In GNU Go 3.2, the moves together with their reasons are
listed, followed by a numerical analysis of the values given to each
move.
If you are tuning (see Tuning) you may want to add the -a
option. This causes GNU Go to report all patterns matched, even ones
that cannot affect the outcome of the move. The reasons for doing
this is that you may want to modify a pattern already matched
instead of introducing a new one.
If you use the -w option, GNU Go will report the statuses of
worms and dragons around the board. This type of information is
available by different methods, however (see Debugboard,
see Colored Display).
If GNU Go is invoked with the option -o filename it will
produce an output file. This option can be added at the command line
in the Go Modem Protocol Setup Window of CGoban. The output file will
show the locations of the moves considered and their weights. It is
worth noting that by enlarging the CGoban window to its fullest size
it can display 3 digit numbers. Dragons with status DEAD are
labelled with an X, and dragons with status CRITICAL are
labelled with a !.
If you have a game file which is not commented this way, or which was produced by a non-current version of GNU Go you may ask GNU Go to produce a commented version by running:
gnugo --quiet -l <old file> --replay <color> -o <new file>
Here <color> can be 'black,' 'white' or 'both'. The replay option will also help you to find out if your current version of GNU Go would play differently than the program that created the file.
The --decide-string option is used to check the tactical reading code
(see Tactical Reading). This option takes an argument, which is a location
on the board in the usual algebraic notation (e.g.
--decide-string C17). This will tell you whether the reading code (in
engine/reading.c) believes the string can be captured, and if so,
whether it believes it can be defended, which moves it finds to attack or
defend the move, how many nodes it searched in coming to these
conclusions. Note that when GNU Go runs normally (not with
--decide-string) the points of attack and defense are
computed when make_worms() runs and cached in
worm.attack and worm.defend.
If used with an output file (-o filename)
--decide-string will produce a variation tree showing
all the variations which are considered. This is a useful way
of debugging the reading code, and also of educating yourself
with the way it works. The variation tree can be displayed
graphically using CGoban.
At each node, the comment contains some information. For example you may find a comment:
attack4-B at D12 (variation 6, hash 51180fdf) break_chain D12: 0 defend3 D12: 1 G12 (trivial extension)
This is to be interpreted as follows. The node in question
was generated by the function attack3() in engine/reading.c,
which was called on the string at D12. The data in
parentheses tell you the values of count_variations and
hashdata.hashval.
The second value ("hash") you probably will not need to know
unless you are debugging the hash code, and we will not discuss it.
But the first value ("variation") is useful when using the debugger
gdb. You can first make an output file using
the -o option, then walk through the reading with
gdb, and to coordinate the SGF file with the debugger,
display the value of count_variations. Specifically,
from the debugger you can find out where you are as follows:
(gdb) set dump_stack() B:D13 W:E12 B:E13 W:F12 B:F11 (variation 6)
If you place yourself right after the call to trymove()
which generated the move in question, then the variation number
in the SGF file should match the variation number displayed by
dump_stack(), and the move in question will be the
last move played (F11 in this example).
This displays the sequence of moves leading up to the variation
in question, and it also prints count_variations-1.
The second two lines tell you that from this node, the function
break_chain() was called at D12 and returned 0 meaning
that no way was found of rescuing the string by attacking
an element of the surrounding chain, and the function
defend3() was called also at D12 and returned 1,
meaning that the string can be defended, and that
G12 is the move that defends it. If you have trouble
finding the function calls which generate these comments,
try setting sgf_dumptree=1 and setting a breakpoint in
sgf_trace.
You can similarly debug the Owl code using the option
--decide-dragon. Usage is entirely similar to
--decide-string, and it can be used similarly
to produce variation trees. These should be typically
much smaller than the variation trees produced by
--decide-string.
You can use the Go Text Protocol (see GTP) to determine
the statuses of dragons and other information needed for
debugging. The GTP command dragon_data P12 will list
the dragon data of the dragon at P12 and
worm_data will list the worm data; other GTP
commands may be useful as well.
You can also conveniently get such information from GDB.
A suggested .gdbinit file may be found in
See Debugging. Assuming this file is loaded, you can
list the dragon data with the command:
(gdb) dragon P12
Similarly you can get the worm data with worm P12.
A useful utility called debugboard is made in
the interface/debugboard/ directory. This can be run
in an Xterm. Use a smaller font since it requires 50 rows
and 80 columns. This runs examine_position(), then
makes a graphical display of the board. Using the cursor
movement keys, you can move around the board and find
out the contents of the worm, dragon and eye arrays.
GNU Go can score the game. If done at the last move, this is usually
accurate unless there is a seki. Normally GNU Go will report its
opinion about the score at the end of the game, but if you want this
information about a game stored in a file, use the --score
option.
gnugo --score last -l filename
loads the sgf file to the end of the file and estimates the winner after the last stored move by estimating the territory.
gnugo --score end -l filename
loads the sgf file and GNU Go continues to play after the last stored move by itself up to the very end. Then the winner is determined by estimating the territory.
gnugo --score aftermath -l filename
loads the sgf file and GNU Go continues to play after the last stored
move by itself up to the very end. Then the winner is determined by
the most accurate algorithm available. Slower but more accurate than
--score end.
gnugo --score L10 -l filename
loads the sgf file until a stone is placed on L10. Now the winner will
be estimated as with gnugo --score last.
Any of these commands may be combined with --chinese-rules
if you want to use Chinese (area) counting.
gnugo --score 100 -l filename
loads the sgf file until move number 100. Now the winner will be estimated
as with gnugo --score last.
If the option -o outputfilename is provided, the results
will also be written as comment at the end of the output file.
Various colored displays of the board may be obtained in a color
xterm or rxvt window. Xterm will only work if xterm is not
compiled with color support. If the colors are not displayed on your xterm,
try rxvt. You may also use the Linux console. The colored display
will work best if the background color is black; if this is not the case you
may want to edit your .Xdefaults file or add the options
-bg black -fg white to xterm or rxvt.
You can get a colored ASCII display of the board in which each dragon
is assigned a different letter; and the different matcher_status values
(ALIVE, DEAD, UNKNOWN, CRITICAL) have different
colors. This is very handy for debugging. Actually two diagrams are generated.
The reason for this is concerns the way the matcher status is computed.
The dragon_status (see Dragons) is computed first, then for some, but not
all dragons, a more accurate owl status is computed. The matcher status is
the owl status if available; otherwise it is the dragon_status. Both the
dragon_status and the owl_status are displayed. The color scheme is as
follows:
green = alive cyan = dead red = critical yellow = unknown magenta = unchecked
To get the colored display, save a game in sgf format using CGoban, or using
the -o option with GNU Go itself.
Open an xterm or rxvt window.
Execute gnugo -l [filename] -L [movenum] -T to get the colored
display.
Other useful colored displays may be obtained by using instead:
Instead of -T, try this with -E. This gives a colored
display of the eyespaces, with marginal eye spaces marked !
(see Eyes).
The option -m level can give colored displays of the
various quantities which are computed in engine/moyo.c.
The regions found by Bouzy's algorithm (see Moyo) can be displayed with the following options:
-m level
use or (hexadecimal) cumulative values for printing these reports :
1 0x01 ascii printing of territorial evaluation (5/21)
2 0x02 ascii printing of moyo evaluation (5/10)
4 0x04 ascii printing of area (4/0)
These data are today only used in the score estimation.
The rest of the engine uses instead the new influence algorithm explained
in See Influence. To get a colored display of the influence regions
found by this module, use -m 0x18 to see the initial influence,
and e.g. -m 0x10 --debug-influence D5 to see the influence
after having made the move D5. There are various other options available
for numerical displays influence; for a detailed description see
See Influential Display.
These options can be combined by adding the levels.
If you want to write your own interface to GNU Go, or if you want to create a go application using the GNU Go engine, this chapter is of interest to you.
First an overview: GNU Go consists of two parts: the GNU Go engine and a program (user interface) which uses this engine. These are linked together into one binary. The current program implements the following user modes:
The GNU Go engine can be used in other applications. For example, supplied
with GNU Go is another program using the engine, called debugboard,
in the directory interface/debugboard/. The program debugboard lets the
user load SGF files and can then interactively look at different properties of
the position such as group status and eye status.
The purpose of this Chapter is to show how to interface your own
program such as debugboard with the GNU Go engine.
Figure 1 describes the structure of a program using the GNU Go engine.
+-----------------------------------+
| |
| Go application |
| |
+-----+----------+------+ |
| | | | |
| | Game | | |
| | handling | | |
| | | | |
| +----+-----+ | |
| SGF | Move | |
| handling | generation | |
| | | |
+----------+------------+-----------+
| |
| Board handling |
| |
+-----------------------------------+
Figure 1: The structure of a program using the GNU Go engine
The foundation is a library called libboard.a which provides
efficient handling of a go board with rule checks for moves, with
incremental handling of connected strings of stones and with methods to
efficiently hash go positions.
On top of this, there is a library which helps the application use
smart go files, SGF files, with complete handling of game trees in
memory and in files. This library is called libsgf.a
The main part of the code within GNU Go is the move generation
library which given a position generates a move. This part of the
engine can also be used to manipulate a go position, add or remove
stones, do tactical and strategic reading and to query the engine for
legal moves. These functions are collected into libengine.a.
The game handling code he