Initial commit of GNU Go v3.8.
[sgk-go] / doc / dragon.texi
@menu
* Worms:: Worms
* Amalgamation:: How two Worms are amalgamated.
* Connection:: Connections.
* Half Eyes:: Half Eyes and False Eyes.
* Dragons:: Union of WORMS.
* Dragons in Color:: Colored display of DRAGONS.
@end menu
Before considering its move, GNU Go collects some data in several
arrays. Two of these arrays, called @code{worm} and @code{dragon}, are
discussed in this document. Others are discussed in @xref{Eyes}.
This information is intended to help evaluate the connectedness, eye
shape, escape potential and life status of each group.
Later routines called by @code{genmove()} will then have access to this
information. This document attempts to explain the philosophy and
algorithms of this preliminary analysis, which is carried out by the
two routines @code{make_worm()} and @code{make_dragon()} in
@file{dragon.c}.
@cindex dragon
@cindex worm
@cindex string
A @dfn{worm} is a maximal set of stones on the board which are connected
along the horizontal and vertical lines, and are of the same color.
We often say @dfn{string} instead of worm.
A @dfn{dragon} is a union of strings of the same color which will be
treated as a unit. The dragons are generated anew at each move. If two strings
are in the dragon, it is the computer's working hypothesis that they will live
or die together and are effectively connected.
The purpose of the dragon code is to allow the computer to formulate
meaningful statements about life and death. To give one example,
consider the following situation:
@example
OOOOO
OOXXXOO
OX...XO
OXXXXXO
OOOOO
@end example
The X's here should be considered a single group with one three-space
eye, but they consist of two separate strings. Thus we must
amalgamate these two strings into a single dragon. Then the assertion
makes sense, that playing at the center will kill or save the dragon,
and is a vital point for both players. It would be difficult to
formulate this statement if the X's are not perceived as a unit.
The present implementation of the dragon code involves simplifying
assumptions which can be refined in later implementations.
@node Worms
@section Worms
@cindex worm
The array @code{struct worm_data worm[MAX_BOARD]} collects information about
the worms. We will give definitions of the various fields. Each field has
constant value at each vertex of the worm. We will define each field.
@example
struct worm_data @{
int color;
int size;
float effective_size;
int origin;
int liberties;
int liberties2;
int liberties3;
int liberties4;
int lunch;
int cutstone;
int cutstone2;
int genus;
int inessential;
int invincible;
int unconditional_status;
int attack_points[MAX_TACTICAL_POINTS];
int attack_codes[MAX_TACTICAL_POINTS];
int defense_points[MAX_TACTICAL_POINTS];
int defend_codes[MAX_TACTICAL_POINTS];
int attack_threat_points[MAX_TACTICAL_POINTS];
int attack_threat_codes[MAX_TACTICAL_POINTS];
int defense_threat_points[MAX_TACTICAL_POINTS];
int defense_threat_codes[MAX_TACTICAL_POINTS];
@};
@end example
@itemize @bullet
@item @code{color}
@quotation
The color of the worm.
@end quotation
@item @code{size}
@quotation
This field contains the cardinality of the worm.
@end quotation
@item @code{effective_size}
@quotation
@cindex effective size (worm)
This is the number of stones in a worm plus the number
of empty intersections that are at least as close to this worm as to any
other worm. Intersections that are shared are counted with equal
fractional values for each worm. This measures the direct territorial
value of capturing a worm. @dfn{effective_size} is a floating point number.
Only intersections at a distance of 4 or less are counted.
@end quotation
@item @code{origin}
@quotation
@cindex origin (worm)
Each worm has a distinguished member, called its @dfn{origin}.
The purpose of this field is to make it easy to determine when two vertices
lie in the same worm: we compare their origin. Also if we wish to perform some
test once for each worm, we simply perform it at the origin and ignore the
other vertices. The origin is characterized by the test:
@example
worm[pos].origin == pos.
@end example
@end quotation
@item @code{liberties}
@item @code{liberties2}
@item @code{liberties3}
@item @code{liberties4}
@quotation
@cindex liberties (worm)
@cindex liberties, higher order (worm)
For a nonempty worm the field liberties is the number of liberties of the
string. This is supplemented by @code{LIBERTIES2}, @code{LIBERTIES3} and
@code{LIBERTIES4}, which are the number of second order, third order, and
fourth order liberties, respectively.
The definition of liberties of order >1 is adapted to the
problem of detecting the shape of the surrounding
empty space. In particular we want to be able to see if a group
is loosely surrounded. A @dfn{liberty of order n} is an empty
vertex which may be connected to the string by placing n
stones of the same color on the board, but no fewer. The
path of connection may pass through an intervening group
of the same color. The stones placed at distance >1 may
not touch a group of the opposite color. Connections through
ko are not permitted. Thus in the following configuration:
@example
.XX... We label the .XX.4.
XO.... liberties of XO1234
XO.... order < 5 of XO1234
...... the O group: .12.4.
.X.X.. .X.X..
@end example
The convention that liberties of order >1 may not touch a
group of the opposite color means that knight's moves and
one space jumps are perceived as impenetrable barriers.
This is useful in determining when the string is becoming
surrounded.
The path may also not pass through a liberty at distance
1 if that liberty is flanked by two stones of the opposing color. This
reflects the fact that the O stone is blocked from expansion to the
left by the two X stones in the following situation:
@example
X.
.O
X.
@end example
@cindex distance from liberty to dragon
We say that n is the @dfn{distance} of the liberty of order n from the dragon.
@end quotation
@item @code{lunch}
@quotation
@cindex lunch (worm)
If nonzero, @code{lunch} points to a boundary worm which can be easily
captured. (It does not matter whether or not the string can be
defended.)
@end quotation
@end itemize
We have two distinct notions of cutting stone, which we keep track
of in the separate fields @code{worm.cutstone} and @code{worm.cutstone2}.
We use currently use both concepts in parallel.
@itemize
@item @code{cutstone}
@quotation
@cindex cutting stone
This field is equal to 2 for cutting stones, 1 for potential cutting
stones. Otherwise it is zero. Definitions for this field: a @dfn{cutting
stone} is one adjacent to two enemy strings, which do not have a liberty in
common. The most common type of cutting string is in this situation:
@example
XO
OX
@end example
@cindex cutting stone, potential
@cindex potential cutting stone
A @dfn{potential cutting stone} is adjacent to two enemy strings which do
share a liberty. For example, X in:
@example
XO
O.
@end example
For cutting strings we set @code{worm[].cutstone=2}. For
potential cutting strings we set @code{worm[].cutstone=1}.
@end quotation
@item @code{cutstone2}
@quotation
Cutting points are identified by the patterns in the connections
database. Proper cuts are handled by the fact that attacking and
defending moves also count as moves cutting or connecting the
surrounding dragons. The @code{cutstone2} field is set during
@code{find_cuts()}, called from @code{make_domains()}.
@end quotation
@findex find_cuts
@findex make_domains
@item @code{genus}
@quotation
@cindex genus (worm)
There are two separate notions of @dfn{genus} for worms and
dragons. The dragon notion is more important, so
@code{dragon[pos].genus} is a far more useful field than
@code{worm[pos].genus}. Both fields are intended as approximations
to the number of eyes. The @dfn{genus} of a string is the number
of connected components of its complement, minus one. It is
an approximation to the number of eyes of the string.
@end quotation
@item @code{inessential}
@quotation
@cindex inessential string
An @dfn{inessential} string is one which meets a
criterion designed to guarantee that it has no life
potential unless a particular surrounding string of the
opposite color can be killed. More precisely an
@dfn{inessential string} is a string S of genus zero,
not adjacent to any opponent string which can be easily
captured, and which has no edge liberties or second
order liberties, and which satisfies the following
further property: If the string is removed from the
board, then the remaining cavity only borders worms of the
opposite color.
@end quotation
@findex unconditional_life
@item @code{invincible}
@quotation
@cindex invincible worm
An @dfn{invincible} worm is one which GNU Go thinks
cannot be captured. Invincible worms are computed by the
function @code{unconditional_life()} which tries to
find those worms of the given color that can never be captured,
even if the opponent is allowed an arbitrary number of consecutive
moves.
@end quotation
@item unconditional_status
@quotation
Unconditional status is also set by the function
@code{unconditional_life}. This is set @code{ALIVE} for stones which are
invincible. Stones which can not be turned invincible even if the
defender is allowed an arbitrary number of consecutive moves are given
an unconditional status of @code{DEAD}. Empty points where the opponent
cannot form an invincible worm are called unconditional territory. The
unconditional status is set to @code{WHITE_TERRITORY} or
@code{BLACK_TERRITORY} depending on who owns the territory. Finally, if
a stone can be captured but is adjacent to unconditional territory of
its own color, it is also given the unconditional status @code{ALIVE}.
In all other cases the unconditional status is @code{UNKNOWN}.
To make sense of these definitions it is important to notice that any
stone which is alive in the ordinary sense (even if only in seki) can be
transformed into an invincible group by some number of consecutive
moves. Well, this is not entirely true because there is a rare class of
seki groups not satisfying this condition. Exactly which these are is
left as an exercise for the reader. Currently @code{unconditional_life},
which strictly follows the definitions above, calls such seki groups
unconditionally dead, which of course is a misfeature. It is possible to
avoid this problem by making the algorithm slightly more complex, but
this is left for a later revision.
@end quotation
@item @code{int attack_points[MAX_TACTICAL_POINTS]}
@item @code{attack_codes[MAX_TACTICAL_POINTS]}
@item @code{int defense_points[MAX_TACTICAL_POINTS];}
@item @code{int defend_codes[MAX_TACTICAL_POINTS];}
@quotation
If the tactical reading code (@pxref{Tactical Reading}) finds that the
worm can be attacked, @code{attack_points[0]} is a point of attack, and
@code{attack_codes[0]} is the attack code, @code{WIN}, @code{KO_A} or
@code{KO_B}. If multiple attacks are known, @code{attack_points[k]} and
@code{attack_codes[k]} are used. Similarly with the defense
codes and defense points.
@end quotation
@item @code{int attack_threat_points[MAX_TACTICAL_POINTS];}
@item @code{int attack_threat_codes[MAX_TACTICAL_POINTS];}
@item @code{int defense_threat_points[MAX_TACTICAL_POINTS];}
@item @code{int defense_threat_codes[MAX_TACTICAL_POINTS];}
@quotation
These are points that threaten to attack or defend a worm.
@end quotation
@end itemize
The function @code{makeworms()} will generate data for all worms.
@node Amalgamation
@section Amalgamation
@cindex amalgamation of worms into dragons
A dragon, we have said, is a group of stones which are treated as a
unit. It is a working hypothesis that these stones will live or die
together. Thus the program will not expect to disconnect an opponent's
strings if they have been amalgamated into a single dragon.
The function @code{make_dragons()} will amalgamate worms into dragons by
maintaining separate arrays @code{worm[]} and @code{dragon[]} containing
similar data. Each dragon is a union of worms. Just as the data maintained in
@code{worm[]} is constant on each worm, the data in
@code{dragon[]} is constant on each dragon.
Amalgamation of worms in GNU Go proceeds as follows.
First we amalgamate all boundary components of an eyeshape. Thus in
the following example:
@example
.OOOO. The four X strings are amalgamated into a
OOXXO. single dragon because they are the boundary
OX..XO components of a blackbordered cave. The
OX..XO cave could contain an inessential string
OOXXO. with no effect on this amalgamation.
XXX...
@end example
@findex dragon_eye
The code for this type of amalgamation is in the routine
@code{dragon_eye()}, discussed further in EYES.
Next, we amalgamate strings which seem uncuttable. We amalgamate dragons
which either share two or more common liberties, or share one liberty
into the which the opponent cannot play without being
captured. (ignores ko rule).
@example
X. X.X XXXX.XXX X.O
.X X.X X......X X.X
XXXXXX.X OXX
@end example
A database of connection patterns may be found in @file{patterns/conn.db}.
@node Connection
@section Connection
@cindex connections
The fields @code{black_eye.cut} and @code{white_eye.cut} are set where the
opponent can cut, and this is done by the B (break) class patterns in
@file{conn.db}. There are two important uses for this field, which can be
accessed by the autohelper functions @code{xcut()} and @code{ocut()}. The
first use is to stop amalgamation in positions like
@example
..X..
OO*OO
X.O.X
..O..
@end example
@noindent
where X can play at * to cut off either branch. What happens
here is that first connection pattern CB1 finds the double cut
and marks * as a cutting point. Later the C (connection) class
patterns in conn.db are searched to find secure connections
over which to amalgamate dragons. Normally a diagonal
connection would be deemed secure and amalgamated by connection
pattern CC101, but there is a constraint requiring that neither of
the empty intersections is a cutting point.
@findex amalgamate_most_valuable_helper
A weakness with this scheme is that X can only cut one connection, not
both, so we should be allowed to amalgamate over one of the connections.
This is performed by connection pattern CC401, which with the help of
@code{amalgamate_most_valuable_helper()} decides which connection to
prefer.
The other use is to simplify making alternative connection patterns to
the solid connection. Positions where the diag_miai helper thinks a
connection is necessary are marked as cutting points by connection
pattern 12. Thus we can write a connection pattern like @code{CC6}:
@example
?xxx? straight extension to connect
XOO*?
O...?
:8,C,NULL
?xxx?
XOOb?
Oa..?
;xcut(a) && odefend_against(b,a)
@end example
@noindent
where we verify that a move at @code{*} would stop the enemy from safely
playing at the cutting point, thus defending against the cut.
@node Half Eyes
@section Half Eyes and False Eyes
@cindex half eye
@cindex false eye
A @dfn{half eye} is a place where, if the defender plays first, an eye
will materialize, but where if the attacker plays first, no eye will
materialize. A @dfn{false eye} is a vertex which is surrounded by a
dragon yet is not an eye. Here is a half eye:
@example
@group
XXXXX
OO..X
O.O.X
OOXXX
@end group
@end example
Here is a false eye:
@example
@group
XXXXX
XOO.X
O.O.X
OOXXX
@end group
@end example
The "topological" algorithm for determining half and false eyes
is described elsewhere (@pxref{Eye Topology}).
The half eye data is collected in the dragon array. Before this is done,
however, an auxiliary array called half_eye_data is filled with
information. The field @code{type} is 0, or else @code{HALF_EYE} or
@code{FALSE_EYE} depending on which type is found; the fields
@code{attack_point[]} point to up to 4 points to attack
the half eye, and similarly @code{defense_point[]} gives points
to defend the half eye.
@example
@group
struct half_eye_data half_eye[MAX_BOARD];
struct half_eye_data @{
float value; /* Topological eye value */
int type; /* HALF_EYE or FALSE_EYE */
int num_attacks; /* Number of attacking points */
int attack_point[4]; /* The moves to attack a topological halfeye */
int num_defends; /* Number of defending points */
int defense_point[4]; /* The moves to defend a topological halfeye */
@};
@end group
@end example
The array @code{struct half_eye_data half_eye[MAX_BOARD]}
contains information about half and false eyes. If the type is
@code{HALF_EYE} then up to four moves are recorded which can
either attack or defend the eye. In rare cases the attack points
could be different from the defense points.
@node Dragons
@section Dragons
@cindex dragons
The array @code{struct dragon_data dragon[MAX_BOARD]}
collects information about the dragons. We will give definitions of the
various fields. Each field has constant value at each vertex of the
dragon. (Fields will be discussed below.)
@example
struct dragon_data @{
int color; /* its color */
int id; /* the index into the dragon2 array */
int origin; /* the origin of the dragon. Two vertices */
/* are in the same dragon iff they have */
/* same origin. */
int size; /* size of the dragon */
float effective_size; /* stones and surrounding spaces */
int crude_status; /* (ALIVE, DEAD, UNKNOWN, CRITICAL)*/
int status; /* best trusted status */
@};
extern struct dragon_data dragon[BOARDMAX];
@end example
Other fields attached to the dragon are contained in the @code{dragon_data2}
struct array. (Fields will be discussed below.)
@example
struct dragon_data2 @{
int origin;
int adjacent[MAX_NEIGHBOR_DRAGONS];
int neighbors;
int hostile_neighbors;
int moyo_size;
float moyo_territorial_value;
int safety;
float weakness;
float weakness_pre_owl;
int escape_route;
struct eyevalue genus;
int heye;
int lunch;
int surround_status;
int surround_size;
int semeais;
int semeai_margin_of_safety;
int semeai_defense_point;
int semeai_defense_certain;
int semeai_attack_point;
int semeai_attack_certain;
int owl_threat_status;
int owl_status;
int owl_attack_point;
int owl_attack_code;
int owl_attack_certain;
int owl_second_attack_point;
int owl_defense_point;
int owl_defense_code;
int owl_defense_certain;
int owl_second_defense_point;
int owl_attack_kworm;
int owl_defense_kworm;
@};
extern struct dragon_data2 *dragon2;
@end example
The difference between the two arrays is that the @code{dragon} array
is indexed by the board, and there is a copy of the dragon data
at every stone in the dragon, while there is only one copy of
the dragon2 data. The dragons are numbered, and the @code{id} field
of the dragon is a key into the dragon2 array. Two macros DRAGON
and DRAGON2 are provided for gaining access to the two arrays.
@example
#define DRAGON2(pos) dragon2[dragon[pos].id]
#define DRAGON(d) dragon[dragon2[d].origin]
@end example
Thus if you know the position @code{pos} of a stone in the dragon
you can access the dragon array directly, for example accessing the
origin with @code{dragon[pos].origin}. However if you need a field
from the dragon2 array, you can access it using the DRAGON2 macro,
for example you can access its neighor dragons by
@example
for (k = 0; k < DRAGON2(pos).neighbors; k++) @{
int d = DRAGON2(pos).adjacent[k];
int apos = dragon2[d].origin;
do_something(apos);
@}
@end example
Similarly if you know the dragon number (which is @code{dragon[pos].id})
then you can access the @code{dragon2} array directly, or you can
access the @code{dragon} array using the DRAGON macro.
Here are the definitions of each field in the @code{dragon} arrray.
@itemize @bullet
@item @code{color}
@quotation
@cindex color (dragon)
The color of the dragon.
@end quotation
@item @code{id}
@cindex dragon number
@quotation
The dragon number, used as a key into the @code{dragon2} array.
@end quotation
@item origin
@cindex dragon origin
@quotation
The origin of the dragon is a unique particular vertex
of the dragon, useful for determining when two vertices belong
to the same dragon. Before amalgamation the worm origins are
copied to the dragon origins. Amalgamation of two dragons
amounts to changing the origin of one.
@end quotation
@item size
@cindex dragon size
@quotation
The number of stones in the dragon.
@end quotation
@item effective size
@cindex effective size
@quotation
The sum of the effective sizes of the constituent worms.
Remembering that vertices equidistant between two or more worms are
counted fractionally in @code{worm.effective_size}, this equals the
cardinality of the dragon plus the number of empty vertices which are
nearer this dragon than any other.
@end quotation
@item crude_status
@quotation
(ALIVE, DEAD, UNKNOWN, CRITICAL). An early measure of the life
potential of the dragon. It is computed before the owl code is
run and is superceded by the status as soon as that becomes
available.
@end quotation
@item status
@cindex dragon status
@quotation
The dragon status is the best measure of the dragon's health.
It is computed after the owl code is run, then revised again
when the semeai code is run.
@end quotation
@end itemize
Here are definitions of the fields in the @code{dragon2} array.
@itemize @bullet
@item origin
@quotation
The origin field is duplicated here.
@end quotation
@item adjacent
@item @code{adjacent[MAX_NEIGHBOR_DRAGONS]}
@cindex neighbor dragons
@cindex adjacent dragons
@findex find_neighbor_dragons
@quotation
Dragons of either color near the given one are called @dfn{neighbors}.
They are computed by the function @code{find_neighbor_dragons()}.
The @code{dragon2.adjacent} array gives the dragon numbers of
these dragons.
@end quotation
@item @code{neighbors}
@cindex neighbor dragons
@cindex adjacent dragons
@findex find_neighbor_dragons
@quotation
Dragons of either color near the given one are called @dfn{neighbors}.
They are computed by the function @code{find_neighbor_dragons()}.
The @code{dragon2.adjacent} array gives the dragon numbers of
these dragons.
@end quotation
@item neighbors
@quotation
The number of neighbor dragons.
@end quotation
@item hostile_neighbors
@quotation
The number of neighbor dragons of the opposite color.
@end quotation
@item moyo_size
@item float moyo_territorial_value
@findex compute_surrounding_moyo_sizes
@quotation
The function @code{compute_surrounding_moyo_sizes()} assigns
a size and a territorial value to the moyo around
each dragon (@pxref{Territory and Moyo}). This is the
moyo size. They are recorded in these fields.
@end quotation
@item safety
@cindex dragon safety
@quotation
The dragon safety can take on one of the values
@itemize @minus
@item TACTICALLY_DEAD - a dragon consisting of a single worm found dead by the
reading code (very reliable)
@item ALIVE - found alive by the owl or semeai code
@item STRONGLY_ALIVE - alive without much question
@item INVINCIBLE - definitively alive even after many tenukis
@item ALIVE_IN_SEKI - determined to be seki by the semeai code
@item CRITICAL - lives or dies depending on who moves first
@item DEAD - found to be dead by the owl code
@item INESSENTIAL - the dragon is unimportant (e.g. nakade stones) and dead
@end itemize
@end quotation
@item weakness
@item weakness_pre_owl
@cindex dragon weakness
@cindex weakness
@quotation
A floating point measure of the safety of a dragon. The dragon
weakness is a number between 0. and 1., higher numbers for
dragons in greater need of safety. The field @code{weakness_pre_owl}
is a preliminary computation before the owl code is run.
@end quotation
@item escape_route
@cindex dragon escape_route
@cindex escape_route
@findex compute_escape
@quotation
A measure of the dragon's potential to escape towards safety,
in case it cannot make two eyes locally. Documentation
may be found in @ref{Escape}.
@end quotation
@item struct eyevalue genus
@cindex dragon genus
@cindex genus
@quotation
The approximate number of eyes the dragon can be expected to
get. Not guaranteed to be accurate. The eyevalue struct, which
is used throughout the engine, is declared thus:
@example
struct eyevalue @{
unsigned char a; /* # of eyes if attacker plays twice */
unsigned char b; /* # of eyes if attacker plays first */
unsigned char c; /* # of eyes if defender plays first */
unsigned char d; /* # of eyes if defender plays twice */
@};
@end example
@end quotation
@item heye
@quotation
Location of a half eye attached to the dragon.
@end quotation
@item lunch
@cindex dragon lunch
@cindex lunch
@quotation
If nonzero, this is the location of a boundary string which
can be captured. In contrast with worm lunches, a dragon
lunch must be able to defend itself.
@end quotation
@item surround_status
@item surround_size
@cindex surround_status
@cindex surround_size
@cindex surround
@quotation
In estimating the safety of a dragon it is useful to know if
it is @dfn{surrounded}. See @ref{Surrounded Dragons} and
the comments in @file{surround.c} for more information about the
algorithm. Used in computing the escape_route, and also callable
from patterns (currently used by CB258).
@end quotation
@item semeais
@item semeai_defense_point
@item semeai_defense_certain
@item semeai_attack_point
@item semeai_attack_certain
@cindex semeai
@cindex semeai_defense_point
@cindex semeai_defense_certain
@cindex semeai_attack_point
@cindex semeai_attack_certain
@quotation
If two dragons of opposite color both have the status CRITICAL
or DEAD they are in a @dfn{semeai} (capturing race), and their
status must be adjudicated by the function
@code{owl_analyze_semeai()} in @file{owl.c}, which attempts to
determine which is alive, which dead, or if the result is
seki, and whether it is important who moves first. The
function @file{new_semeai()} in @file{semeai.c} attempts
to revise the statuses and to generate move reasons based
on these results. The field @code{dragon2.semeais} is nonzero
if the dragon is an element of a semeai, and equals the
number of semeais (seldom more than one). The semeai defense
and attack points are locations the defender or attacker
must move to win the semeai. The field @code{semeai_margin_of_safety}
is intended to indicate whether the semeai is close or not
but currently this field is not maintained. The fields
@code{semeai_defense_certain} and @code{semeai_attack_certain}
indicate that the semeai code was able to finish analysis
without running out of nodes.
@end quotation
@item owl_status
@quotation
This is a classification similar to @code{dragon.crude_status}, but
based on the life and death reading in @file{owl.c}.
The owl code (@pxref{The Owl Code}) is skipped for dragons
which appear safe by certain heuristics. If the owl code
is not run, the owl status is @code{UNCHECKED}.
If @code{owl_attack()} determines that the dragon cannot be
attacked, it is classified as @code{ALIVE}. Otherwise,
@code{owl_defend()} is run, and if it can be defended it
is classified as @code{CRITICAL}, and if not, as @code{DEAD}.
@end quotation
@item owl_attack_point
@cindex owl_attack_point
@quotation
If the dragon can be attacked this is the point to attack the dragon.
@end quotation
@item owl_attack_code
@cindex owl_attack_code
@quotation
The owl attack code, It can be WIN, KO_A, KO_B or 0 (@pxref{Return Codes}).
@end quotation
@item owl_attack_certain
@cindex owl_attack_certain
@quotation
The owl reading is able to finish analyzing the attack
without running out of nodes.
@end quotation
@item owl_second_attack_point
@cindex owl_second_attack_point
@quotation
A second attack point.
@end quotation
@item owl_defense_point
@cindex owl_defense_point
@quotation
If the dragon can be defended, this is the place to play.
@end quotation
@item owl_defense_code
@cindex owl_defense_code
@quotation
The owl defense code, It can be WIN, KO_A, KO_B or 0 (@pxref{Return Codes}).
@end quotation
@item owl_defense_certain
@cindex owl_defense_certain
@quotation
The owl code is able to finish analyzing the defense without
running out of nodes.
@end quotation
@item owl_second_defense_point
@cindex owl_second_defense_point
@quotation
A second owl defense point.
@end quotation
@end itemize
@node Dragons in Color
@section Colored Dragon Display
@cindex colored display
You can get a colored ASCII display of the board in which each dragon
is assigned a different letter; and the different values of
@code{dragon.status} values (@code{ALIVE}, @code{DEAD}, @code{UNKNOWN},
@code{CRITICAL}) have different colors. This is very handy for debugging.
A second diagram shows the values of @code{owl.status}. If this
is @code{UNCHECKED} the dragon is displayed in White.
Save a game in sgf format using CGoban, or using the @option{-o} option with
GNU Go itself.
Open an @command{xterm} or @command{rxvt} window. You may also use the Linux
console. Using the console, you may need to use ``SHIFT-PAGE UP'' to see the
first diagram. Xterm will only work if it is compiled with color support---if
you do not see the colors try @command{rxvt}. Make the background color black
and the foreground color white.
Execute:
@command{gnugo -l [filename] -L [movenum] -T} to get the colored display.
The color scheme: Green = @code{ALIVE}; Yellow = @code{UNKNOWN};
Cyan = @code{DEAD} and Red = @code{CRITICAL}. Worms which have been
amalgamated into the same dragon are labelled with the same letter.
Other useful colored displays may be obtained by using instead:
@itemize @bullet
@item the option -E to display eye spaces (@pxref{Eyes}).
@item the option -m 0x0180 to display territory, moyo and area
(@pxref{Territory and Moyo}).
@end itemize
The colored displays are documented elsewhere (@pxref{Colored Display}).