| @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}). |
| |