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:

  * An interactive board playable on ASCII terminals

  * solo play - GNU Go plays against itself

  * replay - a mode which lets the user investigate moves in an existing SGF file.

  * GMP - Go Modem Protocol, a protocol for automatic play between two computers.

  * GTP - Go Text Protocol, a more general go protocol, see GTP.

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 Game Format (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 helps the application programmer keep tracks of the moves in a game. Games can be saved to SGF files and then later be read back again. These are also within libengine.a.

The responsibility of the application is to provide the user with a user interface, graphical or not, and let the user interact with the engine.

How to use the engine in your own program: getting started
==========================================================

To use the GNU Go engine in your own program you must include the file gnugo.h. This file describes the whole public API. There is another file, liberty.h, which describes the internal interface within the engine. If you want to make a new module within the engine, e.g.  for suggesting moves you will have to include this file also. In this section we will only describe the public interface.

Before you do anything else, you have to call the function init_gnugo(). This function initializes everything within the engine. It takes one parameter: the number of megabytes the engine can use for the internal hash table. In addition to this the engine will use a few megabytes for other purposes such as data describing groups (liberties, life status, etc), eyes and so on.

Basic Data Structures in the Engine
===================================

There are some basic definitions in gnugo.h which are used everywhere. The most important of these are the numeric declarations of colors. Each intersection on the board is represented by one of these:

          color              value
          EMPTY                0
          WHITE                1
          BLACK                2

There is a macro, OTHER_COLOR(color) which can be used to get the other color than the parameter. This macro can only be used on WHITE or BLACK, but not on EMPTY.

GNU Go uses two different representations of the board, for most purposes a one-dimensional one, but for a few purposes a two dimensional one (see Libboard). The one-dimensional board was introduced before GNU Go 3.2, while the two-dimensional board dates back to the ancestral program written by Man Lung Li before 1995. The API still uses the two-dimensional board, so the API functions have not changed much since GNU Go 3.0.

The board_state struct
======================

A basic data structure in the engine is the board_state struct. This structure is internal to the engine and is defined in liberty.h.

          typedef unsigned char Intersection;

          struct board_state {
            int board_size;

            Intersection board[BOARDSIZE];
            int board_ko_pos;
            int black_captured;
            int white_captured;

            Intersection initial_board[BOARDSIZE];
            int initial_board_ko_pos;
            int initial_white_captured;
            int initial_black_captured;
            int move_history_color[MAX_MOVE_HISTORY];
            int move_history_pos[MAX_MOVE_HISTORY];
            int move_history_pointer;

            float komi;
            int move_number;
          };

Here Intersection stores EMPTY, WHITE or BLACK. It is currently defined as an unsigned char to make it reasonably efficient in both storage and access time. The board state contains an array of Intersection's representing the board. The move history is contained in the struct. Also contained in the struct is the location of a ko (EMPTY) if the last move was not a ko capture, the komi, the number of captures, and corresponding data for the initial position at the beginning of the move history.

Functions which manipulate a Position
=====================================

All the functions in the engine that manipulate Positions have names prefixed by gnugo_. These functions still use the two-dimensional representation of the board (see The Board Array). Here is a complete list, as prototyped in gnugo.h:

  * void init_gnugo(float memory)

          Initialize the gnugo engine. This needs to be called once only.

  * void gnugo_clear_board(int boardsize)

          Clear the board.

  * void gnugo_set_komi(float new_komi)

          Set the komi.

  * void gnugo_add_stone(int i, int j, int color)

          Place a stone on the board

  * void gnugo_remove_stone(int i, int j)

          Remove a stone from the board

  * int gnugo_is_pass(int i, int j)

          Return true if (i,j) is PASS_MOVE

  * void gnugo_play_move(int i, int j, int color)

          Play a move and start the clock

  * int gnugo_undo_move(int n)

          Undo n permanent moves. Returns 1 if successful and 0 if it fails. If n moves cannot be undone, no move is undone.

  * int gnugo_play_sgfnode(SGFNode *node, int to_move)

          Perform the moves and place the stones from the SGF node on the board. Return the color of the player whose turn it is to move.

  * int gnugo_play_sgftree(SGFNode *root, int *until, SGFNode **curnode)

          Play the moves in ROOT UNTIL movenumber is reached.  Return the color of the player whose turn it is to move.

  * int gnugo_is_legal(int i, int j, int color)

          Interface to is_legal().

  * int gnugo_is_suicide(int i, int j, int color)

          Interface to is_suicide().

  * int gnugo_placehand(int handicap)

          Interface to placehand. Sets up handicap pieces and returns the number of placed handicap stones.

  * void gnugo_recordboard(SGFNode *root)

          Interface to sgffile_recordboard()

  * int gnugo_sethand(int handicap, SGFNode *node)

          Interface to placehand. Sets up handicap stones and returns the number of placed handicap stones, updating the sgf file

  * int gnugo_genmove(int *i, int *j, int color)

          Interface to genmove().

  * int gnugo_attack(int m, int n, int *i, int *j)

          Interface to attack().

  * int gnugo_find_defense(int m, int n, int *i, int *j)

          Interface to find_defense().

  * void gnugo_who_wins(int color, FILE *outfile)

          Interface to who_wins().

  * float gnugo_estimate_score(float *upper, float *lower)

          Put upper and lower score estimates into *upper, *lower and return the average. A positive score favors white. In computing the upper bound, CRITICAL dragons are awarded to white; in computing the lower bound, they are awarded to black.

  * void gnugo_examine_position(int color, int how_much)

          Interface to examine_position.

  * int gnugo_get_komi()

          Report the komi.

  * void gnugo_get_board(int b[MAX_BOARD][MAX_BOARD])

          Place the board into the b array.

  * int gnugo_get_boardsize()

          Report the board size.

  * int gnugo_get_move_number()

          Report the move number.

Game handling
=============

The functions (in see Positional Functions) are all that are needed to create a fully functional go program.  But to make the life easier for the programmer, there is a small set of functions specially designed for handling ongoing games.

The data structure describing an ongoing game is the Gameinfo. It is defined as follows:

     typedef struct {
       int       handicap;

       int       to_move;            /* whose move it currently is */
       SGFTree   game_record;        /* Game record in sgf format. */

       int       computer_player;    /* BLACK, WHITE, or EMPTY (used as BOTH) */

       char      outfilename[128];   /* Trickle file */
       FILE      *outfile;
     } Gameinfo;

The meaning of handicap should be obvious. to_move is the color of the side whose turn it is to move.

The SGF tree game_record is used to store all the moves in the entire game, including a header node which contains, among other things, komi and handicap.

If one or both of the opponents is the computer, the field computer_player is used. Otherwise it can be ignored.

GNU Go can use a trickle file to continuously save all the moves of an ongoing game. This file can also contain information about internal state of the engine such as move reasons for various locations or move valuations. The name of this file should be stored in outfilename and the file pointer to the open file is stored in outfile. If no trickle file is used, outfilename[0] will contain a null character and outfile will be set to NULL.

Functions which manipulate a Gameinfo
-------------------------------------

All the functions in the engine that manipulate Gameinfos have names prefixed by gameinfo_.  Here is a complete list, as prototyped in gnugo.h:

  * void gameinfo_clear(Gameinfo *ginfo, int boardsize, float komi)

          Initialize the Gameinfo structure.

  * void gameinfo_print(Gameinfo *ginfo)

          Print a gameinfo.

  * void gameinfo_load_sgfheader(Gameinfo *gameinfo, SGFNode *head)

          Reads header info from sgf structure and sets the appropriate variables.

  * void gameinfo_play_move(Gameinfo *ginfo, int i, int j, int color)

          Make a move in the game. Return 1 if the move was legal. In that case the move is actually done. Otherwise return 0.

  * int gameinfo_play_sgftree_rot(Gameinfo *gameinfo, SGFNode *head, const char *untilstr, int orientation)

          Play the moves in an SGF tree. Walk the main variation, actioning the properties into the playing board. Returns the color of the next move to be made. Head is an sgf tree. Untilstr is an optional string of the form either 'L12' or '120' which tells it to stop playing at that move or move number. When debugging, this is the location of the move being examined.

  * int gameinfo_play_sgftree(Gameinfo *gameinfo, SGFNode *head, const char *untilstr)

          Same as previous function, using standard orientation.