Updated README: Equal sign not required with `--mode` flag.
[sgk-go] / doc / owl.texi
CommitLineData
7eeb782e
AT
1In the tactical reading code in @file{reading.c}, the
2code generating the moves which are tried are all hand
3coded in C, for efficiency. There is much to be said for
4another type of reading, in which the moves to be tried are
5generated from a pattern database.
6
7GNU Go does three main types of pattern based reading. First,
8there is the OWL code (Optics with Limit Negotiation) which
9attempts to read out to a point where the code in
10@file{engine/optics.c} (@pxref{Eyes}) can be used to evaluate
11it. Like the tactical reading code, a persistent cache is
12employed to maintain some of the owl data from move to
13move. This is an essential speedup without which GNU Go would
14play too slowly.
15
16Secondly, there is the @file{engine/combination.c} which
17attempts to find combinations---situations where a series
18of threats eventually culminates in one that cannot be
19parried.
20
21Finally there is the semeai module. A @strong{semeai} is
22a capturing race between two adjacent DEAD or CRITICAL
23dragons of opposite colors. The principal function,
24@code{owl_analyze_semeai()} is contained in @file{owl.c}.
25Due to the complex nature of semeais, the results of
26this function are more frequently wrong than the usual
27owl code.
28
29@menu
30* The Owl Code:: Life and death reading
31* Combinations:: Combinations
32@end menu
33
34@node The Owl Code
35@section The Owl Code
36
37The life and death code in @file{optics.c}, described elsewhere
38(@pxref{Eyes}), works reasonably well as long as the position is in a
39@dfn{terminal position}, which we define to be one where there are no
40moves left which can expand the eye space, or limit it. In situations
41where the dragon is surrounded, yet has room to thrash around a bit
42making eyes, a simple application of the graph-based analysis will not
43work. Instead, a bit of reading is needed to reach a terminal position.
44
45The defender tries to expand his eyespace, the attacker to limit
46it, and when neither finds an effective move, the position is
47evaluated. We call this type of life and death reading
48@dfn{Optics With Limit-negotiation} (OWL). The module which
49implements it is in @file{engine/owl.c}.
50
51There are two reasonably small databases
52@file{patterns/owl_defendpats.db} and @file{patterns/owl_attackpats.db}
53of expanding and limiting moves. The code in @file{owl.c} generates a
54small move tree, allowing the attacker only moves from
55@file{owl_attackpats.db}, and the defender only moves from
56@file{owl_defendpats.db}. In addition to the moves suggested by
57patterns, vital moves from the eye space analysis are also tested.
58
59A third database, @file{owl_vital_apats.db} includes patterns which
60override the eyespace analysis done by the optics code. Since the
61eyeshape graphs ignore the complications of shortage of liberties and
62cutting points in the surrounding chains, the static analysis of
63eyespace is sometimes wrong. The problem is when the optics code says
64that a dragon definitely has 2 eyes, but it isn't true due to
65shortage of liberties, so the ordinary owl patterns never get into play.
66In such situations @file{owl_vital_apats.db} is the only available measure
67to correct mistakes by the optics. Currently the patterns in
68@file{owl_vital_apats.db} are only matched when the level is 9 or
69greater.
70
71The owl code is tuned by editing these three pattern databases,
72principally the first two.
73
74@findex owl_attack
75@findex owl_defend
76@findex compute_eyes_pessimistic
77A node of the move tree is considered @code{terminal} if no further moves
78are found from @file{owl_attackpats.db} or @file{owl_defendpats.db}, or if
79the function @code{compute_eyes_pessimistic()} reports that the group is
80definitely alive. At this point, the status of the group is evaluated.
81The functions @code{owl_attack()} and @code{owl_defend()}, with
82usage similar to @code{attack()} and @code{find_defense()}, make
83use of the owl pattern databases to generate the move tree and decide
84the status of the group.
85
86The function @code{compute_eyes_pessimistic()} used by the owl
87code is very conservative and only feels certain about eyes if the
88eyespace is completely closed (i.e. no marginal vertices).
89
90The maximum number of moves tried at each node is limited by
91the parameter @code{MAX_MOVES} defined at the beginning of
92@file{engine/owl.c}. The most most valuable moves are
93tried first, with the following restrictions:
94
95@itemize @bullet
96@item
97If @code{stackp > owl_branch_depth} then only one move is tried per
98variation.
99@item
100If @code{stackp > owl_reading_depth} then the reading terminates,
101and the situation is declared a win for the defender (since
102deep reading may be a sign of escape).
103@item
104If the node count exceeds @code{owl_node_limit}, the reading also
105terminates with a win for the defender.
106@item
107Any pattern with value 99 is considered a forced move: no
108other move is tried, and if two such moves are found, the function
109returns false. This is only relevant for the attacker.
110@item
111Any pattern in @file{patterns/owl_attackpats.db} and
112@file{patterns/owl_defendpats.db} with value 100 is considered a win: if
113such a pattern is found by @code{owl_attack} or @code{owl_defend}, the
114function returns true. This feature must be used most carefully.
115@end itemize
116
117The functions @code{owl_attack()} and @code{owl_defend()} may, like
118@code{attack()} and @code{find_defense()}, return an attacking or
119defending move through their pointer arguments. If the position is
120already won, @code{owl_attack()} may or may not return an attacking
121move. If it finds no move of interest, it will return @code{PASS}, that
122is, @code{0}. The same goes for @code{owl_defend()}.
123
124When @code{owl_attack()} or @code{owl_defend()} is called,
125the dragon under attack is marked in the array @code{goal}.
126The stones of the dragon originally on the board are marked
127with goal=1; those added by @code{owl_defend()} are marked
128with goal=2. If all the original strings of the original dragon
129are captured, @code{owl_attack()} considers the dragon to be defeated,
130even if some stones added later can make a live group.
131
132Only dragons with small escape route are studied when the
133functions are called from @code{make_dragons()}.
134
135The owl code can be conveniently tested using the
136@option{--decide-owl @var{location}} option. This should be used with
137@option{-t} to produce a useful trace, @option{-o} to produce
138an SGF file of variations produced when the life and death of
139the dragon at @var{location} is checked, or both.
140@option{--decide-position} performs the same analysis for all
141dragons with small escape route.
142
143@node Combinations
144@section Combination reading
145
146It may happen that no single one of a set of worms can be killed,
147yet there is a move that guarantees that at least one can be captured.
148The simplest example is a double atari. The purpose of the code in
149@file{combination.c} is to find such moves.
150
151For example, consider the following situation:
152
153@example
154
155+---------
156|....OOOOX
157|....OOXXX
158|..O.OXX..
159|.OXO.OX..
160|.OX..OO..
161|.XXOOOXO.
162|..*XXOX..
163|....XOX..
164|.XX..X...
165|X........
166
167@end example
168
169Every @samp{X} stone in this position is alive. However the move
170at @samp{*} produces a position in which at least one of four
171strings will get captured. This is a @emph{combination}.
172
173The driving function is called @code{atari_atari} because typically
174a combination involves a sequence of ataris culminating in a capture,
175though sometimes the moves involved are not ataris. For example in
176the above example, the first move at @samp{*} is @emph{not} an
177atari, though after @samp{O} defends the four stones above, a
178sequence of ataris ensues resulting in the capture of some
179string.
180
181Like the owl functions @code{atari_atari} does pattern-based
182reading. The database generating the attacking moves is
183@file{aa_attackpats.db}. One danger with this function is
184that the first atari tried might be irrelevant to the actual
185combination. To detect this possibility, once we've found a
186combination, we mark that first move as forbidden, then try
187again. If no combination of the same size or larger turns
188up, then the first move was indeed essential.
189
190@itemize @bullet
191@item @code{void combinations(int color)}
192@findex combinations
193@quotation
194Generate move reasons for combination attacks and defenses against
195them. This is one of the move generators called from genmove().
196@end quotation
197@item @code{int atari_atari(int color, int *attack_move, char defense_moves[BOARDMAX], int save_verbose)}
198@findex atari_atari
199@quotation
200Look for a combination for @code{color}. For the purpose of
201the move generation, returns the size of the smallest of the
202worms under attack.
203@end quotation
204@item @code{int atari_atari_confirm_safety(int color, int move, int *defense, int minsize, const char saved_dragons[BOARDMAX], const char saved_worms[BOARDMAX])}
205@findex atari_atari_confirm_safety
206@quotation
207Tries to determine whether a move is a blunder. Wrapper
208around atari_atari_blunder_size. Check whether a combination
209attack of size at least @code{minsize} appears after move at
210@code{move} has been made. The arrays @code{saved_dragons[]} and
211@code{saved_worms[]} should be one for stones belonging to dragons
212or worms respectively, which are supposedly saved by @code{move}.
213@end quotation
214@item @code{int atari_atari_blunder_size(int color, int move, int *defense, const char safe_stones[BOARDMAX])}
215@findex atari_atari_blunder_size
216@quotation
217This function checks whether any new combination attack appears after
218move at (move) has been made, and returns its size (in points).
219@code{safe_stones} marks which of our stones are supposedly safe
220after this move.
221@end quotation
222@end itemize
223
224
225