[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

# 18. Utility Functions

In this Chapter, we document some of the utilities which may be called from the GNU Go engine.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

## 18.1 General Utilities

Utility functions from ‘`engine/utils.c`’. Many of these functions underlie autohelper functions (see section Autohelper Functions).

- `void change_dragon_status(int dr, int status)`

  > Change the status of all the stones in the dragon at `dr`.

- `int defend_against(int move, int color, int apos)`

  > Check whether a move at `move` stops the enemy from playing at (apos).

- `int cut_possible(int pos, int color)`

  > Returns true if `color` can cut at `pos`, or if connection through `pos` is inhibited. This information is collected by `find_cuts()`, using the B patterns in the connections database.

- `int does_attack(int move, int str)`

  > returns true if the move at `move` attacks `str`. This means that it captures the string, and that `str` is not already dead.

- `int does_defend(int move, int str)`

  > `does_defend(move, str)` returns true if the move at `move` defends `str`. This means that it defends the string, and that `str` can be captured if no defense is made.

- `int somewhere(int color, int last_move, ...)`

  > Example: `somewhere(WHITE, 2, apos, bpos, cpos)`. Returns true if one of the vertices listed satisfies `board[pos]==color`. Here num_moves is the number of moves minus one. If the check is true the dragon is not allowed to be dead. This check is only valid if `stackp==0`.

- `int visible_along_edge(int color, int apos, int bpos)`

  > Search along the edge for the first visible stone. Start at apos and move in the direction of bpos. Return 1 if the first visible stone is of the given color. It is required that apos and bpos are at the same distance from the edge.

- `int test_symmetry_after_move(int move, int color, int strict)`

  > Is the board symmetric (or rather antisymmetric) with respect to mirroring in tengen after a specific move has been played? If the move is PASS_MOVE, check the current board. If strict is set we require that each stone is matched by a stone of the opposite color at the mirrored vertex. Otherwise we only require that each stone is matched by a stone of either color.

- `int play_break_through_n(int color, int num_moves, ...)`

  > The function `play_break_through_n()` plays a sequence of moves, alternating between the players and starting with color. After having played through the sequence, the three last coordinate pairs gives a position to be analyzed by `break_through()`, to see whether either color has managed to enclose some stones and/or connected his own stones. If any of the three last positions is empty, it’s assumed that the enclosure has failed, as well as the attempt to connect. If one or more of the moves to play turns out to be illegal for some reason, the rest of the sequence is played anyway, and `break_through()` is called as if nothing special happened. Like `break_through()`, this function returns 1 if the attempt to break through was succesful and 2 if it only managed to cut through.

- `int play_attack_defend_n(int color, int do_attack, int num_moves, ...)`
- `int play_attack_defend2_n(int color, int do_attack, int num_moves, ...)`

  > The function `play_attack_defend_n()` plays a sequence of moves, alternating between the players and starting with `color`. After having played through the sequence, the last coordinate pair gives a target to attack or defend, depending on the value of do_attack. If there is no stone present to attack or defend, it is assumed that it has already been captured. If one or more of the moves to play turns out to be illegal for some reason, the rest of the sequence is played anyway, and attack/defense is tested as if nothing special happened. Conversely, `play_attack_defend2_n()` plays a sequence of moves, alternating between the players and starting with `color`. After having played through the sequence, the two last coordinate pairs give two targets to simultaneously attack or defend, depending on the value of do_attack. If there is no stone present to attack or defend, it is assumed that it has already been captured. If one or more of the moves to play turns out to be illegal for some reason, the rest of the sequence is played anyway, and attack/defense is tested as if nothing special happened. A typical use of these functions is to set up a ladder in an autohelper and see whether it works or not.

- `int play_connect_n(int color, int do_connect, int num_moves, ...)`

  > Plays a sequence of moves, alternating between the players and starting with `color`. After having played through the sequence, the two last coordinates give two targets that should be connected or disconnected, depending on the value of do_connect. If there is no stone present to connect or disconnect, it is assumed that the connection has failed. If one or more of the moves to play turns out to be illegal for some reason, the rest of the sequence is played anyway, and connection/disconnection is tested as if nothing special happened. Ultimately the connection is decided by the functions `string_connect` and `disconnect` (see section Connection Reading).

- `void set_depth_values(int level)`

  > It is assumed in reading a ladder if `stackp >= depth` that as soon as a bounding stone is in atari, the string is safe. Similar uses are made of the other depth parameters such as `backfill_depth` and so forth. In short, simplifying assumptions are made when `stackp` is large. Unfortunately any such scheme invites the “horizon effect,” in which a stalling move is perceived as a win, by pushing the refutation past the “horizon”—the value of `stackp` in which the reading assumptions are relaxed. To avoid the depth it is sometimes necessary to increase the depth parameters. This function can be used to set the various reading depth parameters. If `mandated_depth_value` is not -1 that value is used; otherwise the depth values are set as a function of level. The parameter `mandated_depth_value` can be set at the command line to force a particular value of depth; normally it is -1.

- `void modify_depth_values(int n)`

  > Modify the various tactical reading depth parameters. This is typically used to avoid horizon effects. By temporarily increasing the depth values when trying some move, one can avoid that an irrelevant move seems effective just because the reading hits a depth limit earlier than it did when reading only on relevant moves.

- `void increase_depth_values(void)`

  > `modify_depth_values(1)`.

- `void decrease_depth_values(void)`

  > `modify_depth_values(-1)`.

- `void restore_depth_values()`

  > Sets `depth` and so forth to their saved values.

- `void set_temporary_depth_values(int d, int b, int b2, int bc, int ss, int br, int f, int k)`

  > Explicitly set the depth values. This function is currently never called.

- `int confirm_safety(int move, int color, int *defense_point, char safe_stones[BOARDMAX])`

  > Check that the move at color doesn’t involve any kind of blunder, regardless of size.

- `float blunder_size(int move, int color, int *defense_point, char safe_stones[BOARDMAX])`

  > This function will detect some blunders. If the move reduces the number of liberties of an adjacent friendly string, there is a danger that the move could backfire, so the function checks that no friendly worm which was formerly not attackable becomes attackable, and it checks that no opposing worm which was not defendable becomes defendable. It returns the estimated size of the blunder, or 0.0 if nothing bad has happened. The array `safe_stones[]` contains the stones that are supposedly safe after `move`. It may be `NULL`. For use when called from `fill_liberty()`, this function may optionally return a point of defense, which, if taken, will presumably make the move at `move` safe on a subsequent turn.

- `int double_atari(int move, int color, float *value, char safe_stones[BOARDMAX])`

  > Returns true if a move by (color) fits the following shape:

  >         X*        (O=color)
  >         OX

  > capturing one of the two ‘`X`’ strings. The name is a slight misnomer since this includes attacks which are not necessarily double ataris, though the common double atari is the most important special case. If `safe_stones != NULL`, then only attacks on stones marked as safe are tried. The value of the double atari attack is returned in value (unless value is `NULL`), and the attacked stones are marked unsafe.

- `void unconditional_life(int unconditional_territory[BOARDMAX], int color)`

  > Find those worms of the given color that can never be captured, even if the opponent is allowed an arbitrary number of consecutive moves. The coordinates of the origins of these worms are written to the worm arrays and the number of non-capturable worms is returned. The algorithm is to cycle through the worms until none remains or no more can be captured. A worm is removed when it is found to be capturable, by letting the opponent try to play on all its liberties. If the attack fails, the moves are undone. When no more worm can be removed in this way, the remaining ones are unconditionally alive. After this, unconditionally dead opponent worms and unconditional territory are identified. To find these, we continue from the position obtained at the end of the previous operation (only unconditionally alive strings remain for color) with the following steps:

  > 1. Play opponent stones on all liberties of the unconditionally alive strings except where illegal. (That the move order may determine exactly which liberties can be played legally is not important. Just pick an arbitrary order).
  > 2. Recursively extend opponent strings in atari, except where this would be suicide.
  > 3. Play an opponent stone anywhere it can get two empty neighbors. (I.e. split big eyes into small ones).
  > 4. an opponent stone anywhere it can get one empty neighbor. (I.e. reduce two space eyes to one space eyes.) Remaining opponent strings in atari and remaining liberties of the unconditionally alive strings constitute the unconditional territory. Opponent strings from the initial position placed on unconditional territory are unconditionally dead. On return, `unconditional_territory[][]` is 1 where color has unconditionally alive stones, 2 where it has unconditional territory, and 0 otherwise.

- `void who_wins(int color, FILE *outfile)`

  > Score the game and determine the winner

- `void find_superstring(int str, int *num_stones, int *stones)`

  > Find the stones of an extended string, where the extensions are through the following kinds of connections:

  > 1. Solid connections (just like ordinary string).

  >            OO

  > 2. Diagonal connection or one space jump through an intersection where an opponent move would be suicide or self-atari.

  >            ...
  >            O.O
  >            XOX
  >            X.X

  > 3. Bamboo joint.

  >            OO
  >            ..
  >            OO

  > 4. Diagonal connection where both adjacent intersections are empty.

  >            .O
  >            O.

  > 5. Connection through adjacent or diagonal tactically captured stones. Connections of this type are omitted when the superstring code is called from reading.c, but included when the superstring code is called from owl.c

- `void find_superstring_liberties(int str, int *num_libs, int *libs, int liberty_cap)`

  > This function computes the superstring at `str` as described above, but omitting connections of type 5. Then it constructs a list of liberties of the superstring which are not already liberties of `str`. If `liberty_cap` is nonzero, only liberties of substrings of the superstring which have fewer than `liberty_cap` liberties are generated.

- `void find_proper_superstring_liberties(int str, int *num_libs, int *libs, int liberty_cap)`

  > This function is the same as find_superstring_liberties, but it omits those liberties of the string `str`, presumably since those have already been treated elsewhere. If `liberty_cap` is nonzero, only liberties of substrings of the superstring which have at most `liberty_cap` liberties are generated.

- `void find_superstring_stones_and_liberties(int str, int *num_stones, int *stones, int *num_libs, int *libs, int liberty_cap)`

  > This function computes the superstring at `str` as described above, but omitting connections of type 5. Then it constructs a list of liberties of the superstring which are not already liberties of `str`. If liberty_cap is nonzero, only liberties of substrings of the superstring which have fewer than liberty_cap liberties are generated.

- `void superstring_chainlinks(int str, int *num_adj, int adjs[MAXCHAIN], int liberty_cap)`

  > analogous to chainlinks, this function finds boundary chains of the superstring at `str`, including those which are boundary chains of `str` itself. If `liberty_cap != 0`, only those boundary chains with `<= liberty_cap` liberties are reported.

- `void proper_superstring_chainlinks(int str, int *num_adj, int adjs[MAXCHAIN], int liberty_cap)`

  > analogous to chainlinks, this function finds boundary chains of the superstring at `str`, omitting those which are boundary chains of `str` itself. If `liberty_cap != 0`, only those boundary chains with `<= liberty_cap` liberties are reported.

- `void start_timer(int n)`

  > Start a timer. GNU Go has four internal timers available for assessing the time spent on various tasks.

- `double time_report(int n, const char *occupation, int move, double mintime)`

  > Report time spent and restart the timer. Make no report if elapsed time is less than mintime.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

## 18.2 Print Utilities

Functions in ‘`engine/printutils.c`’ do formatted printing similar to `printf` and its allies. The following formats are recognized:

- `%c`, `%d`, `%f`, `%s`, `%x`

  > These have their usual meaning in formatted output, printing a character, integer, float, string or hexadecimal, respectively.

- `%o`

  > ‘Outdent.’ Normally output is indented by `2*stackp` spaces, so that the depth can be seen at a glance in traces. At the beginning of a format, this `%o` inhibits the indentation.

- `%H`

  > Print a hashvalue.

- `%C`

  > Print a color as a string.

- `%m`, `%2m` (synonyms)

  > Takes 2 integers and writes a move, using the two dimensional board representation (see section The Board Array)

- `%1m`

  > Takes 1 integers and writes a move, using the one dimensional board representation (see section The Board Array)

We list the non statically declared functions in ‘`printutils.c`’.

- `void gfprintf(FILE *outfile, const char *fmt, ...)`

  > Formatted output to ‘`outfile`’.

- `int gprintf(const char *fmt, ...)`

  > Formatted output to stderr. Always returns 1 to allow use in short-circuit logical expressions.

- `int mprintf(const char *fmt, ...)`

  > Formatted output to stdout.

- `DEBUG(level, fmt, args...)`

  > If `level & debug`, do formatted output to stderr. Otherwise, ignore.

- `void abortgo(const char *file, int line, const char *msg, int pos)`

  > Print debugging output in an error situation, then exit.

- `const char * color_to_string(int color)`

  > Convert a color value to a string

- `const char * location_to_string(int pos)`

  > Convert a location to a string

- `void location_to_buffer(int pos, char *buf)`

  > Convert a location to a string, writing to a buffer.

- `int string_to_location(int boardsize, char *str, int *m, int *n)`

  > Get the `(m, n)` coordinates in the standard GNU Go coordinate system from the string `str`. This means that ‘`m`’ is the nth row from the top and ‘`n`’ is the column. Both coordinates are between 0 and `boardsize-1`, inclusive. Return 1 if ok, otherwise return 0;

- `int is_hoshi_point(int m, int n)` True if the coordinate is a hoshi point.
- `void draw_letter_coordinates(FILE *outfile)` Print a line with coordinate letters above the board.
- `void simple_showboard(FILE *outfile)`

  > Bare bones version of `showboard(0)`. No fancy options, no hint of color, and you can choose where to write it.

The following functions are in ‘`showbord.c`’. Not all public functions in that file are listed here.

- `void showboard(int xo)`

  > Show go board.

  >     xo=0:      black and white XO board for ascii game
  >     xo=1:      colored dragon display
  >     xo=2:      colored eye display
  >     xo=3:      colored owl display
  >     xo=4:      colored matcher status display

- `const char * status_to_string(int status)`

  > Convert a status value to a string.

- `const char * safety_to_string(int status)`

  > Convert a safety value to a string.

- `const char * result_to_string(int result)`

  > Convert a read result to a string

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

## 18.3 Board Utilities

The functions documented in this section are from ‘`board.c`’. Other functions in ‘`board.c`’ are described in See section Some Board Functions.

- `void store_board(struct board_state *state)`

  > Save board state.

- `void restore_board(struct board_state *state)`

  > Restore a saved board state.

- `void clear_board(void)`

  > Clear the internal board.

- `void dump_stack(void)`

  > for use under GDB prints the move stack.

- `void add_stone(int pos, int color)`

  > Place a stone on the board and update the board_hash. This operation destroys all move history.

- `void remove_stone(int pos)`

  > Remove a stone from the board and update the board_hash. This operation destroys the move history.

- `int is_pass(int pos)`

  > Test if the move is a pass or not. Return 1 if it is.

- `int is_legal(int pos, int color)`

  > Determines whether the move `color` at `pos` is legal.

- `int is_suicide(int pos, int color)`

  > Determines whether the move `color` at `pos` would be a suicide. This is the case if

  > 1. There is no neighboring empty intersection.
  > 2. There is no neighboring opponent string with exactly one liberty.
  > 3. There is no neighboring friendly string with more than one liberty.

- `int is_illegal_ko_capture(int pos, int color)`

  > Determines whether the move `color` at `pos` would be an illegal ko capture.

- `int is_edge_vertex(int pos)`

  > Determine whether vertex is on the edge.

- `int edge_distance(int pos)`

  > Distance to the edge.

- `int is_corner_vertex(int pos)`

  > Determine whether vertex is a corner.

- `int get_komaster()`
- `int get_kom_pos()`

  > Public functions to access the variable `komaster` and `kom_pos`, which are static in ‘`board.c`’.

Next we come to `countlib()` and its allies, which address the problem of determining how many liberties a string has. Although `countlib()` addresses this basic question, other functions can often get the needed information more quickly, so there are a number of different functions in this family.

- `int countlib(int str)`

  > Count the number of liberties of the string at `pos`. There must be a stone at this location.

- `int findlib(int str, int maxlib, int *libs)`

  > Find the liberties of the string at `str`. This location must not be empty. The locations of up to maxlib liberties are written into `libs[]`. The full number of liberties is returned. If you want the locations of all liberties, whatever their number, you should pass `MAXLIBS` as the value for `maxlib` and allocate space for `libs[]` accordingly.

- `int fastlib(int pos, int color, int ignore_captures)`

  > Count the liberties a stone of the given color would get if played at `pos`. The intent of this function is to be as fast as possible, not necessarily complete. But if it returns a positive value (meaning it has succeeded), the value is guaranteed to be correct. Captures are ignored based if the `ignore_captures` field is nonzero. The location `pos` must be empty. The function fails if there are more than two neighbor strings of the same color. In this case, the return value is -1. Captures are handled in a very limited way, so if ignore_capture is 0, and a capture is required, it will often return -1.

- `int approxlib(int pos, int color, int maxlib, int *libs)`

  > Find the liberties a stone of the given color would get if played at `pos`, ignoring possible captures of opponent stones. The location `pos` must be empty. If `libs != NULL`, the locations of up to `maxlib` liberties are written into `libs[]`. The counting of liberties may or may not be halted when `maxlib` is reached. The number of liberties found is returned, which may be less than the total number of liberties if `maxlib` is small. If you want the number or the locations of all liberties, however many they are, you should pass `MAXLIBS` as the value for maxlib and allocate space for `libs[]` accordingly.

- `int accuratelib(int pos, int color, int maxlib, int *libs)`

  > Find the liberties a stone of the given color would get if played at `pos`. This function takes into consideration all captures. Its return value is exact in that sense it counts all the liberties, unless `maxlib` allows it to stop earlier. The location `pos` must be empty. If `libs != NULL`, the locations of up to `maxlib` liberties are written into `libs[]`. The counting of liberties may or may not be halted when `maxlib` is reached. The number of found liberties is returned. This function guarantees that liberties which are not results of captures come first in `libs[]` array. To find whether all the liberties starting from a given one are results of captures, one may use `if (board[libs[k]] != EMPTY)` construction. If you want the number or the locations of all liberties, however many they are, you should pass `MAXLIBS` as the value for `maxlib` and allocate space for `libs[]` accordingly.

Next we have some general utility functions.

- `int count_common_libs(int str1, int str2)`

  > Find the number of common liberties of the two strings.

- `int find_common_libs(int str1, int str2, int maxlib, int *libs)`

  > Find the common liberties of the two strings. The locations of up to `maxlib` common liberties are written into `libs[]`. The full number of common liberties is returned. If you want the locations of all common liberties, whatever their number, you should pass `MAXLIBS` as the value for `maxlib` and allocate space for `libs[]` accordingly.

- `int have_common_lib(int str1, int str2, int *lib)`

  > Determine whether two strings have at least one common liberty. If they do and `lib != NULL`, one common liberty is returned in `*lib`.

- `int countstones(int str)`

  > Report the number of stones in a string.

- `int findstones(int str, int maxstones, int *stones)`

  > Find the stones of the string at `str`. The location must not be empty. The locations of up to maxstones stones are written into `stones[]`. The full number of stones is returned.

- `int chainlinks(int str, int adj[MAXCHAIN])`

  > This very useful function returns (in the `adj` array) the chains surrounding the string at `str`. The number of chains is returned.

- `int chainlinks2(int str, int adj[MAXCHAIN], int lib)`

  > Returns (in `adj` array) those chains surrounding the string at `str`, which has exactly `lib` liberties. The number of such chains is returned.

- `int chainlinks3(int str, int adj[MAXCHAIN], int lib)`

  > Returns (in `adj` array) the chains surrounding the string at `str`, which have less or equal `lib` liberties. The number of such chains is returned.

- `int extended_chainlinks(int str, int adj[MAXCHAIN], int both_colors)`

  > Returns (in the `adj` array) the opponent strings being directly adjacent to `str` or having a common liberty with `str`. The number of such strings is returned. If the both_colors parameter is true, also own strings sharing a liberty are returned.

- `int find_origin(int str)`

  > Find the origin of a string, i.e. the point with the smallest 1D board coordinate. The idea is to have a canonical reference point for a string.

- `int is_self_atari(int pos, int color)`

  > Determine whether a move by color at `pos` would be a self atari, i.e. whether it would get more than one liberty. This function returns true also for the case of a suicide move.

- `int liberty_of_string(int pos, int str)`

  > Returns true if `pos` is a liberty of the string at `str`.

- `int second_order_liberty_of_string(int pos, int str)`

  > Returns true if `pos` is a second order liberty of the string at str.

- `int neighbor_of_string(int pos, int str)`

  > Returns true if `pos` is adjacent to the string at `str`.

- `int has_neighbor(int pos, int color)`

  > Returns true if `pos` has a neighbor of `color`.

- `int same_string(int str1, int str2)`

  > Returns true if `str1` and `str2` belong to the same string.

- `int adjacent_strings(int str1, int str2)`

  > Returns true if the strings at `str1` and `str2` are adjacent.

- `int is_ko(int pos, int color, int *ko_pos)`

  > Return true if the move `pos` by `color` is a ko capture (whether capture is legal on this move or not). If so, and if `ko_pos` is not a `NULL` pointer, then `*ko_pos` returns the location of the captured ko stone. If the move is not a ko capture, `*ko_pos` is set to 0. A move is a ko capture if and only if

  > 1. All neighbors are opponent stones.
  > 2. The number of captured stones is exactly one.

- `int is_ko_point(int pos)`

  > Return true if `pos` is either a stone, which if captured would give ko, or if `pos` is an empty intersection adjacent to a ko stone.

- `int does_capture_something(int pos, int color)`

  > Returns 1 if at least one string is captured when color plays at `pos`.

- `void mark_string(int str, char mx[BOARDMAX], char mark)`

  > For each stone in the string at pos, set `mx` to value mark. If some of the stones in the string are marked prior to calling this function, only the connected unmarked stones starting from pos are guaranteed to become marked. The rest of the string may or may not become marked. (In the current implementation, it will.)

- `int move_in_stack(int pos, int cutoff)`

  > Returns true if at least one move has been played at pos at deeper than level `cutoff` in the reading tree.

- `int stones_on_board(int color)`

  > Return the number of stones of the indicated color(s) on the board. This only counts stones in the permanent position, not stones placed by `trymove()` or `tryko()`. Use `stones_on_board(BLACK | WHITE)` to get the total number of stones on the board.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

## 18.4 Utilities from ‘`engine/influence.c`’

We will only list here a portion of the public functions in `influence.c`. The influence code is invoked through the function `compute_influence` (see section Where influence gets used in the engine). It is invoked as follows.

- `void compute_influence(int color, const char safe_stones[BOARDMAX], const float strength[BOARDMAX], struct influence_data *q, int move, const char *trace_message)`

  > Compute the influence values for both colors. The caller must

  > Results will be stored in q. `move` has no effects except toggling debugging. Set it to -1 for no debug output at all (otherwise it will be controlled by the ‘`-m`’ command line option). It is assumed that `color` is in turn to move. (This affects the barrier patterns (class A, D) and intrusions (class B)). Color

Other functions in ‘`influence.c`’ are of the nature of utilities which may be useful throughout the engine. We list the most useful ones here.

- `void influence_mark_non_territory(int pos, int color)`

  > Called from actions for ‘`t`’ patterns in ‘`barriers.db`’. Marks `pos` as not being territory for `color`.

- `int whose_territory(const struct influence_data *q, int pos)`

  > Return the color of the territory at `pos`. If it’s territory for neither color, `EMPTY` is returned.

- `int whose_moyo(const struct influence_data *q, int pos)`

  > Return the color who has a moyo at `pos`. If neither color has a moyo there, `EMPTY` is returned. The definition of moyo in terms of the influences is totally ad hoc.

- `int whose_area(const struct influence_data *q, int pos)`

  > Return the color who has dominating influence (“area”) at `pos`. If neither color dominates the influence there, EMPTY is returned. The definition of area in terms of the influences is totally ad hoc.

[ << ] | [ >> ] |  |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

This document was generated on January 20, 2026 using texi2html 1.82.