| 1 | If you want to write your own interface to GNU Go, or if you want to |
| 2 | create a go application using the GNU Go engine, this chapter is of |
| 3 | interest to you. |
| 4 | |
| 5 | First an overview: GNU Go consists of two parts: the GNU Go @i{engine} |
| 6 | and a program (user interface) which uses this engine. These are linked |
| 7 | together into one binary. The current program implements the following |
| 8 | user modes: |
| 9 | |
| 10 | @itemize @bullet |
| 11 | @item An interactive board playable on ASCII terminals |
| 12 | @item solo play - GNU Go plays against itself |
| 13 | @item replay - a mode which lets the user investigate moves in an existing |
| 14 | SGF file. |
| 15 | @item GMP - Go Modem Protocol, a protocol for automatic play between two |
| 16 | computers. |
| 17 | @item GTP - Go Text Protocol, a more general go protocol, @pxref{GTP}. |
| 18 | @end itemize |
| 19 | @cindex API |
| 20 | |
| 21 | The GNU Go engine can be used in other applications. For example, supplied |
| 22 | with GNU Go is another program using the engine, called @file{debugboard}, |
| 23 | in the directory @file{interface/debugboard/}. The program debugboard lets the |
| 24 | user load SGF files and can then interactively look at different properties of |
| 25 | the position such as group status and eye status. |
| 26 | |
| 27 | The purpose of this Chapter is to show how to interface your own |
| 28 | program such as @code{debugboard} with the GNU Go engine. |
| 29 | |
| 30 | Figure 1 describes the structure of a program using the GNU Go |
| 31 | engine. |
| 32 | |
| 33 | @example |
| 34 | @group |
| 35 | +-----------------------------------+ |
| 36 | | | |
| 37 | | Go application | |
| 38 | | | |
| 39 | +-----+----------+------+ | |
| 40 | | | | | | |
| 41 | | | Game | | | |
| 42 | | | handling | | | |
| 43 | | | | | | |
| 44 | | +----+-----+ | | |
| 45 | | SGF | Move | | |
| 46 | | handling | generation | | |
| 47 | | | | | |
| 48 | +----------+------------+-----------+ |
| 49 | | | |
| 50 | | Board handling | |
| 51 | | | |
| 52 | +-----------------------------------+ |
| 53 | |
| 54 | Figure 1: The structure of a program using the GNU Go engine |
| 55 | |
| 56 | @end group |
| 57 | @end example |
| 58 | |
| 59 | The foundation is a library called @code{libboard.a} which provides |
| 60 | efficient handling of a go board with rule checks for moves, with |
| 61 | incremental handling of connected strings of stones and with methods to |
| 62 | efficiently hash go positions. |
| 63 | |
| 64 | On top of this, there is a library which helps the application use |
| 65 | Smart Game Format (SGF) files, with complete handling of game trees in |
| 66 | memory and in files. This library is called @code{libsgf.a} |
| 67 | |
| 68 | The main part of the code within GNU Go is the move generation |
| 69 | library which given a position generates a move. This part of the |
| 70 | engine can also be used to manipulate a go position, add or remove |
| 71 | stones, do tactical and strategic reading and to query the engine for |
| 72 | legal moves. These functions are collected into @code{libengine.a}. |
| 73 | |
| 74 | The game handling code helps the application programmer keep tracks |
| 75 | of the moves in a game. Games can be saved to |
| 76 | SGF files and then later be read back again. These are also within |
| 77 | @code{libengine.a}. |
| 78 | |
| 79 | The responsibility of the application is to provide the user with a |
| 80 | user interface, graphical or not, and let the user interact with the |
| 81 | engine. |
| 82 | |
| 83 | @menu |
| 84 | * Getting Started:: How to use the engine in your program |
| 85 | * Basic Data Structures:: Basic Data Structures in the Engine |
| 86 | * The Board State:: The board_state `struct' |
| 87 | * Positional Functions:: Functions which manipulate a Position |
| 88 | @end menu |
| 89 | |
| 90 | @node Getting Started |
| 91 | |
| 92 | @section How to use the engine in your own program: getting started |
| 93 | |
| 94 | To use the GNU Go engine in your own program you must include |
| 95 | the file @file{gnugo.h}. This file describes the whole public API. There is |
| 96 | another file, @file{liberty.h}, which describes the internal interface within |
| 97 | the engine. If you want to make a new module within the engine, e.g. for |
| 98 | suggesting moves you will have to include this file also. In this section we |
| 99 | will only describe the public interface. |
| 100 | |
| 101 | @findex init_gnugo |
| 102 | Before you do anything else, you have to call the function |
| 103 | @code{init_gnugo()}. This function initializes everything within the engine. |
| 104 | It takes one parameter: the number of megabytes the engine can use for |
| 105 | the internal hash table. In addition to this the engine will use a few |
| 106 | megabytes for other purposes such as data describing groups (liberties, |
| 107 | life status, etc), eyes and so on. |
| 108 | |
| 109 | @node Basic Data Structures |
| 110 | @section Basic Data Structures in the Engine |
| 111 | @cindex data structures |
| 112 | @cindex position struct |
| 113 | |
| 114 | |
| 115 | There are some basic definitions in gnugo.h which are used |
| 116 | everywhere. The most important of these are the numeric declarations of |
| 117 | colors. Each intersection on the board is represented by one of these: |
| 118 | |
| 119 | @example |
| 120 | @group |
| 121 | |
| 122 | color value |
| 123 | EMPTY 0 |
| 124 | WHITE 1 |
| 125 | BLACK 2 |
| 126 | |
| 127 | @end group |
| 128 | @end example |
| 129 | |
| 130 | There is a macro, @code{OTHER_COLOR(color)} which can be used to get the |
| 131 | other color than the parameter. This macro can only be used on @code{WHITE} |
| 132 | or @code{BLACK}, but not on @code{EMPTY}. |
| 133 | @findex OTHER_COLOR |
| 134 | |
| 135 | GNU Go uses two different representations of the board, for |
| 136 | most purposes a one-dimensional one, but for a few purposes a |
| 137 | two dimensional one (@pxref{Libboard}). The one-dimensional |
| 138 | board was introduced before GNU Go 3.2, while the two-dimensional |
| 139 | board dates back to the ancestral program written by Man Lung Li |
| 140 | before 1995. The API still uses the two-dimensional board, so |
| 141 | the API functions have not changed much since GNU Go 3.0. |
| 142 | |
| 143 | @node The Board State |
| 144 | |
| 145 | @section The board_state struct |
| 146 | @cindex board_state |
| 147 | |
| 148 | A basic data structure in the engine is the @code{board_state} struct. |
| 149 | This structure is internal to the engine and is defined in @file{liberty.h}. |
| 150 | |
| 151 | @example |
| 152 | @group |
| 153 | |
| 154 | typedef unsigned char Intersection; |
| 155 | |
| 156 | struct board_state @{ |
| 157 | int board_size; |
| 158 | |
| 159 | Intersection board[BOARDSIZE]; |
| 160 | int board_ko_pos; |
| 161 | int black_captured; |
| 162 | int white_captured; |
| 163 | |
| 164 | Intersection initial_board[BOARDSIZE]; |
| 165 | int initial_board_ko_pos; |
| 166 | int initial_white_captured; |
| 167 | int initial_black_captured; |
| 168 | int move_history_color[MAX_MOVE_HISTORY]; |
| 169 | int move_history_pos[MAX_MOVE_HISTORY]; |
| 170 | int move_history_pointer; |
| 171 | |
| 172 | float komi; |
| 173 | int move_number; |
| 174 | @}; |
| 175 | |
| 176 | @end group |
| 177 | @end example |
| 178 | |
| 179 | Here @code{Intersection} stores @code{EMPTY}, @code{WHITE} or |
| 180 | @code{BLACK}. It is currently defined as an @code{unsigned char} to make |
| 181 | it reasonably efficient in both storage and access time. The board state |
| 182 | contains an array of @code{Intersection}'s representing the board. |
| 183 | The move history is contained in the struct. Also contained in |
| 184 | the struct is the location of a ko (@code{EMPTY}) if the last |
| 185 | move was not a ko capture, the komi, the number of captures, and |
| 186 | corresponding data for the initial position at the beginning |
| 187 | of the move history. |
| 188 | |
| 189 | @node Positional Functions |
| 190 | |
| 191 | @section Functions which manipulate a Position |
| 192 | |
| 193 | All the functions in the engine that manipulate Positions have names |
| 194 | prefixed by @code{gnugo_}. These functions still use the two-dimensional |
| 195 | representation of the board (@pxref{The Board Array}). Here is a complete |
| 196 | list, as prototyped in @file{gnugo.h}: |
| 197 | |
| 198 | @itemize |
| 199 | @item @code{void init_gnugo(float memory)} |
| 200 | @findex init_gnugo |
| 201 | @quotation |
| 202 | Initialize the gnugo engine. This needs to be called |
| 203 | once only. |
| 204 | @end quotation |
| 205 | @item @code{void gnugo_clear_board(int boardsize)} |
| 206 | @findex gnugo_clear_board |
| 207 | @quotation |
| 208 | Clear the board. |
| 209 | @end quotation |
| 210 | @item @code{void gnugo_set_komi(float new_komi)} |
| 211 | @findex gnugo_set_komi |
| 212 | @quotation |
| 213 | Set the komi. |
| 214 | @end quotation |
| 215 | @item @code{void gnugo_add_stone(int i, int j, int color)} |
| 216 | @findex gnugo_add_stone |
| 217 | @quotation |
| 218 | Place a stone on the board |
| 219 | @end quotation |
| 220 | @item @code{void gnugo_remove_stone(int i, int j)} |
| 221 | @findex gnugo_remove_stone |
| 222 | @quotation |
| 223 | Remove a stone from the board |
| 224 | @end quotation |
| 225 | @item @code{int gnugo_is_pass(int i, int j)} |
| 226 | @findex gnugo_is_pass |
| 227 | @quotation |
| 228 | Return true if (i,j) is PASS_MOVE |
| 229 | @end quotation |
| 230 | @item @code{void gnugo_play_move(int i, int j, int color)} |
| 231 | @findex gnugo_play_move |
| 232 | @quotation |
| 233 | Play a move and start the clock |
| 234 | @end quotation |
| 235 | @item @code{int gnugo_undo_move(int n)} |
| 236 | @findex gnugo_undo_move |
| 237 | @quotation |
| 238 | Undo n permanent moves. Returns 1 if successful and 0 if it fails. |
| 239 | If n moves cannot be undone, no move is undone. |
| 240 | @end quotation |
| 241 | @item @code{int gnugo_play_sgfnode(SGFNode *node, int to_move)} |
| 242 | @findex gnugo_play_sgfnode |
| 243 | @quotation |
| 244 | Perform the moves and place the stones from the SGF node on the |
| 245 | board. Return the color of the player whose turn it is to move. |
| 246 | @end quotation |
| 247 | @item @code{int gnugo_play_sgftree(SGFNode *root, int *until, SGFNode **curnode)} |
| 248 | @findex gnugo_play_sgftree |
| 249 | @quotation |
| 250 | Play the moves in ROOT UNTIL movenumber is reached. Return the color of the |
| 251 | player whose turn it is to move. |
| 252 | @end quotation |
| 253 | @item @code{int gnugo_is_legal(int i, int j, int color)} |
| 254 | @findex gnugo_is_legal |
| 255 | @quotation |
| 256 | Interface to @code{is_legal()}. |
| 257 | @end quotation |
| 258 | @item @code{int gnugo_is_suicide(int i, int j, int color)} |
| 259 | @findex gnugo_is_suicide |
| 260 | @quotation |
| 261 | Interface to @code{is_suicide()}. |
| 262 | @end quotation |
| 263 | @item @code{int gnugo_placehand(int handicap)} |
| 264 | @findex gnugo_placehand |
| 265 | @quotation |
| 266 | Interface to placehand. Sets up handicap pieces and |
| 267 | returns the number of placed handicap stones. |
| 268 | @end quotation |
| 269 | @item @code{void gnugo_recordboard(SGFNode *root)} |
| 270 | @findex gnugo_recordboard |
| 271 | @quotation |
| 272 | Interface to @code{sgffile_recordboard()} |
| 273 | @end quotation |
| 274 | @item @code{int gnugo_sethand(int handicap, SGFNode *node)} |
| 275 | @findex gnugo_sethand |
| 276 | @quotation |
| 277 | Interface to placehand. Sets up handicap stones and |
| 278 | returns the number of placed handicap stones, updating the sgf file |
| 279 | @end quotation |
| 280 | @item @code{float gnugo_genmove(int *i, int *j, int color, int *resign)} |
| 281 | @findex gnugo_genmove |
| 282 | @quotation |
| 283 | Interface to @code{genmove()}. |
| 284 | @end quotation |
| 285 | @item @code{int gnugo_attack(int m, int n, int *i, int *j)} |
| 286 | @findex gnugo_attack |
| 287 | @quotation |
| 288 | Interface to @code{attack()}. |
| 289 | @end quotation |
| 290 | @item @code{int gnugo_find_defense(int m, int n, int *i, int *j)} |
| 291 | @findex gnugo_find_defense |
| 292 | @quotation |
| 293 | Interface to @code{find_defense()}. |
| 294 | @end quotation |
| 295 | @item @code{void gnugo_who_wins(int color, FILE *outfile)} |
| 296 | @findex gnugo_who_wins |
| 297 | @quotation |
| 298 | Interface to @code{who_wins()}. |
| 299 | @end quotation |
| 300 | @item @code{float gnugo_estimate_score(float *upper, float *lower)} |
| 301 | @findex gnugo_estimate_score |
| 302 | @quotation |
| 303 | Put upper and lower score estimates into @code{*upper}, @code{*lower} and |
| 304 | return the average. A positive score favors white. In computing |
| 305 | the upper bound, @code{CRITICAL} dragons are awarded to white; in |
| 306 | computing the lower bound, they are awarded to black. |
| 307 | @end quotation |
| 308 | @item @code{void gnugo_examine_position(int color, int how_much)} |
| 309 | @findex gnugo_examine_position |
| 310 | @quotation |
| 311 | Interface to @code{examine_position}. |
| 312 | @end quotation |
| 313 | @item @code{int gnugo_get_komi()} |
| 314 | @findex gnugo_get_komi |
| 315 | @quotation |
| 316 | Report the komi. |
| 317 | @end quotation |
| 318 | @item @code{void gnugo_get_board(int b[MAX_BOARD][MAX_BOARD])} |
| 319 | @findex gnugo_get_board |
| 320 | @quotation |
| 321 | Place the board into the @samp{b} array. |
| 322 | @end quotation |
| 323 | @item @code{int gnugo_get_boardsize()} |
| 324 | @findex gnugo_get_boardsize |
| 325 | @quotation |
| 326 | Report the board size. |
| 327 | @end quotation |
| 328 | @item @code{int gnugo_get_move_number()} |
| 329 | @findex gnugo_get_move_number |
| 330 | @quotation |
| 331 | Report the move number. |
| 332 | @end quotation |
| 333 | @end itemize |
| 334 | |
| 335 | @section Game handling |
| 336 | |
| 337 | The functions (in @pxref{Positional Functions}) are all that are needed to |
| 338 | create a fully functional go program. But to make the life easier for the |
| 339 | programmer, there is a small set of functions specially designed for handling |
| 340 | ongoing games. |
| 341 | |
| 342 | The data structure describing an ongoing game is the @code{Gameinfo}. It |
| 343 | is defined as follows: |
| 344 | |
| 345 | @example |
| 346 | @group |
| 347 | |
| 348 | typedef struct @{ |
| 349 | int handicap; |
| 350 | |
| 351 | int to_move; /* whose move it currently is */ |
| 352 | SGFTree game_record; /* Game record in sgf format. */ |
| 353 | |
| 354 | int computer_player; /* BLACK, WHITE, or EMPTY (used as BOTH) */ |
| 355 | |
| 356 | char outfilename[128]; /* Trickle file */ |
| 357 | FILE *outfile; |
| 358 | @} Gameinfo; |
| 359 | |
| 360 | @end group |
| 361 | @end example |
| 362 | |
| 363 | The meaning of @code{handicap} should be obvious. @code{to_move} is the |
| 364 | color of the side whose turn it is to move. |
| 365 | |
| 366 | The SGF tree @code{game_record} is used to store all the moves in the entire |
| 367 | game, including a header node which contains, among other things, komi |
| 368 | and handicap. |
| 369 | |
| 370 | If one or both of the opponents is the computer, the field |
| 371 | @code{computer_player} is used. Otherwise it can be ignored. |
| 372 | |
| 373 | GNU Go can use a trickle file to continuously save all the moves of an |
| 374 | ongoing game. This file can also contain information about internal |
| 375 | state of the engine such as move reasons for various locations or move |
| 376 | valuations. The name of this file should |
| 377 | be stored in @code{outfilename} and the file pointer to the open file is |
| 378 | stored in @code{outfile}. If no trickle file is used, |
| 379 | @code{outfilename[0]} will contain a null character and @code{outfile} |
| 380 | will be set to @code{NULL}. |
| 381 | |
| 382 | @subsection Functions which manipulate a Gameinfo |
| 383 | |
| 384 | All the functions in the engine that manipulate Gameinfos have names |
| 385 | prefixed by @code{gameinfo_}. Here is a complete list, as prototyped in |
| 386 | @file{gnugo.h}: |
| 387 | |
| 388 | @itemize |
| 389 | @item @code{void gameinfo_clear(Gameinfo *ginfo, int boardsize, float komi)} |
| 390 | @findex gameinfo_clear |
| 391 | @quotation |
| 392 | Initialize the @code{Gameinfo} structure. |
| 393 | @end quotation |
| 394 | @item @code{void gameinfo_print(Gameinfo *ginfo)} |
| 395 | @findex gameinfo_print |
| 396 | @quotation |
| 397 | Print a gameinfo. |
| 398 | @end quotation |
| 399 | @item @code{void gameinfo_load_sgfheader(Gameinfo *gameinfo, SGFNode *head)} |
| 400 | @findex gameinfo_load_sgfheader |
| 401 | @quotation |
| 402 | Reads header info from sgf structure and sets the appropriate variables. |
| 403 | @end quotation |
| 404 | @item @code{void gameinfo_play_move(Gameinfo *ginfo, int i, int j, int color)} |
| 405 | @findex gameinfo_play_move |
| 406 | @quotation |
| 407 | Make a move in the game. Return 1 if the move was legal. In that |
| 408 | case the move is actually done. Otherwise return 0. |
| 409 | @end quotation |
| 410 | @item @code{int gameinfo_play_sgftree_rot(Gameinfo *gameinfo, SGFNode *head, const char *untilstr, int orientation)} |
| 411 | @findex gameinfo_play_sgftree_rot |
| 412 | @quotation |
| 413 | Play the moves in an SGF tree. Walk the main variation, actioning the |
| 414 | properties into the playing board. Returns the color of the next move to be |
| 415 | made. Head is an sgf tree. Untilstr is an optional string of the form either |
| 416 | 'L12' or '120' which tells it to stop playing at that move or move |
| 417 | number. When debugging, this is the location of the move being examined. |
| 418 | @end quotation |
| 419 | @item @code{int gameinfo_play_sgftree(Gameinfo *gameinfo, SGFNode *head, const char *untilstr)} |
| 420 | @findex gameinfo_play_sgftree |
| 421 | @quotation |
| 422 | Same as previous function, using standard orientation. |
| 423 | @end quotation |
| 424 | @end itemize |
| 425 | |
| 426 | |