Before considering its move, GNU Go collects some data in several arrays. Two of these arrays, called worm and dragon, are discussed in this document. Others are discussed in see Eyes.

This information is intended to help evaluate the connectedness, eye shape, escape potential and life status of each group.

Later routines called by 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 make_worm() and make_dragon() in dragon.c.

A 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 string instead of worm.

A 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:

           OOOOO
          OOXXXOO
          OX...XO
          OXXXXXO
           OOOOO

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.

Worms
=====

The array 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.

     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];
     };

  * color

          The color of the worm.

  * size

          This field contains the cardinality of the worm.

  * effective_size

          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. effective_size is a floating point number. Only intersections at a distance of 4 or less are counted.

  * origin

          Each worm has a distinguished member, called its 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:

               worm[pos].origin == pos.

  * liberties

  * liberties2

  * liberties3

  * liberties4

          For a nonempty worm the field liberties is the number of liberties of the string. This is supplemented by LIBERTIES2, LIBERTIES3 and 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 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:

                         .XX...    We label the     .XX.4.
                         XO....    liberties of     XO1234
                         XO....    order < 5 of     XO1234
                         ......    the O group:     .12.4.
                         .X.X..                     .X.X..

          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:

                         X.
                         .O
                         X.

          We say that n is the distance of the liberty of order n from the dragon.

  * lunch

          If nonzero, lunch points to a boundary worm which can be easily captured.  (It does not matter whether or not the string can be defended.)

We have two distinct notions of cutting stone, which we keep track of in the separate fields worm.cutstone and worm.cutstone2. We use currently use both concepts in parallel.

  * cutstone

          This field is equal to 2 for cutting stones, 1 for potential cutting stones. Otherwise it is zero.  Definitions for this field: a 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:

                         XO
                         OX

          A potential cutting stone is adjacent to two enemy strings which do share a liberty. For example, X in:

                         XO
                         O.

          For cutting strings we set worm[].cutstone=2. For potential cutting strings we set worm[].cutstone=1.

  * cutstone2

          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 cutstone2 field is set during find_cuts(), called from make_domains().

  * genus

          There are two separate notions of genus for worms and dragons. The dragon notion is more important, so dragon[pos].genus is a far more useful field than worm[pos].genus. Both fields are intended as approximations to the number of eyes. The 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.

  * inessential

          An 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 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.

  * invincible

          An invincible worm is one which GNU Go thinks cannot be captured. Invincible worms are computed by the function 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.

  * unconditional_status

          Unconditional status is also set by the function unconditional_life. This is set 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 DEAD. Empty points where the opponent cannot form an invincible worm are called unconditional territory. The unconditional status is set to WHITE_TERRITORY or 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 ALIVE. In all other cases the unconditional status is 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 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.

  * int attack_points[MAX_TACTICAL_POINTS]

  * attack_codes[MAX_TACTICAL_POINTS]

  * int defense_points[MAX_TACTICAL_POINTS];

  * int defend_codes[MAX_TACTICAL_POINTS];

          If the tactical reading code (see Tactical Reading) finds that the worm can be attacked, attack_points[0] is a point of attack, and attack_codes[0] is the attack code, WIN, KO_A or KO_B. If multiple attacks are known, attack_points[k] and attack_codes[k] are used. Similarly with the defense codes and defense 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];

          These are points that threaten to attack or defend a worm.

The function makeworms() will generate data for all worms.

Amalgamation
============

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 make_dragons() will amalgamate worms into dragons by maintaining separate arrays worm[] and dragon[] containing similar data. Each dragon is a union of worms. Just as the data maintained in worm[] is constant on each worm, the data in 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:

     .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...

The code for this type of amalgamation is in the routine 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).

        X.    X.X     XXXX.XXX         X.O
        .X    X.X     X......X         X.X
                      XXXXXX.X         OXX

A database of connection patterns may be found in patterns/conn.db.

Connection
==========

The fields black_eye.cut and white_eye.cut are set where the opponent can cut, and this is done by the B (break) class patterns in conn.db.  There are two important uses for this field, which can be accessed by the autohelper functions xcut() and ocut(). The first use is to stop amalgamation in positions like

     ..X..
     OO*OO
     X.O.X
     ..O..

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.

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 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 CC6:

     ?xxx?     straight extension to connect
     XOO*?
     O...?

     :8,C,NULL

     ?xxx?
     XOOb?
     Oa..?

     ;xcut(a) && odefend_against(b,a)

where we verify that a move at * would stop the enemy from safely playing at the cutting point, thus defending against the cut.

Half Eyes and False Eyes
========================

A 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 false eye is a vertex which is surrounded by a dragon yet is not an eye. Here is a half eye:

     XXXXX
     OO..X
     O.O.X
     OOXXX

Here is a false eye:

     XXXXX
     XOO.X
     O.O.X
     OOXXX

The "topological" algorithm for determining half and false eyes is described elsewhere (see 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 type is 0, or else HALF_EYE or FALSE_EYE depending on which type is found; the fields attack_point[] point to up to 4 points to attack the half eye, and similarly defense_point[] gives points to defend the half eye.

     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 */
     };

The array struct half_eye_data half_eye[MAX_BOARD] contains information about half and false eyes.  If the type is 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.

Dragons
=======

The array 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.)

     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];

Other fields attached to the dragon are contained in the dragon_data2 struct array. (Fields will be discussed below.)

     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;

The difference between the two arrays is that the 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 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.

     #define DRAGON2(pos) dragon2[dragon[pos].id]
     #define DRAGON(d) dragon[dragon2[d].origin]

Thus if you know the position pos of a stone in the dragon you can access the dragon array directly, for example accessing the origin with 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

     for (k = 0; k < DRAGON2(pos).neighbors; k++) {
       int d = DRAGON2(pos).adjacent[k];
       int apos = dragon2[d].origin;
       do_something(apos);
     }

Similarly if you know the dragon number (which is dragon[pos].id) then you can access the dragon2 array directly, or you can access the dragon array using the DRAGON macro.

Here are the definitions of each field in the dragon arrray.

  * color

          The color of the dragon.

  * id

          The dragon number, used as a key into the dragon2 array.

  * origin

          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.

  * size

          The number of stones in the dragon.

  * effective size

          The sum of the effective sizes of the constituent worms. Remembering that vertices equidistant between two or more worms are counted fractionally in worm.effective_size, this equals the cardinality of the dragon plus the number of empty vertices which are nearer this dragon than any other.

  * crude_status

          (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.

  * status

          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.

Here are definitions of the fields in the dragon2 array.

  * origin

          The origin field is duplicated here.

  * adjacent

  * adjacent[MAX_NEIGHBOR_DRAGONS]

          Dragons of either color near the given one are called neighbors. They are computed by the function find_neighbor_dragons(). The dragon2.adjacent array gives the dragon numbers of these dragons.

  * neighbors

          Dragons of either color near the given one are called neighbors. They are computed by the function find_neighbor_dragons(). The dragon2.adjacent array gives the dragon numbers of these dragons.

  * neighbors

          The number of neighbor dragons.

  * hostile_neighbors

          The number of neighbor dragons of the opposite color.

  * moyo_size

  * float moyo_territorial_value

          The function compute_surrounding_moyo_sizes() assigns a size and a territorial value to the moyo around each dragon (see Territory and Moyo). This is the moyo size. They are recorded in these fields.

  * safety

          The dragon safety can take on one of the values

            - TACTICALLY_DEAD - a dragon consisting of a single worm found dead by the reading code (very reliable)

            - ALIVE - found alive by the owl or semeai code

            - STRONGLY_ALIVE - alive without much question

            - INVINCIBLE - definitively alive even after many tenukis

            - ALIVE_IN_SEKI - determined to be seki by the semeai code

            - CRITICAL - lives or dies depending on who moves first

            - DEAD - found to be dead by the owl code

            - INESSENTIAL - the dragon is unimportant (e.g. nakade stones) and dead

  * weakness

  * weakness_pre_owl

          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 weakness_pre_owl is a preliminary computation before the owl code is run.

  * escape_route

          A measure of the dragon's potential to escape towards safety, in case it cannot make two eyes locally. Documentation may be found in Escape.

  * struct eyevalue genus

          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:

               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 */
               };

  * heye

          Location of a half eye attached to the dragon.

  * lunch

          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.

  * surround_status

  * surround_size

          In estimating the safety of a dragon it is useful to know if it is surrounded. See Surrounded Dragons and the comments in surround.c for more information about the algorithm.  Used in computing the escape_route, and also callable from patterns (currently used by CB258).

  * semeais

  * semeai_defense_point

  * semeai_defense_certain

  * semeai_attack_point

  * semeai_attack_certain

          If two dragons of opposite color both have the status CRITICAL or DEAD they are in a semeai (capturing race), and their status must be adjudicated by the function owl_analyze_semeai() in 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 new_semeai() in semeai.c attempts to revise the statuses and to generate move reasons based on these results. The field 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 semeai_margin_of_safety is intended to indicate whether the semeai is close or not but currently this field is not maintained. The fields semeai_defense_certain and semeai_attack_certain indicate that the semeai code was able to finish analysis without running out of nodes.

  * owl_status

          This is a classification similar to dragon.crude_status, but based on the life and death reading in owl.c. The owl code (see The Owl Code) is skipped for dragons which appear safe by certain heuristics. If the owl code is not run, the owl status is UNCHECKED. If owl_attack() determines that the dragon cannot be attacked, it is classified as ALIVE. Otherwise, owl_defend() is run, and if it can be defended it is classified as CRITICAL, and if not, as DEAD.

  * owl_attack_point

          If the dragon can be attacked this is the point to attack the dragon.

  * owl_attack_code

          The owl attack code, It can be WIN, KO_A, KO_B or 0 (see Return Codes).

  * owl_attack_certain

          The owl reading is able to finish analyzing the attack without running out of nodes.

  * owl_second_attack_point

          A second attack point.

  * owl_defense_point

          If the dragon can be defended, this is the place to play.

  * owl_defense_code

          The owl defense code, It can be WIN, KO_A, KO_B or 0 (see Return Codes).

  * owl_defense_certain

          The owl code is able to finish analyzing the defense without running out of nodes.

  * owl_second_defense_point

          A second owl defense point.

Colored Dragon 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 dragon.status values (ALIVE, DEAD, UNKNOWN, CRITICAL) have different colors. This is very handy for debugging. A second diagram shows the values of owl.status. If this is UNCHECKED the dragon is displayed in White.

Save a game in sgf format using CGoban, or using the -o option with GNU Go itself.

Open an xterm or 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 rxvt. Make the background color black and the foreground color white.

Execute:

gnugo -l [filename] -L [movenum] -T to get the colored display.

The color scheme: Green = ALIVE; Yellow = UNKNOWN; Cyan = DEAD and Red = 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:

  * the option -E to display eye spaces (see Eyes).

  * the option -m 0x0180 to display territory, moyo and area (see Territory and Moyo).

The colored displays are documented elsewhere (see Colored Display).