Next: Print Utilities, Up: Utility Functions
Utility functions from engine/utils.c. Many of these functions underlie autohelper functions (see 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 ifcolor
can cut atpos
, or if connection throughpos
is inhibited. This information is collected byfind_cuts()
, using the B patterns in the connections database.
int does_attack(int move, int str)
returns true if the move atmove
attacksstr
. This means that it captures the string, and thatstr
is not already dead.
int does_defend(int move, int str)
does_defend(move, str)
returns true if the move atmove
defendsstr
. This means that it defends the string, and thatstr
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 satisfiesboard[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 ifstackp==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 functionplay_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 bybreak_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, andbreak_through()
is called as if nothing special happened. Likebreak_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 functionplay_attack_defend_n()
plays a sequence of moves, alternating between the players and starting withcolor
. 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 withcolor
. 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 withcolor
. 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 functionsstring_connect
anddisconnect
(see Connection Reading).
void set_depth_values(int level)
It is assumed in reading a ladder ifstackp >= 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 asbackfill_depth
and so forth. In short, simplifying assumptions are made whenstackp
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 ofstackp
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. Ifmandated_depth_value
is not -1 that value is used; otherwise the depth values are set as a function of level. The parametermandated_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 arraysafe_stones[]
contains the stones that are supposedly safe aftermove
. It may beNULL
. For use when called fromfill_liberty()
, this function may optionally return a point of defense, which, if taken, will presumably make the move atmove
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) OXcapturing 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 isNULL
), 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:
- 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).
- 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:
- Solid connections (just like ordinary string).
OO- Diagonal connection or one space jump through an intersection where an opponent move would be suicide or self-atari.
... O.O XOX X.X- Bamboo joint.
OO .. OO- Diagonal connection where both adjacent intersections are empty.
.O O.- 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 atstr
as described above, but omitting connections of type 5. Then it constructs a list of liberties of the superstring which are not already liberties ofstr
. Ifliberty_cap
is nonzero, only liberties of substrings of the superstring which have fewer thanliberty_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 stringstr
, presumably since those have already been treated elsewhere. Ifliberty_cap
is nonzero, only liberties of substrings of the superstring which have at mostliberty_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 atstr
as described above, but omitting connections of type 5. Then it constructs a list of liberties of the superstring which are not already liberties ofstr
. 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 atstr
, including those which are boundary chains ofstr
itself. Ifliberty_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 atstr
, omitting those which are boundary chains ofstr
itself. Ifliberty_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.