GNU Go Documentation
18.1 General Utilities
Utility functions from `engine/utils.c'. Many of these
functions underlie autohelper functions (see section 12.7 Autohelper Functions).
void change_matcher_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, ...)
Returns true if one of the vertices listed satisfies
board[pos]==color. Here last_move is the number of moves minus one.
Example: somewhere(WHITE, 2, apos, bpos, cpos).
int play_break_through_n(int color, int num_moves, ...)
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, ...)
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. A typical use for
these functions is to set up a ladder in an autohelper and see whether it
works or not.
int play_attack_defend2_n(int color, int do_attack, 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 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 for these functions is to
set up a crosscut in an autohelper and see whether at least one cutting stone
can be captured.
void set_depth_values(int level)
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.
int accurate_approxlib(int pos, int color, int maxlib, int *libs)
Play a stone at pos and count the number of liberties for the
resulting string. This requires pos to be empty. This function
differs from approxlib() by the fact that it removes captured
stones before counting the liberties.
int confirm_safety(int move, int color, int size, int *defense_point, int saved_dragons[BOARDMAX], int saved_worms[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. Only worms with
worm.size>size are checked. The arrays saved_dragons[] and
saved_worms[] should be one for stones belonging to dragons or worms
respectively, which are supposedly saved by move. These may be
NULL if no stones are supposed to gaving been saved. 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)
Returns true if a move by color fits the following shape:
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.
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:
- 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).
- Recursively extend opponent strings in atari, except where this
would be suicide.
- Play an opponent stone anywhere it can get two empty
neighbors. (I.e. split big eyes into small ones).
- 4. Play 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. Result is printed on
outfile.
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:
- Solid connections (just like ordinary string).
- Diagonal connection or one space jump through an intersection
where an opponent move would be suicide or self-atari.
- Bamboo joint.
- Diagonal connection where both adjacent intersections are empty.
- 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. Internal timers are used for assessing 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.