GNU Go Documentation
14.8 Reading Functions
Here we list the publically callable functions in `reading.c'.
The return codes of these functions are explained elsewhere
(see section 14.1 Reading Basics). To briefly repeat this, a reading
function return WIN if the attack succeeds unconditionally, 0 if it doesn't.
It returns KO_A or KO_B if the result depends on ko:
- Returns
KO_A if the attack succeeds provided attacker is willing to
ignore any ko threat (the attacker makes the first ko capture).
- Returns
KO_B if attack succeeds provided attacker has a ko threat
which must be answered (the defender makes the first ko capture).
int attack(int str, int *move)
Determines if the string at str can be captured, and if so,
*move returns the attacking move, unless move is a null
pointer. Use a null pointer if you are interested in the result of the
attack but not the attacking move itself.
int find_defense(int str, int *move)
Attempts to find a move that will save the string at str. It
returns WIN if such a move is found, with *move the location of
the saving move, unless move is a null pointer. It is not checked
that tenuki defends, so this may give an erroneous answer if
!attack(str).
int attack_and_defend(int str, int *attack_code, int *attack_point, int *defend_code, int *defense_point)
This is a frontend to the attack() and find_defense()
functions, which guarantees a consistent result. If a string cannot be
attacked, 0 is returned and *attack_code is 0. If a string can be
attacked and defended, WIN is returned, *attack_code and
*defend_code are both non-zero, and *attack_point,
*defense_point both point to vertices on the board. If a string
can be attacked but not defended, 0 is again returned,
*attack_code is non-zero, *defend_code is 0, and
*attack_point points to a vertex on the board. This function in
particular guarantees that if there is an attack, it will never return
defense_point = NO_MOVE, which means the string is safe
without defense. Separate calls to attack() and
find_defense() may occasionally give this result, due to
irregularities introduced by the persistent reading cache.
int attack_either(int astr, int bstr)
Returns true if there is a move which guarantees that at least one of
the strings astr and bstr can be captured. A typical
application for this is in connection patterns, where after a cut it
suffices to capture one of the cutting stones. The current
implementation only looks for uncoordinated attacks. This is
insufficient to find double ataris or moves such as `a' in
positions like
| | XOOOOOOOX
XOXXOXXOX
XX..a..XX
---------
|
where neither of the threatened `X' stones can be captured outright.
Still either can be captured by a move down to `a'.
int defend_both(int astr, int bstr)
Returns true if both the strings astr and bstr can be defended
simultaneously or if there is no attack. A typical application for this is in
connection patterns, where after a cut it's necessary to defend both cutting
stones. The current implementation only makes halfhearted attempts to find
coordinated defense moves. A proper implementation would require some serious
reading.
int break_through(int apos, int bpos, int cpos)
returns WIN if a position can succesfully be broken through and
CUT if it can be cut. The position is assumed to have the shape
(the colors may be reversed)
It is `X' to move and try to capture at least one of `a',
`b', and `c'. If this succeeds, `X' is said to have
broken through the position. Otherwise `X' may try to cut through
the position, which means keeping `F' safe and getting a tactically
safe string at either `d' or `e'. Important:
`a', `b', and `c' must be given in the correct order.
int attack_threats(int str, int max_points, int moves[], int codes[])
Return up to max_threats threats to capture the string at str. If
the string is directly attackable the number of threats is reported to
be 0. NOTE: You can call attack_threats with moves[] and
codes[] already partly filled in. So if you want to get the
threats from scratch, you have to set them to 0 yourself.
int safe_move(int move, int color)
Checks whether a move at move is illegal or can immediately be captured. If
stackp==0 the result is cached. If the move only can be captured by a
ko, it's considered safe.
void purge_persistent_reading_cache()
Remove persistent cache entries which are no longer current.
void reading_hotspots(float values[BOARDMAX])
Based on the entries in the reading cache and their nodes field,
compute where the relatively most expensive tactical reading is
going on.