874 lines
34 KiB
Plaintext
874 lines
34 KiB
Plaintext
|
In this Chapter, we document some of the utilities which may be
|
||
|
called from the GNU Go engine.
|
||
|
|
||
|
@menu
|
||
|
* General Utilities:: Utilities from @file{engine/utils.c}
|
||
|
* Print Utilities:: Utilities from @file{engine/printutils.c}
|
||
|
* Board Utilities:: Utilities from @file{engine/board.c}
|
||
|
* Influence Utilities:: Utilities from @file{engine/influence.c}
|
||
|
@end menu
|
||
|
|
||
|
@node General Utilities
|
||
|
@section General Utilities
|
||
|
|
||
|
Utility functions from @file{engine/utils.c}. Many of these
|
||
|
functions underlie autohelper functions (@pxref{Autohelper Functions}).
|
||
|
|
||
|
|
||
|
@itemize @bullet
|
||
|
@item @code{void change_dragon_status(int dr, int status)}
|
||
|
@findex change_dragon_status
|
||
|
@quotation
|
||
|
Change the status of all the stones in the dragon at @code{dr}.
|
||
|
@end quotation
|
||
|
@item @code{int defend_against(int move, int color, int apos)}
|
||
|
@findex defend_against
|
||
|
@quotation
|
||
|
Check whether a move at @code{move} stops the enemy from playing at (apos).
|
||
|
@end quotation
|
||
|
@item @code{int cut_possible(int pos, int color)}
|
||
|
@quotation
|
||
|
Returns true if @code{color} can cut at @code{pos}, or if connection through
|
||
|
@code{pos} is inhibited. This information is collected by @code{find_cuts()},
|
||
|
using the B patterns in the connections database.
|
||
|
@end quotation
|
||
|
@item @code{int does_attack(int move, int str)}
|
||
|
@findex does_attack
|
||
|
@quotation
|
||
|
returns true if the move at @code{move} attacks @code{str}. This means that it captures
|
||
|
the string, and that @code{str} is not already dead.
|
||
|
@end quotation
|
||
|
@item @code{int does_defend(int move, int str)}
|
||
|
@findex does_defend
|
||
|
@quotation
|
||
|
@code{does_defend(move, str)} returns true if the move at @code{move}
|
||
|
defends @code{str}. This means that it defends the string, and that
|
||
|
@code{str} can be captured if no defense is made.
|
||
|
@end quotation
|
||
|
@item @code{int somewhere(int color, int last_move, ...)}
|
||
|
@findex somewhere
|
||
|
@quotation
|
||
|
Example: @code{somewhere(WHITE, 2, apos, bpos, cpos)}.
|
||
|
Returns true if one of the vertices listed satisfies
|
||
|
@code{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 @code{stackp==0}.
|
||
|
@end quotation
|
||
|
@item @code{int visible_along_edge(int color, int apos, int bpos)}
|
||
|
@quotation
|
||
|
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.
|
||
|
@end quotation
|
||
|
@item @code{int test_symmetry_after_move(int move, int color, int strict)}
|
||
|
@findex test_symmetry_after_move
|
||
|
@quotation
|
||
|
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.
|
||
|
@end quotation
|
||
|
@item @code{int play_break_through_n(int color, int num_moves, ...)}
|
||
|
@findex play_break_through_n
|
||
|
@quotation
|
||
|
The function @code{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 @code{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
|
||
|
@code{break_through()} is called as if nothing special happened.
|
||
|
Like @code{break_through()}, this function returns 1 if the attempt to
|
||
|
break through was succesful and 2 if it only managed to cut
|
||
|
through.
|
||
|
@end quotation
|
||
|
@item @code{int play_attack_defend_n(int color, int do_attack, int num_moves, ...)}
|
||
|
@item @code{int play_attack_defend2_n(int color, int do_attack, int num_moves, ...)}
|
||
|
@findex play_attack_defend2_n
|
||
|
@findex play_attack_defend_n
|
||
|
@quotation
|
||
|
The function @code{play_attack_defend_n()} plays a sequence of moves,
|
||
|
alternating between the players and starting with @code{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,
|
||
|
@code{play_attack_defend2_n()} plays a sequence of moves,
|
||
|
alternating between the players and starting with @code{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.
|
||
|
@end quotation
|
||
|
@item @code{int play_connect_n(int color, int do_connect, int num_moves, ...)}
|
||
|
@findex play_connect_n
|
||
|
@quotation
|
||
|
Plays a sequence of moves, alternating between the players and starting
|
||
|
with @code{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
|
||
|
@code{string_connect} and @code{disconnect} (@pxref{Connection Reading}).
|
||
|
@end quotation
|
||
|
@item @code{void set_depth_values(int level)}
|
||
|
@findex set_depth_values
|
||
|
@quotation
|
||
|
It is assumed in reading a ladder if @code{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 @code{backfill_depth} and so forth. In short, simplifying
|
||
|
assumptions are made when @code{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
|
||
|
@code{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
|
||
|
@code{mandated_depth_value} is not -1 that value is used; otherwise the depth
|
||
|
values are set as a function of level. The parameter
|
||
|
@code{mandated_depth_value} can be set at the command line to force a
|
||
|
particular value of depth; normally it is -1.
|
||
|
@end quotation
|
||
|
@item @code{void modify_depth_values(int n)}
|
||
|
@findex modify_depth_values
|
||
|
@quotation
|
||
|
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.
|
||
|
@end quotation
|
||
|
@item @code{void increase_depth_values(void)}
|
||
|
@findex increase_depth_values
|
||
|
@quotation
|
||
|
@code{modify_depth_values(1)}.
|
||
|
@end quotation
|
||
|
@item @code{void decrease_depth_values(void)}
|
||
|
@findex decrease_depth_values
|
||
|
@quotation
|
||
|
@code{modify_depth_values(-1)}.
|
||
|
@end quotation
|
||
|
@item @code{void restore_depth_values()}
|
||
|
@findex restore_depth_values
|
||
|
@quotation
|
||
|
Sets @code{depth} and so forth to their saved values.
|
||
|
@end quotation
|
||
|
@item @code{void set_temporary_depth_values(int d, int b, int b2, int bc, int ss, int br, int f, int k)}
|
||
|
@quotation
|
||
|
Explicitly set the depth values. This function is currently never
|
||
|
called.
|
||
|
@end quotation
|
||
|
@item @code{int confirm_safety(int move, int color, int *defense_point, char safe_stones[BOARDMAX])}
|
||
|
@findex confirm_safety
|
||
|
@quotation
|
||
|
Check that the move at color doesn't involve any kind of blunder,
|
||
|
regardless of size.
|
||
|
@end quotation
|
||
|
@item @code{float blunder_size(int move, int color, int *defense_point, char safe_stones[BOARDMAX])}
|
||
|
@findex blunder_size
|
||
|
@quotation
|
||
|
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
|
||
|
@code{safe_stones[]} contains the stones that are supposedly safe after
|
||
|
@code{move}. It may be @code{NULL}. For use when called from
|
||
|
@code{fill_liberty()}, this function may optionally return a point of defense,
|
||
|
which, if taken, will presumably make the move at @code{move} safe on a
|
||
|
subsequent turn.
|
||
|
@end quotation
|
||
|
@item @code{int double_atari(int move, int color, float *value, char safe_stones[BOARDMAX])}
|
||
|
@findex double_atari
|
||
|
@quotation
|
||
|
Returns true if a move by (color) fits the following shape:
|
||
|
@example
|
||
|
X* (O=color)
|
||
|
OX
|
||
|
@end example
|
||
|
capturing one of the two @samp{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 @code{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 @code{NULL}),
|
||
|
and the attacked stones are marked unsafe.
|
||
|
@end quotation
|
||
|
@item @code{void unconditional_life(int unconditional_territory[BOARDMAX], int color)}
|
||
|
@findex unconditional_life
|
||
|
@quotation
|
||
|
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:
|
||
|
|
||
|
@enumerate
|
||
|
@item 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).
|
||
|
@item
|
||
|
Recursively extend opponent strings in atari, except where this
|
||
|
would be suicide.
|
||
|
@item
|
||
|
Play an opponent stone anywhere it can get two empty
|
||
|
neighbors. (I.e. split big eyes into small ones).
|
||
|
@item
|
||
|
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, @code{unconditional_territory[][]} is 1 where color has
|
||
|
unconditionally alive stones, 2 where it has unconditional
|
||
|
territory, and 0 otherwise.
|
||
|
@end enumerate
|
||
|
@end quotation
|
||
|
@item @code{void who_wins(int color, FILE *outfile)}
|
||
|
@quotation
|
||
|
Score the game and determine the winner
|
||
|
@end quotation
|
||
|
@item @code{void find_superstring(int str, int *num_stones, int *stones)}
|
||
|
@findex find_superstring
|
||
|
@cindex superstring
|
||
|
@quotation
|
||
|
Find the stones of an extended string, where the extensions are
|
||
|
through the following kinds of connections:
|
||
|
@enumerate
|
||
|
@item Solid connections (just like ordinary string).
|
||
|
@example
|
||
|
OO
|
||
|
@end example
|
||
|
@item Diagonal connection or one space jump through an intersection
|
||
|
where an opponent move would be suicide or self-atari.
|
||
|
@example
|
||
|
...
|
||
|
O.O
|
||
|
XOX
|
||
|
X.X
|
||
|
@end example
|
||
|
@item
|
||
|
Bamboo joint.
|
||
|
@example
|
||
|
OO
|
||
|
..
|
||
|
OO
|
||
|
@end example
|
||
|
@item Diagonal connection where both adjacent intersections are empty.
|
||
|
@example
|
||
|
.O
|
||
|
O.
|
||
|
@end example
|
||
|
@item 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
|
||
|
@end enumerate
|
||
|
@end quotation
|
||
|
@item @code{void find_superstring_liberties(int str, int *num_libs, int *libs, int liberty_cap)}
|
||
|
@findex find_superstring_liberties
|
||
|
@quotation
|
||
|
This function computes the superstring at @code{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 @code{str}. If
|
||
|
@code{liberty_cap} is nonzero, only liberties of substrings of the superstring
|
||
|
which have fewer than @code{liberty_cap} liberties are generated.
|
||
|
@end quotation
|
||
|
@item @code{void find_proper_superstring_liberties(int str, int *num_libs, int *libs, int liberty_cap)}
|
||
|
@findex find_proper_superstring_liberties
|
||
|
@quotation
|
||
|
This function is the same as find_superstring_liberties, but it omits those
|
||
|
liberties of the string @code{str}, presumably since those have already been
|
||
|
treated elsewhere. If @code{liberty_cap} is nonzero, only liberties of
|
||
|
substrings of the superstring which have at most @code{liberty_cap} liberties
|
||
|
are generated.
|
||
|
@end quotation
|
||
|
@item @code{void find_superstring_stones_and_liberties(int str, int *num_stones, int *stones, int *num_libs, int *libs, int liberty_cap)}
|
||
|
@findex find_superstring_stones_and_liberties
|
||
|
@quotation
|
||
|
This function computes the superstring at @code{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
|
||
|
@code{str}. If liberty_cap is nonzero, only liberties of substrings of the
|
||
|
superstring which have fewer than liberty_cap liberties are
|
||
|
generated.
|
||
|
@end quotation
|
||
|
@item @code{void superstring_chainlinks(int str, int *num_adj, int adjs[MAXCHAIN], int liberty_cap)}
|
||
|
@findex superstring_chainlinks
|
||
|
@quotation
|
||
|
analogous to chainlinks, this function finds boundary chains of the
|
||
|
superstring at @code{str}, including those which are boundary chains of
|
||
|
@code{str} itself. If @code{liberty_cap != 0}, only those boundary chains with
|
||
|
@code{<= liberty_cap} liberties are reported.
|
||
|
@end quotation
|
||
|
@item @code{void proper_superstring_chainlinks(int str, int *num_adj, int adjs[MAXCHAIN], int liberty_cap)}
|
||
|
@findex proper_superstring_chainlingks
|
||
|
@quotation
|
||
|
analogous to chainlinks, this function finds boundary chains of the
|
||
|
superstring at @code{str}, omitting those which are boundary chains of
|
||
|
@code{str} itself. If @code{liberty_cap != 0}, only those boundary chains with
|
||
|
@code{<= liberty_cap} liberties are reported.
|
||
|
@end quotation
|
||
|
@item @code{void start_timer(int n)}
|
||
|
@findex start_timer
|
||
|
@cindex timers
|
||
|
@quotation
|
||
|
Start a timer. GNU Go has four internal timers available for
|
||
|
assessing the time spent on various tasks.
|
||
|
@end quotation
|
||
|
@item @code{double time_report(int n, const char *occupation, int move, double mintime)}
|
||
|
@findex time_report
|
||
|
@quotation
|
||
|
Report time spent and restart the timer. Make no report if elapsed
|
||
|
time is less than mintime.
|
||
|
@end quotation
|
||
|
@end itemize
|
||
|
|
||
|
@node Print Utilities
|
||
|
@section Print Utilities
|
||
|
@cindex formatted printing
|
||
|
|
||
|
Functions in @file{engine/printutils.c} do formatted printing similar to
|
||
|
@code{printf} and its allies. The following formats are recognized:
|
||
|
|
||
|
@itemize @bullet
|
||
|
@item @code{%c}, @code{%d}, @code{%f}, @code{%s}, @code{%x}
|
||
|
@quotation
|
||
|
These have their usual meaning in formatted output, printing
|
||
|
a character, integer, float, string or hexadecimal, respectively.
|
||
|
@end quotation
|
||
|
@item @code{%o}
|
||
|
@quotation
|
||
|
`Outdent.' Normally output is indented by @code{2*stackp} spaces,
|
||
|
so that the depth can be seen at a glance in traces. At the
|
||
|
beginning of a format, this @code{%o} inhibits the indentation.
|
||
|
@end quotation
|
||
|
@item @code{%H}
|
||
|
@quotation
|
||
|
Print a hashvalue.
|
||
|
@end quotation
|
||
|
@item @code{%C}
|
||
|
@quotation
|
||
|
Print a color as a string.
|
||
|
@end quotation
|
||
|
@item @code{%m}, @code{%2m} (synonyms)
|
||
|
@quotation
|
||
|
Takes 2 integers and writes a move, using the two dimensional
|
||
|
board representation (@pxref{The Board Array})
|
||
|
@end quotation
|
||
|
@item @code{%1m}
|
||
|
@quotation
|
||
|
Takes 1 integers and writes a move, using the one dimensional
|
||
|
board representation (@pxref{The Board Array})
|
||
|
@end quotation
|
||
|
@end itemize
|
||
|
|
||
|
We list the non statically declared functions in @file{printutils.c}.
|
||
|
|
||
|
@itemize @bullet
|
||
|
@item @code{void gfprintf(FILE *outfile, const char *fmt, ...)}
|
||
|
@findex gfprintf
|
||
|
@quotation
|
||
|
Formatted output to @file{outfile}.
|
||
|
@end quotation
|
||
|
@item @code{int gprintf(const char *fmt, ...)}
|
||
|
@findex gprintf
|
||
|
@quotation
|
||
|
Formatted output to stderr. Always returns 1 to allow use in short-circuit
|
||
|
logical expressions.
|
||
|
@end quotation
|
||
|
@item @code{int mprintf(const char *fmt, ...)}
|
||
|
@findex mprintf
|
||
|
@quotation
|
||
|
Formatted output to stdout.
|
||
|
@end quotation
|
||
|
@item @code{DEBUG(level, fmt, args...)}
|
||
|
@findex DEBUG
|
||
|
@quotation
|
||
|
If @code{level & debug}, do formatted output to stderr. Otherwise, ignore.
|
||
|
@end quotation
|
||
|
@item @code{void abortgo(const char *file, int line, const char *msg, int pos)}
|
||
|
@findex abortgo
|
||
|
@quotation
|
||
|
Print debugging output in an error situation, then exit.
|
||
|
@end quotation
|
||
|
@item @code{const char * color_to_string(int color)}
|
||
|
@findex color_to_string
|
||
|
@quotation
|
||
|
Convert a color value to a string
|
||
|
@end quotation
|
||
|
@item @code{const char * location_to_string(int pos)}
|
||
|
@findex location_to_string
|
||
|
@quotation
|
||
|
Convert a location to a string
|
||
|
@end quotation
|
||
|
@item @code{void location_to_buffer(int pos, char *buf)}
|
||
|
@findex location_to_buffer
|
||
|
@quotation
|
||
|
Convert a location to a string, writing to a buffer.
|
||
|
@end quotation
|
||
|
@item @code{int string_to_location(int boardsize, char *str, int *m, int *n)}
|
||
|
@findex string_to_location
|
||
|
@quotation
|
||
|
Get the @code{(m, n)} coordinates in the standard GNU Go coordinate system
|
||
|
from the string @code{str}. This means that @samp{m} is the nth row from the
|
||
|
top and @samp{n} is the column. Both coordinates are between 0 and
|
||
|
@code{boardsize-1}, inclusive. Return 1 if ok, otherwise return 0;
|
||
|
@end quotation
|
||
|
@item @code{int is_hoshi_point(int m, int n)}
|
||
|
@findex is_hoshi_point
|
||
|
True if the coordinate is a hoshi point.
|
||
|
@item @code{void draw_letter_coordinates(FILE *outfile)}
|
||
|
@findex draw_letter_coordinates
|
||
|
Print a line with coordinate letters above the board.
|
||
|
@item @code{void simple_showboard(FILE *outfile)}
|
||
|
@findex simple_showboard
|
||
|
@quotation
|
||
|
Bare bones version of @code{showboard(0)}. No fancy options, no hint of
|
||
|
color, and you can choose where to write it.
|
||
|
@end quotation
|
||
|
@end itemize
|
||
|
|
||
|
The following functions are in @file{showbord.c}. Not all public
|
||
|
functions in that file are listed here.
|
||
|
|
||
|
@itemize
|
||
|
@item @code{void showboard(int xo)}
|
||
|
@findex showboard
|
||
|
@quotation
|
||
|
Show go board.
|
||
|
@example
|
||
|
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
|
||
|
@end example
|
||
|
@end quotation
|
||
|
@item @code{const char * status_to_string(int status)}
|
||
|
@findex status_to_string
|
||
|
@quotation
|
||
|
Convert a status value to a string.
|
||
|
@end quotation
|
||
|
@item @code{const char * safety_to_string(int status)}
|
||
|
@findex safety_to_string
|
||
|
@quotation
|
||
|
Convert a safety value to a string.
|
||
|
@end quotation
|
||
|
@item @code{const char * result_to_string(int result)}
|
||
|
@findex result_to_string
|
||
|
@quotation
|
||
|
Convert a read result to a string
|
||
|
@end quotation
|
||
|
@end itemize
|
||
|
|
||
|
@node Board Utilities
|
||
|
@section Board Utilities
|
||
|
|
||
|
The functions documented in this section are from @file{board.c}. Other
|
||
|
functions in @file{board.c} are described in @xref{Some Board Functions}.
|
||
|
|
||
|
@itemize @bullet
|
||
|
@item @code{void store_board(struct board_state *state)}
|
||
|
@findex store_board
|
||
|
@quotation
|
||
|
Save board state.
|
||
|
@end quotation
|
||
|
@item @code{void restore_board(struct board_state *state)}
|
||
|
@findex restore_board
|
||
|
@quotation
|
||
|
Restore a saved board state.
|
||
|
@end quotation
|
||
|
@item @code{void clear_board(void)}
|
||
|
@findex clear_board
|
||
|
@quotation
|
||
|
Clear the internal board.
|
||
|
@end quotation
|
||
|
@item @code{void dump_stack(void)}
|
||
|
@findex dump_stack
|
||
|
@quotation
|
||
|
for use under GDB prints the move stack.
|
||
|
@end quotation
|
||
|
@item @code{void add_stone(int pos, int color)}
|
||
|
@findex add_stone
|
||
|
@quotation
|
||
|
Place a stone on the board and update the board_hash. This operation
|
||
|
destroys all move history.
|
||
|
@end quotation
|
||
|
@item @code{void remove_stone(int pos)}
|
||
|
@findex remove_stone
|
||
|
@quotation
|
||
|
Remove a stone from the board and update the board_hash. This
|
||
|
operation destroys the move history.
|
||
|
@end quotation
|
||
|
@item @code{int is_pass(int pos)}
|
||
|
@findex is_pass
|
||
|
@quotation
|
||
|
Test if the move is a pass or not. Return 1 if it is.
|
||
|
@end quotation
|
||
|
@item @code{int is_legal(int pos, int color)}
|
||
|
@findex is_legal
|
||
|
@quotation
|
||
|
Determines whether the move @code{color} at @code{pos} is legal.
|
||
|
@end quotation
|
||
|
@item @code{int is_suicide(int pos, int color)}
|
||
|
@findex is_suicide
|
||
|
@quotation
|
||
|
Determines whether the move @code{color} at @code{pos} would be a suicide.
|
||
|
This is the case if
|
||
|
@enumerate
|
||
|
@item There is no neighboring empty intersection.
|
||
|
@item There is no neighboring opponent string with exactly one liberty.
|
||
|
@item There is no neighboring friendly string with more than one liberty.
|
||
|
@end enumerate
|
||
|
@end quotation
|
||
|
@item @code{int is_illegal_ko_capture(int pos, int color)}
|
||
|
@findex is_illegal_ko_capture
|
||
|
@quotation
|
||
|
Determines whether the move @code{color} at @code{pos} would be an illegal ko
|
||
|
capture.
|
||
|
@end quotation
|
||
|
@item @code{int is_edge_vertex(int pos)}
|
||
|
@findex is_edge_vertex
|
||
|
@quotation
|
||
|
Determine whether vertex is on the edge.
|
||
|
@end quotation
|
||
|
@item @code{int edge_distance(int pos)}
|
||
|
@findex edge_distance
|
||
|
@quotation
|
||
|
Distance to the edge.
|
||
|
@end quotation
|
||
|
@item @code{int is_corner_vertex(int pos)}
|
||
|
@findex is_corner_vertex
|
||
|
@quotation
|
||
|
Determine whether vertex is a corner.
|
||
|
@end quotation
|
||
|
@item @code{int get_komaster()}
|
||
|
@findex get_komaster
|
||
|
@item @code{int get_kom_pos()}
|
||
|
@findex get_kom_pos
|
||
|
@quotation
|
||
|
Public functions to access the variable @code{komaster} and @code{kom_pos},
|
||
|
which are static in @file{board.c}.
|
||
|
@end quotation
|
||
|
@end itemize
|
||
|
|
||
|
Next we come to @code{countlib()} and its allies, which
|
||
|
address the problem of determining how many liberties a
|
||
|
string has. Although @code{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.
|
||
|
|
||
|
@itemize @bullet
|
||
|
@item @code{int countlib(int str)}
|
||
|
@findex countlib
|
||
|
@quotation
|
||
|
Count the number of liberties of the string at @code{pos}. There
|
||
|
must be a stone at this location.
|
||
|
@end quotation
|
||
|
@item @code{int findlib(int str, int maxlib, int *libs)}
|
||
|
@findex findlib
|
||
|
@quotation
|
||
|
Find the liberties of the string at @code{str}. This location must not be
|
||
|
empty. The locations of up to maxlib liberties are written into
|
||
|
@code{libs[]}. The full number of liberties is returned. If you want the
|
||
|
locations of all liberties, whatever their number, you should pass
|
||
|
@code{MAXLIBS} as the value for @code{maxlib} and allocate space for
|
||
|
@code{libs[]} accordingly.
|
||
|
@end quotation
|
||
|
@item @code{int fastlib(int pos, int color, int ignore_captures)}
|
||
|
@findex fastlib
|
||
|
@quotation
|
||
|
Count the liberties a stone of the given color would get if played
|
||
|
at @code{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 @code{ignore_captures} field is nonzero. The location @code{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.
|
||
|
@end quotation
|
||
|
@item @code{int approxlib(int pos, int color, int maxlib, int *libs)}
|
||
|
@findex approxlib
|
||
|
@quotation
|
||
|
Find the liberties a stone of the given color would get if played at
|
||
|
@code{pos}, ignoring possible captures of opponent stones. The location
|
||
|
@code{pos} must be empty. If @code{libs != NULL}, the locations of up to
|
||
|
@code{maxlib} liberties are written into @code{libs[]}. The counting of
|
||
|
liberties may or may not be halted when @code{maxlib} is reached. The number
|
||
|
of liberties found is returned, which may be less than the total number of
|
||
|
liberties if @code{maxlib} is small. If you want the number or the locations
|
||
|
of all liberties, however many they are, you should pass @code{MAXLIBS} as the
|
||
|
value for maxlib and allocate space for @code{libs[]} accordingly.
|
||
|
@end quotation
|
||
|
@item @code{int accuratelib(int pos, int color, int maxlib, int *libs)}
|
||
|
@findex accuratelib
|
||
|
@quotation
|
||
|
Find the liberties a stone of the given color would get if played at
|
||
|
@code{pos}. This function takes into consideration all captures. Its return
|
||
|
value is exact in that sense it counts all the liberties, unless @code{maxlib}
|
||
|
allows it to stop earlier. The location @code{pos} must be empty. If
|
||
|
@code{libs != NULL}, the locations of up to @code{maxlib} liberties are
|
||
|
written into @code{libs[]}. The counting of liberties may or may not be halted
|
||
|
when @code{maxlib} is reached. The number of found liberties is returned.
|
||
|
This function guarantees that liberties which are not results of captures come
|
||
|
first in @code{libs[]} array. To find whether all the liberties starting from
|
||
|
a given one are results of captures, one may use @code{if (board[libs[k]] !=
|
||
|
EMPTY)} construction. If you want the number or the locations of all
|
||
|
liberties, however many they are, you should pass @code{MAXLIBS} as the value
|
||
|
for @code{maxlib} and allocate space for @code{libs[]} accordingly.
|
||
|
@end quotation
|
||
|
@end itemize
|
||
|
|
||
|
Next we have some general utility functions.
|
||
|
|
||
|
@itemize @bullet
|
||
|
@item @code{int count_common_libs(int str1, int str2)}
|
||
|
@findex count_common_libs
|
||
|
@quotation
|
||
|
Find the number of common liberties of the two strings.
|
||
|
@end quotation
|
||
|
@item @code{int find_common_libs(int str1, int str2, int maxlib, int *libs)}
|
||
|
@findex find_common_libs
|
||
|
@quotation
|
||
|
Find the common liberties of the two strings. The locations of up to
|
||
|
@code{maxlib} common liberties are written into @code{libs[]}. The full
|
||
|
number of common liberties is returned. If you want the locations of all
|
||
|
common liberties, whatever their number, you should pass @code{MAXLIBS} as the
|
||
|
value for @code{maxlib} and allocate space for @code{libs[]} accordingly.
|
||
|
@end quotation
|
||
|
@item @code{int have_common_lib(int str1, int str2, int *lib)}
|
||
|
@findex have_common_lib
|
||
|
@quotation
|
||
|
Determine whether two strings have at least one common liberty.
|
||
|
If they do and @code{lib != NULL}, one common liberty is returned in
|
||
|
@code{*lib}.
|
||
|
@end quotation
|
||
|
@item @code{int countstones(int str)}
|
||
|
@findex countstones
|
||
|
@quotation
|
||
|
Report the number of stones in a string.
|
||
|
@end quotation
|
||
|
@item @code{int findstones(int str, int maxstones, int *stones)}
|
||
|
@findex findstones
|
||
|
@quotation
|
||
|
Find the stones of the string at @code{str}. The location must not be
|
||
|
empty. The locations of up to maxstones stones are written into
|
||
|
@code{stones[]}. The full number of stones is returned.
|
||
|
@end quotation
|
||
|
@item @code{int chainlinks(int str, int adj[MAXCHAIN])}
|
||
|
@findex chainlinks
|
||
|
@quotation
|
||
|
This very useful function returns (in the @code{adj} array) the chains
|
||
|
surrounding the string at @code{str}. The number of chains is returned.
|
||
|
@end quotation
|
||
|
@item @code{int chainlinks2(int str, int adj[MAXCHAIN], int lib)}
|
||
|
@findex chainlinks2
|
||
|
@quotation
|
||
|
Returns (in @code{adj} array) those chains surrounding the string at
|
||
|
@code{str}, which has exactly @code{lib} liberties. The number of such chains
|
||
|
is returned.
|
||
|
@end quotation
|
||
|
@item @code{int chainlinks3(int str, int adj[MAXCHAIN], int lib)}
|
||
|
@findex chainlinks3
|
||
|
@quotation
|
||
|
Returns (in @code{adj} array) the chains surrounding
|
||
|
the string at @code{str}, which have less or equal @code{lib} liberties.
|
||
|
The number of such chains is returned.
|
||
|
@end quotation
|
||
|
@item @code{int extended_chainlinks(int str, int adj[MAXCHAIN], int both_colors)}
|
||
|
@findex extended_chainlinks
|
||
|
@quotation
|
||
|
Returns (in the @code{adj} array) the opponent strings being directly adjacent
|
||
|
to @code{str} or having a common liberty with @code{str}. The number of such
|
||
|
strings is returned. If the both_colors parameter is true, also own strings
|
||
|
sharing a liberty are returned.
|
||
|
@end quotation
|
||
|
@item @code{int find_origin(int str)}
|
||
|
@findex find_origin
|
||
|
@quotation
|
||
|
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.
|
||
|
@end quotation
|
||
|
@item @code{int is_self_atari(int pos, int color)}
|
||
|
@findex is_self_atari
|
||
|
@quotation
|
||
|
Determine whether a move by color at @code{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.
|
||
|
@end quotation
|
||
|
@item @code{int liberty_of_string(int pos, int str)}
|
||
|
@findex liberty_of_string
|
||
|
@quotation
|
||
|
Returns true if @code{pos} is a liberty of the string at @code{str}.
|
||
|
@end quotation
|
||
|
@item @code{int second_order_liberty_of_string(int pos, int str)}
|
||
|
@findex second_order_liberty_of_string
|
||
|
@quotation
|
||
|
Returns true if @code{pos} is a second order liberty of the string at str.
|
||
|
@end quotation
|
||
|
@item @code{int neighbor_of_string(int pos, int str)}
|
||
|
@findex neighbor_of_string
|
||
|
@quotation
|
||
|
Returns true if @code{pos} is adjacent to the string at @code{str}.
|
||
|
@end quotation
|
||
|
@item @code{int has_neighbor(int pos, int color)}
|
||
|
@findex has_neighbor
|
||
|
@quotation
|
||
|
Returns true if @code{pos} has a neighbor of @code{color}.
|
||
|
@end quotation
|
||
|
@item @code{int same_string(int str1, int str2)}
|
||
|
@findex same_string
|
||
|
@quotation
|
||
|
Returns true if @code{str1} and @code{str2} belong to the same string.
|
||
|
@end quotation
|
||
|
@item @code{int adjacent_strings(int str1, int str2)}
|
||
|
@findex adjacent_strings
|
||
|
@quotation
|
||
|
Returns true if the strings at @code{str1} and @code{str2} are adjacent.
|
||
|
@end quotation
|
||
|
@item @code{int is_ko(int pos, int color, int *ko_pos)}
|
||
|
@findex is_ko
|
||
|
@quotation
|
||
|
Return true if the move @code{pos} by @code{color} is a ko capture
|
||
|
(whether capture is legal on this move or not). If so,
|
||
|
and if @code{ko_pos} is not a @code{NULL} pointer, then
|
||
|
@code{*ko_pos} returns the location of the captured ko stone.
|
||
|
If the move is not a ko capture, @code{*ko_pos} is set to 0.
|
||
|
A move is a ko capture if and only if
|
||
|
@enumerate
|
||
|
@item All neighbors are opponent stones.
|
||
|
@item The number of captured stones is exactly one.
|
||
|
@end enumerate
|
||
|
@end quotation
|
||
|
@item @code{int is_ko_point(int pos)}
|
||
|
@findex is_ko_point
|
||
|
@quotation
|
||
|
Return true if @code{pos} is either a stone, which if captured would give
|
||
|
ko, or if @code{pos} is an empty intersection adjacent to a ko stone.
|
||
|
@end quotation
|
||
|
@item @code{int does_capture_something(int pos, int color)}
|
||
|
@findex does_capture_something
|
||
|
@quotation
|
||
|
Returns 1 if at least one string is captured when color plays at @code{pos}.
|
||
|
@end quotation
|
||
|
@item @code{void mark_string(int str, char mx[BOARDMAX], char mark)}
|
||
|
@findex mark_string
|
||
|
@quotation
|
||
|
For each stone in the string at pos, set @code{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.)
|
||
|
@end quotation
|
||
|
@item @code{int move_in_stack(int pos, int cutoff)}
|
||
|
@findex move_in_stack
|
||
|
@quotation
|
||
|
Returns true if at least one move has been played at pos
|
||
|
at deeper than level @code{cutoff} in the reading tree.
|
||
|
@end quotation
|
||
|
@item @code{int stones_on_board(int color)}
|
||
|
@findex stones_on_board
|
||
|
@quotation
|
||
|
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 @code{trymove()} or @code{tryko()}. Use
|
||
|
@code{stones_on_board(BLACK | WHITE)} to get
|
||
|
the total number of stones on the board.
|
||
|
@end quotation
|
||
|
@end itemize
|
||
|
|
||
|
@node Influence Utilities
|
||
|
@section Utilities from @file{engine/influence.c}
|
||
|
|
||
|
We will only list here a portion of the public functions in @code{influence.c}.
|
||
|
The influence code is invoked through the function @code{compute_influence}
|
||
|
(@pxref{Influence Usage}). It is invoked as follows.
|
||
|
|
||
|
@itemize @bullet
|
||
|
@item @code{void compute_influence(int color, const char safe_stones[BOARDMAX], const float strength[BOARDMAX], struct influence_data *q, int move, const char *trace_message)}
|
||
|
@findex compute_influence
|
||
|
@quotation
|
||
|
Compute the influence values for both colors.
|
||
|
The caller must
|
||
|
@itemize @minus
|
||
|
@item set up the @code{board[]} state
|
||
|
@item mark safe stones with @code{INFLUENCE_SAFE_STONE}, dead stones with 0
|
||
|
@item mark stones newly saved by a move with @code{INFLUENCE_SAVED_STONE}
|
||
|
(this is relevant if the influence_data *q is reused to compute
|
||
|
a followup value for this move).
|
||
|
@end itemize
|
||
|
Results will be stored in q.
|
||
|
@code{move} has no effects except toggling debugging. Set it to -1
|
||
|
for no debug output at all (otherwise it will be controlled by
|
||
|
the @option{-m} command line option). It is assumed that @code{color} is in turn to move. (This affects the
|
||
|
barrier patterns (class A, D) and intrusions (class B)). Color
|
||
|
@end quotation
|
||
|
@end itemize
|
||
|
|
||
|
Other functions in @file{influence.c} are of the nature of utilities
|
||
|
which may be useful throughout the engine. We list the most useful
|
||
|
ones here.
|
||
|
|
||
|
@itemize @bullet
|
||
|
@item @code{void influence_mark_non_territory(int pos, int color)}
|
||
|
@findex influence_mark_non_territory
|
||
|
@quotation
|
||
|
Called from actions for @samp{t} patterns in @file{barriers.db}.
|
||
|
Marks @code{pos} as not being territory for @code{color}.
|
||
|
@end quotation
|
||
|
@item @code{int whose_territory(const struct influence_data *q, int pos)}
|
||
|
@findex whose_territory
|
||
|
@quotation
|
||
|
Return the color of the territory at @code{pos}. If it's territory for
|
||
|
neither color, @code{EMPTY} is returned.
|
||
|
@end quotation
|
||
|
@item @code{int whose_moyo(const struct influence_data *q, int pos)}
|
||
|
@findex whose_moyo
|
||
|
@quotation
|
||
|
Return the color who has a moyo at @code{pos}. If neither color has a
|
||
|
moyo there, @code{EMPTY} is returned. The definition of moyo in terms of the
|
||
|
influences is totally ad hoc.
|
||
|
@end quotation
|
||
|
@item @code{int whose_area(const struct influence_data *q, int pos)}
|
||
|
@findex whose_area
|
||
|
@quotation
|
||
|
Return the color who has dominating influence (``area'') at @code{pos}.
|
||
|
If neither color dominates the influence there, EMPTY is returned.
|
||
|
The definition of area in terms of the influences is totally ad hoc.
|
||
|
@end quotation
|
||
|
@end itemize
|
||
|
|
||
|
|
||
|
|