Next: Dragons in Color, Previous: Half Eyes, Up: Worms and 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.
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.
The number of stones in the dragon.
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.
(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.
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.
The origin field is duplicated here.
adjacent[MAX_NEIGHBOR_DRAGONS]
Dragons of either color near the given one are called neighbors. They are computed by the functionfind_neighbor_dragons()
. Thedragon2.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 functionfind_neighbor_dragons()
. Thedragon2.adjacent
array gives the dragon numbers of these dragons.
The number of neighbor dragons.
The number of neighbor dragons of the opposite color.
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.
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
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.
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.
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 */ };
Location of a half eye attached to the dragon.
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.
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).
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 functionowl_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 fielddragon2.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 fieldsemeai_margin_of_safety
is intended to indicate whether the semeai is close or not but currently this field is not maintained. The fieldssemeai_defense_certain
andsemeai_attack_certain
indicate that the semeai code was able to finish analysis without running out of nodes.
This is a classification similar todragon.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 isUNCHECKED
. Ifowl_attack()
determines that the dragon cannot be attacked, it is classified asALIVE
. Otherwise,owl_defend()
is run, and if it can be defended it is classified asCRITICAL
, and if not, asDEAD
.
If the dragon can be attacked this is the point to attack the dragon.
The owl attack code, It can be WIN, KO_A, KO_B or 0 (see Return Codes).
The owl reading is able to finish analyzing the attack without running out of nodes.
A second attack point.
If the dragon can be defended, this is the place to play.
The owl defense code, It can be WIN, KO_A, KO_B or 0 (see Return Codes).
The owl code is able to finish analyzing the defense without running out of nodes.
A second owl defense point.