Updated README: Equal sign not required with `--mode` flag.
[sgk-go] / engine / optics.c
CommitLineData
7eeb782e
AT
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
2 * This is GNU Go, a Go program. Contact gnugo@gnu.org, or see *
3 * http://www.gnu.org/software/gnugo/ for more information. *
4 * *
5 * Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, *
6 * 2008 and 2009 by the Free Software Foundation. *
7 * *
8 * This program is free software; you can redistribute it and/or *
9 * modify it under the terms of the GNU General Public License as *
10 * published by the Free Software Foundation - version 3 or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License in file COPYING for more details. *
17 * *
18 * You should have received a copy of the GNU General Public *
19 * License along with this program; if not, write to the Free *
20 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
21 * Boston, MA 02111, USA. *
22\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
23
24#include "gnugo.h"
25
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29#include "liberty.h"
30#include "eyes.h"
31#include "gg_utils.h"
32
33#define MAXEYE 20
34
35
36/* This structure is used in communication between read_eye() and
37 * recognize_eye().
38 */
39struct vital_points {
40 int attacks[4 * MAXEYE];
41 int defenses[4 * MAXEYE];
42 int num_attacks;
43 int num_defenses;
44};
45
46
47static void
48compute_primary_domains(int color, int domain[BOARDMAX],
49 int lively[BOARDMAX],
50 int false_margins[BOARDMAX],
51 int first_time);
52static void count_neighbours(struct eye_data eyedata[BOARDMAX]);
53static int is_lively(int owl_call, int pos);
54static int false_margin(int pos, int color, int lively[BOARDMAX]);
55static void originate_eye(int origin, int pos,
56 int *esize, int *msize,
57 struct eye_data eye[BOARDMAX]);
58static int read_eye(int pos, int *attack_point, int *defense_point,
59 struct eyevalue *value,
60 struct eye_data eye[BOARDMAX],
61 struct half_eye_data heye[BOARDMAX],
62 int add_moves);
63static int recognize_eye(int pos, int *attack_point, int *defense_point,
64 struct eyevalue *value,
65 struct eye_data eye[BOARDMAX],
66 struct half_eye_data heye[BOARDMAX],
67 struct vital_points *vp);
68static void guess_eye_space(int pos, int effective_eyesize, int margins,
69 int bulk_score, struct eye_data eye[BOARDMAX],
70 struct eyevalue *value, int *pessimistic_min);
71static void reset_map(int size);
72static void first_map(int *map_value);
73static int next_map(int *q, int map[MAXEYE]);
74static void print_eye(struct eye_data eye[BOARDMAX],
75 struct half_eye_data heye[BOARDMAX], int pos);
76static void add_false_eye(int pos, struct eye_data eye[BOARDMAX],
77 struct half_eye_data heye[BOARDMAX]);
78static float topological_eye(int pos, int color,
79 struct eye_data my_eye[BOARDMAX],
80 struct half_eye_data heye[BOARDMAX]);
81static float evaluate_diagonal_intersection(int m, int n, int color,
82 int *attack_point,
83 int *defense_point,
84 struct eye_data my_eye[BOARDMAX]);
85
86
87/* These are used during the calculations of eye spaces. */
88static int black_domain[BOARDMAX];
89static int white_domain[BOARDMAX];
90
91/* Used internally by mapping functions. */
92static int map_size;
93static signed char used_index[MAXEYE];
94
95
96/*
97 * make_domains() is called from make_dragons() and from
98 * owl_determine_life(). It marks the black and white domains
99 * (eyeshape regions) and collects some statistics about each one.
100 */
101
102void
103make_domains(struct eye_data b_eye[BOARDMAX],
104 struct eye_data w_eye[BOARDMAX],
105 int owl_call)
106{
107 int k;
108 int pos;
109 int lively[BOARDMAX];
110 int false_margins[BOARDMAX];
111
112 memset(black_domain, 0, sizeof(black_domain));
113 memset(white_domain, 0, sizeof(white_domain));
114 memset(false_margins, 0, sizeof(false_margins));
115
116 if (b_eye)
117 memset(b_eye, 0, BOARDMAX * sizeof(b_eye[0]));
118 if (w_eye)
119 memset(w_eye, 0, BOARDMAX * sizeof(w_eye[0]));
120
121 /* Initialize eye data and compute the lively array. */
122 for (pos = BOARDMIN; pos < BOARDMAX; pos++)
123 if (ON_BOARD(pos))
124 lively[pos] = is_lively(owl_call, pos);
125
126 /* Compute the domains of influence of each color. */
127 compute_primary_domains(BLACK, black_domain, lively, false_margins, 1);
128 compute_primary_domains(WHITE, white_domain, lively, false_margins, 0);
129
130 /* Now we fill out the arrays b_eye and w_eye with data describing
131 * each eye shape.
132 */
133
134 for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
135 if (!ON_BOARD(pos))
136 continue;
137
138 if (board[pos] == EMPTY || !lively[pos]) {
139 if (black_domain[pos] == 0 && white_domain[pos] == 0) {
140 if (w_eye)
141 w_eye[pos].color = GRAY;
142 if (b_eye)
143 b_eye[pos].color = GRAY;
144 }
145 else if (black_domain[pos] == 1 && white_domain[pos] == 0 && b_eye) {
146 b_eye[pos].color = BLACK;
147 for (k = 0; k < 4; k++) {
148 int apos = pos + delta[k];
149 if (ON_BOARD(apos) && white_domain[apos] && !black_domain[apos]) {
150 b_eye[pos].marginal = 1;
151 break;
152 }
153 }
154 }
155 else if (black_domain[pos] == 0 && white_domain[pos] == 1 && w_eye) {
156 w_eye[pos].color = WHITE;
157 for (k = 0; k < 4; k++) {
158 int apos = pos + delta[k];
159 if (ON_BOARD(apos) && black_domain[apos] && !white_domain[apos]) {
160 w_eye[pos].marginal = 1;
161 break;
162 }
163 }
164 }
165 else if (black_domain[pos] == 1 && white_domain[pos] == 1) {
166 if (b_eye) {
167 for (k = 0; k < 4; k++) {
168 int apos = pos + delta[k];
169 if (ON_BOARD(apos) && black_domain[apos]
170 && !white_domain[apos]) {
171 b_eye[pos].marginal = 1;
172 b_eye[pos].color = BLACK;
173 break;
174 }
175 }
176 if (k == 4)
177 b_eye[pos].color = GRAY;
178 }
179
180 if (w_eye) {
181 for (k = 0; k < 4; k++) {
182 int apos = pos + delta[k];
183 if (ON_BOARD(apos) && white_domain[apos]
184 && !black_domain[apos]) {
185 w_eye[pos].marginal = 1;
186 w_eye[pos].color = WHITE;
187 break;
188 }
189 }
190 if (k == 4)
191 w_eye[pos].color = GRAY;
192 }
193 }
194 }
195 }
196
197 /* The eye spaces are all found. Now we need to find the origins. */
198 partition_eyespaces(b_eye, BLACK);
199 partition_eyespaces(w_eye, WHITE);
200}
201
202/* Find connected eyespace components and compute relevant statistics. */
203void
204partition_eyespaces(struct eye_data eye[BOARDMAX], int color)
205{
206 int pos;
207
208 if (!eye)
209 return;
210
211 for (pos = BOARDMIN; pos < BOARDMAX; pos++)
212 if (ON_BOARD(pos))
213 eye[pos].origin = NO_MOVE;
214
215 for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
216 if (!ON_BOARD(pos))
217 continue;
218 if (eye[pos].origin == NO_MOVE && eye[pos].color == color) {
219 int esize = 0;
220 int msize = 0;
221
222 originate_eye(pos, pos, &esize, &msize, eye);
223 eye[pos].esize = esize;
224 eye[pos].msize = msize;
225 }
226 }
227
228 /* Now we count the number of neighbors and marginal neighbors
229 * of each vertex.
230 */
231 count_neighbours(eye);
232}
233
234
235/* Compute the domains of influence of each color, used in determining
236 * eye shapes. NOTE: the term influence as used here is distinct from the
237 * influence in influence.c.
238 *
239 * For this algorithm the strings which are not lively are invisible. Ignoring
240 * these, the algorithm assigns friendly influence to:
241 *
242 * (1) every vertex which is occupied by a (lively) friendly stone,
243 * (2) every empty vertex adjoining a (lively) friendly stone,
244 * (3) every empty vertex for which two adjoining vertices (not
245 * on the first line) in the (usually 8) surrounding ones have friendly
246 * influence, with two CAVEATS explained below.
247 *
248 * Thus in the following diagram, e would be assigned friendly influence
249 * if a and b have friendly influence, or a and d. It is not sufficent
250 * for b and d to have friendly influence, because they are not adjoining.
251 *
252 * uabc
253 * def
254 * ghi
255 *
256 * The constraint that the two adjoining vertices not lie on the first
257 * line prevents influence from leaking under a stone on the third line.
258 *
259 * The first CAVEAT alluded to above is that even if a and b have friendly
260 * influence, this does not cause e to have friendly influence if there
261 * is a lively opponent stone at d. This constraint prevents
262 * influence from leaking past knight's move extensions.
263 *
264 * The second CAVEAT is that even if a and b have friendly influence
265 * this does not cause e to have influence if there are lively opponent
266 * stones at u and at c. This prevents influence from leaking past
267 * nikken tobis (two space jumps).
268 *
269 * The corner vertices are handled slightly different.
270 *
271 * +---
272 * |ab
273 * |cd
274 *
275 * We get friendly influence at a if we have friendly influence
276 * at b or c and no lively unfriendly stone at b, c or d.
277 *
278 */
279
280#define sufficient_influence(pos, apos, bpos) \
281 (ON_BOARD(bpos) && influence[bpos] > threshold[pos] - influence[apos])
282
283static void
284compute_primary_domains(int color, int domain[BOARDMAX],
285 int lively[BOARDMAX],
286 int false_margins[BOARDMAX],
287 int first_time)
288{
289 int other = OTHER_COLOR(color);
290 int i, j, k;
291 int pos, pos2;
292 int own, enemy;
293 signed char threshold[BOARDMAX];
294 signed char influence[BOARDMAX];
295 int list[BOARDMAX];
296 int size = 0, lastchange = 0;
297
298 memset(threshold, 0, sizeof(threshold));
299 memset(influence, 0, sizeof(influence));
300
301 /* In the first pass we
302 * 1. Give influence to lively own stones and their neighbors.
303 * (Cases (1) and (2) above.)
304 * 2. Fill influence[] and threshold[] arrays with initial values.
305 */
306 for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
307 if (!ON_BOARD(pos))
308 continue;
309
310 if (lively[pos]) {
311 if (board[pos] == color) {
312 domain[pos] = 1; /* Case (1) above. */
313 influence[pos] = 1;
314 }
315 else
316 influence[pos] = -1;
317 continue;
318 }
319
320 own = enemy = 0;
321 for (k = 0; k < 4; k++) {
322 pos2 = pos + delta[k];
323 if (ON_BOARD(pos2) && lively[pos2]) {
324 if (board[pos2] == color)
325 own = 1;
326 else
327 enemy = 1;
328 }
329 }
330
331 if (own) {
332 /* To explain the asymmetry between the first time around
333 * this loop and subsequent ones, a false margin is adjacent
334 * to both B and W lively stones, so it's found on the first
335 * pass through the loop.
336 */
337 if (first_time) {
338 if (board[pos] == EMPTY && (false_margin(pos, color, lively)
339 || false_margin(pos, other, lively)))
340 false_margins[pos] = 1;
341 else {
342 domain[pos] = 1;
343 influence[pos] = 1;
344 }
345 }
346 else if (board[pos] != EMPTY || !false_margins[pos]) {
347 domain[pos] = 1;
348 influence[pos] = 1;
349 }
350 }
351 else
352 list[size++] = pos;
353
354 if (enemy) {
355 threshold[pos] = 1;
356 influence[pos]--;
357 }
358 else if (is_edge_vertex(pos))
359 influence[pos]--;
360 }
361
362 /* Now we loop over the board until no more vertices can be added to
363 * the domain through case (3) above.
364 */
365 if (size) {
366 k = size;
367 while (1) {
368 if (!k)
369 k = size;
370 pos = list[--k];
371
372 /* Case (3) above. */
373 if (sufficient_influence(pos, SOUTH(pos), SE(pos))
374 || sufficient_influence(pos, SOUTH(pos), SW(pos))
375 || sufficient_influence(pos, EAST(pos), SE(pos))
376 || sufficient_influence(pos, EAST(pos), NE(pos))
377 || sufficient_influence(pos, WEST(pos), SW(pos))
378 || sufficient_influence(pos, WEST(pos), NW(pos))
379 || sufficient_influence(pos, NORTH(pos), NW(pos))
380 || sufficient_influence(pos, NORTH(pos), NE(pos))) {
381 domain[pos] = 1;
382 influence[pos]++;
383
384 if (!--size)
385 break;
386 if (k < size)
387 list[k] = list[size];
388 else
389 k--;
390 lastchange = k;
391 }
392 else if (k == lastchange)
393 break; /* Looped the whole list and found nothing new */
394 }
395 }
396
397 if (0 && (debug & DEBUG_EYES)) {
398 start_draw_board();
399 for (i = 0; i < board_size; i++)
400 for (j = 0; j < board_size; j++) {
401 draw_color_char(i, j, domain[POS(i, j)] ? '1' : '0', GG_COLOR_BLACK);
402 }
403 end_draw_board();
404 }
405}
406
407
408static void
409count_neighbours(struct eye_data eyedata[BOARDMAX])
410{
411 int pos;
412 int k;
413
414 for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
415 if (!ON_BOARD(pos) || eyedata[pos].origin == NO_MOVE)
416 continue;
417
418 eyedata[pos].esize = eyedata[eyedata[pos].origin].esize;
419 eyedata[pos].msize = eyedata[eyedata[pos].origin].msize;
420 eyedata[pos].neighbors = 0;
421 eyedata[pos].marginal_neighbors = 0;
422
423 for (k = 0; k < 4; k++) {
424 int pos2 = pos + delta[k];
425 if (ON_BOARD(pos2) && eyedata[pos2].origin == eyedata[pos].origin) {
426 eyedata[pos].neighbors++;
427 if (eyedata[pos2].marginal)
428 eyedata[pos].marginal_neighbors++;
429 }
430 }
431 }
432}
433
434
435static int
436is_lively(int owl_call, int pos)
437{
438 if (board[pos] == EMPTY)
439 return 0;
440
441 if (owl_call)
442 return owl_lively(pos);
443 else
444 return (!worm[pos].inessential
445 && (worm[pos].attack_codes[0] == 0
446 || worm[pos].defense_codes[0] != 0));
447}
448
449
450/* In the following situation, we do not wish the vertex at 'a'
451 * included in the O eye space:
452 *
453 * OOOOXX
454 * OXaX..
455 * ------
456 *
457 * This eyespace should parse as (X), not (X!). Thus the vertex
458 * should not be included in the eyespace if it is adjacent to
459 * an X stone which is alive, yet X cannot play safely at a.
460 * The function returns 1 if this situation is found at
461 * (pos) for color O.
462 *
463 * The condition above is true, curiously enough, also for the
464 * following case:
465 * A group has two eyes, one of size 1 and one which is critical 1/2.
466 * It also has to have less than 4 external liberties, since the
467 * reading has to be able to capture the group tactically. In that
468 * case, the eye of size one will be treated as a false marginal.
469 * Thus we have to exclude this case, which is done by requiring (pos)
470 * to be adjacent to both white and black stones. Since this test is
471 * least expensive, we start with it.
472 *
473 * As a second optimization we require that one of the other colored
474 * neighbors is not lively. This should cut down on the number of
475 * calls to attack() and safe_move().
476 */
477
478static int
479false_margin(int pos, int color, int lively[BOARDMAX])
480{
481 int other = OTHER_COLOR(color);
482 int neighbors = 0;
483 int k;
484 int all_lively;
485 int potential_false_margin;
486
487 /* Require neighbors of both colors. */
488 for (k = 0; k < 4; k++)
489 if (ON_BOARD(pos + delta[k]))
490 neighbors |= board[pos + delta[k]];
491
492 if (neighbors != (WHITE | BLACK))
493 return 0;
494
495 /* At least one opponent neighbor should be not lively. */
496 all_lively = 1;
497 for (k = 0; k < 4; k++)
498 if (board[pos + delta[k]] == other && !lively[pos + delta[k]])
499 all_lively = 0;
500
501 if (all_lively)
502 return 0;
503
504 potential_false_margin = 0;
505 for (k = 0; k < 4; k++) {
506 int apos = pos + delta[k];
507 if (board[apos] != other || !lively[apos])
508 continue;
509
510 if (stackp == 0 && worm[apos].attack_codes[0] == 0)
511 potential_false_margin = 1;
512
513 if (stackp > 0 && !attack(apos, NULL))
514 potential_false_margin = 1;
515 }
516
517 if (potential_false_margin && safe_move(pos, other) == 0) {
518 DEBUG(DEBUG_EYES, "False margin for %C at %1m.\n", color, pos);
519 return 1;
520 }
521
522 return 0;
523}
524
525
526/*
527 * originate_eye(pos, pos, *esize, *msize, eye) creates an eyeshape
528 * with origin pos. esize and msize return the size and the number of
529 * marginal vertices. The repeated variables (pos) are due to the
530 * recursive definition of the function.
531 */
532static void
533originate_eye(int origin, int pos,
534 int *esize, int *msize,
535 struct eye_data eye[BOARDMAX])
536{
537 int k;
538 ASSERT_ON_BOARD1(origin);
539 ASSERT_ON_BOARD1(pos);
540 gg_assert(esize != NULL);
541 gg_assert(msize != NULL);
542
543 eye[pos].origin = origin;
544 (*esize)++;
545 if (eye[pos].marginal)
546 (*msize)++;
547
548 for (k = 0; k < 4; k++) {
549 int pos2 = pos + delta[k];
550 if (ON_BOARD(pos2)
551 && eye[pos2].color == eye[pos].color
552 && eye[pos2].origin == NO_MOVE
553 && (!eye[pos2].marginal || !eye[pos].marginal))
554 originate_eye(origin, pos2, esize, msize, eye);
555 }
556}
557
558
559/*
560 * propagate_eye(origin) copies the data at the (origin) to the
561 * rest of the eye (invariant fields only).
562 */
563
564void
565propagate_eye(int origin, struct eye_data eye[BOARDMAX])
566{
567 int pos;
568
569 for (pos = BOARDMIN; pos < BOARDMAX; pos++)
570 if (ON_BOARD(pos) && eye[pos].origin == origin) {
571 eye[pos].color = eye[origin].color;
572 eye[pos].esize = eye[origin].esize;
573 eye[pos].msize = eye[origin].msize;
574 eye[pos].origin = eye[origin].origin;
575 eye[pos].value = eye[origin].value;
576 }
577}
578
579
580/* Find the dragon or dragons surrounding an eye space. Up to
581 * max_dragons dragons adjacent to the eye space are added to
582 * the dragon array, and the number of dragons found is returned.
583 */
584
585int
586find_eye_dragons(int origin, struct eye_data eye[BOARDMAX], int eye_color,
587 int dragons[], int max_dragons)
588{
589 int mx[BOARDMAX];
590 int num_dragons = 0;
591 int pos;
592
593 memset(mx, 0, sizeof(mx));
594 DEBUG(DEBUG_MISCELLANEOUS, "find_eye_dragons: %1m %C\n", origin, eye_color);
595 for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
596 if (board[pos] == eye_color
597 && mx[dragon[pos].origin] == 0
598 && ((ON_BOARD(SOUTH(pos))
599 && eye[SOUTH(pos)].origin == origin
600 && !eye[SOUTH(pos)].marginal)
601 || (ON_BOARD(WEST(pos))
602 && eye[WEST(pos)].origin == origin
603 && !eye[WEST(pos)].marginal)
604 || (ON_BOARD(NORTH(pos))
605 && eye[NORTH(pos)].origin == origin
606 && !eye[NORTH(pos)].marginal)
607 || (ON_BOARD(EAST(pos))
608 && eye[EAST(pos)].origin == origin
609 && !eye[EAST(pos)].marginal))) {
610 DEBUG(DEBUG_MISCELLANEOUS,
611 " dragon: %1m %1m\n", pos, dragon[pos].origin);
612 mx[dragon[pos].origin] = 1;
613 if (dragons != NULL && num_dragons < max_dragons)
614 dragons[num_dragons] = dragon[pos].origin;
615 num_dragons++;
616 }
617 }
618
619 return num_dragons;
620}
621
622/* Print debugging data for the eyeshape at (i,j). Useful with GDB.
623 */
624
625static void
626print_eye(struct eye_data eye[BOARDMAX], struct half_eye_data heye[BOARDMAX],
627 int pos)
628{
629 int m, n;
630 int pos2;
631 int mini, maxi;
632 int minj, maxj;
633 int origin = eye[pos].origin;
634
635 gprintf("Eyespace at %1m: color=%C, esize=%d, msize=%d\n",
636 pos, eye[pos].color, eye[pos].esize, eye[pos].msize);
637
638 for (pos2 = BOARDMIN; pos2 < BOARDMAX; pos2++) {
639 if (!ON_BOARD(pos2))
640 continue;
641
642 if (eye[pos2].origin != pos)
643 continue;
644
645 if (eye[pos2].marginal && IS_STONE(board[pos2]))
646 gprintf("%1m (X!)\n", pos2);
647 else if (is_halfeye(heye, pos2) && IS_STONE(board[pos2])) {
648 if (heye[pos2].value == 3.0)
649 gprintf("%1m (XH)\n", pos2);
650 else
651 gprintf("%1m (XH) (topological eye value = %f)\n", pos2,
652 heye[pos2].value);
653 }
654 else if (!eye[pos2].marginal && IS_STONE(board[pos2]))
655 gprintf("%1m (X)\n", pos2);
656 else if (eye[pos2].marginal && board[pos2] == EMPTY)
657 gprintf("%1m (!)\n", pos2);
658 else if (is_halfeye(heye, pos2) && board[pos2] == EMPTY) {
659 if (heye[pos2].value == 3.0)
660 gprintf("%1m (H)\n", pos2);
661 else
662 gprintf("%1m (H) (topological eye value = %f)\n", pos2,
663 heye[pos2].value);
664 }
665 else
666 gprintf("%1m\n", pos2);
667 }
668 gprintf("\n");
669
670 /* Determine the size of the eye. */
671 mini = board_size;
672 maxi = -1;
673 minj = board_size;
674 maxj = -1;
675 for (m = 0; m < board_size; m++)
676 for (n = 0; n < board_size; n++) {
677 if (eye[POS(m, n)].origin != origin)
678 continue;
679
680 if (m < mini) mini = m;
681 if (m > maxi) maxi = m;
682 if (n < minj) minj = n;
683 if (n > maxj) maxj = n;
684 }
685
686 /* Prints the eye shape. A half eye is shown by h, if empty or H, if an
687 * enemy is present. Note that each half eye has a marginal point which is
688 * not printed, so the representation here may have less points than the
689 * matching eye pattern in eyes.db. Printing a marginal for the half eye
690 * would be nice, but difficult to implement.
691 */
692 for (m = mini; m <= maxi; m++) {
693 gprintf(""); /* Get the indentation right. */
694 for (n = minj; n <= maxj; n++) {
695 int pos2 = POS(m, n);
696 if (eye[pos2].origin == origin) {
697 if (board[pos2] == EMPTY) {
698 if (eye[pos2].marginal)
699 gprintf("%o!");
700 else if (is_halfeye(heye, pos2))
701 gprintf("%oh");
702 else
703 gprintf("%o.");
704 }
705 else if (is_halfeye(heye, pos2))
706 gprintf("%oH");
707 else
708 gprintf("%oX");
709 }
710 else
711 gprintf("%o ");
712 }
713 gprintf("\n");
714 }
715}
716
717
718/*
719 * Given an eyespace with origin (pos), this function computes the
720 * minimum and maximum numbers of eyes the space can yield. If max and
721 * min are different, then vital points of attack and defense are also
722 * generated.
723 *
724 * If add_moves == 1, this function may add a move_reason for (color) at
725 * a vital point which is found by the function. If add_moves == 0,
726 * set color == EMPTY.
727 */
728
729void
730compute_eyes(int pos, struct eyevalue *value,
731 int *attack_point, int *defense_point,
732 struct eye_data eye[BOARDMAX],
733 struct half_eye_data heye[BOARDMAX], int add_moves)
734{
735 if (attack_point)
736 *attack_point = NO_MOVE;
737 if (defense_point)
738 *defense_point = NO_MOVE;
739
740 if (debug & DEBUG_EYES) {
741 print_eye(eye, heye, pos);
742 DEBUG(DEBUG_EYES, "\n");
743 }
744
745 /* Look up the eye space in the graphs database. */
746 if (read_eye(pos, attack_point, defense_point, value, eye, heye, add_moves))
747 return;
748
749 /* Ideally any eye space that hasn't been matched yet should be two
750 * secure eyes. Until the database becomes more complete we have
751 * some additional heuristics to guess the values of unknown
752 * eyespaces.
753 */
754 if (eye[pos].esize - 2*eye[pos].msize > 3)
755 set_eyevalue(value, 2, 2, 2, 2);
756 else if (eye[pos].esize - 2*eye[pos].msize > 0)
757 set_eyevalue(value, 1, 1, 1, 1);
758 else
759 set_eyevalue(value, 0, 0, 0, 0);
760}
761
762
763/*
764 * This function works like compute_eyes(), except that it also gives
765 * a pessimistic view of the chances to make eyes. Since it is intended
766 * to be used from the owl code, the option to add move reasons has
767 * been removed.
768 */
769void
770compute_eyes_pessimistic(int pos, struct eyevalue *value,
771 int *pessimistic_min,
772 int *attack_point, int *defense_point,
773 struct eye_data eye[BOARDMAX],
774 struct half_eye_data heye[BOARDMAX])
775{
776 static int bulk_coefficients[5] = {-1, -1, 1, 4, 12};
777
778 int pos2;
779 int margins = 0;
780 int halfeyes = 0;
781 int margins_adjacent_to_margin = 0;
782 int effective_eyesize;
783 int bulk_score = 0;
784 signed char chainlinks[BOARDMAX];
785
786 /* Stones inside eyespace which do not coincide with a false eye or
787 * a halfeye.
788 */
789 int interior_stones = 0;
790
791 memset(chainlinks, 0, BOARDMAX);
792
793 for (pos2 = BOARDMIN; pos2 < BOARDMAX; pos2++) {
794 int k;
795
796 if (!ON_BOARD(pos2) || eye[pos2].origin != pos)
797 continue;
798
799 if (eye[pos2].marginal || is_halfeye(heye, pos2)) {
800 margins++;
801 if (eye[pos2].marginal && eye[pos2].marginal_neighbors > 0)
802 margins_adjacent_to_margin++;
803 if (is_halfeye(heye, pos2))
804 halfeyes++;
805 }
806 else if (IS_STONE(board[pos2]))
807 interior_stones++;
808
809 bulk_score += bulk_coefficients[(int) eye[pos2].neighbors];
810
811 for (k = 0; k < 4; k++) {
812 int neighbor = pos2 + delta[k];
813
814 if (board[neighbor] == eye[pos].color) {
815 if (!chainlinks[neighbor]) {
816 bulk_score += 4;
817 mark_string(neighbor, chainlinks, 1);
818 }
819 }
820 else if (!ON_BOARD(neighbor))
821 bulk_score += 2;
822 }
823 }
824
825 /* This is a measure based on the simplified assumption that both
826 * players only cares about playing the marginal eye spaces. It is
827 * used later to guess the eye value for unidentified eye shapes.
828 */
829 effective_eyesize = (eye[pos].esize + halfeyes - 2*margins
830 - margins_adjacent_to_margin);
831
832 if (attack_point)
833 *attack_point = NO_MOVE;
834 if (defense_point)
835 *defense_point = NO_MOVE;
836
837 if (debug & DEBUG_EYES) {
838 print_eye(eye, heye, pos);
839 DEBUG(DEBUG_EYES, "\n");
840 }
841
842 /* Look up the eye space in the graphs database. */
843 if (read_eye(pos, attack_point, defense_point, value,
844 eye, heye, 0)) {
845 *pessimistic_min = min_eyes(value) - margins;
846
847 /* A single point eye which is part of a ko can't be trusted. */
848 if (eye[pos].esize == 1
849 && is_ko(pos, OTHER_COLOR(eye[pos].color), NULL))
850 *pessimistic_min = 0;
851
852 DEBUG(DEBUG_EYES, " graph matching - %s, pessimistic_min=%d\n",
853 eyevalue_to_string(value), *pessimistic_min);
854 }
855
856 /* Ideally any eye space that hasn't been matched yet should be two
857 * secure eyes. Until the database becomes more complete we have
858 * some additional heuristics to guess the values of unknown
859 * eyespaces.
860 */
861 else {
862 guess_eye_space(pos, effective_eyesize, margins, bulk_score, eye,
863 value, pessimistic_min);
864 DEBUG(DEBUG_EYES, " guess_eye - %s, pessimistic_min=%d\n",
865 eyevalue_to_string(value), *pessimistic_min);
866 }
867
868 if (*pessimistic_min < 0) {
869 *pessimistic_min = 0;
870 DEBUG(DEBUG_EYES, " pessimistic min revised to 0\n");
871 }
872
873 /* An eyespace with at least two interior stones is assumed to be
874 * worth at least one eye, regardless of previous considerations.
875 */
876 if (*pessimistic_min < 1 && interior_stones >= 2) {
877 *pessimistic_min = 1;
878 DEBUG(DEBUG_EYES, " pessimistic min revised to 1 (interior stones)\n");
879 }
880
881 if (attack_point
882 && *attack_point == NO_MOVE
883 && max_eyes(value) != *pessimistic_min) {
884 /* Find one marginal vertex and set as attack and defense point.
885 *
886 * We make some effort to find the best marginal vertex by giving
887 * priority to ones with more than one neighbor in the eyespace.
888 * We prefer non-halfeye margins and ones which are not self-atari
889 * for the opponent. Margins not on the edge are also favored.
890 */
891 int best_attack_point = NO_MOVE;
892 int best_defense_point = NO_MOVE;
893 float score = 0.0;
894
895 for (pos2 = BOARDMIN; pos2 < BOARDMAX; pos2++) {
896 if (ON_BOARD(pos2) && eye[pos2].origin == pos) {
897 float this_score = 0.0;
898 int this_attack_point = NO_MOVE;
899 int this_defense_point = NO_MOVE;
900 if (eye[pos2].marginal && board[pos2] == EMPTY) {
901 this_score = eye[pos2].neighbors;
902 this_attack_point = pos2;
903 this_defense_point = pos2;
904
905 if (is_self_atari(pos2, OTHER_COLOR(eye[pos].color)))
906 this_score -= 0.5;
907
908 if (is_edge_vertex(pos2))
909 this_score -= 0.1;
910 }
911 else if (is_halfeye(heye, pos2)) {
912 this_score = 0.75;
913 this_defense_point = heye[pos2].defense_point[0];
914 this_attack_point = heye[pos2].attack_point[0];
915 }
916 else
917 continue;
918
919 if (gg_normalize_float2int(this_score, 0.01)
920 > gg_normalize_float2int(score, 0.01)) {
921 best_attack_point = this_attack_point;
922 best_defense_point = this_defense_point;
923 score = this_score;
924 }
925 }
926 }
927
928 if (score > 0.0) {
929 if (defense_point)
930 *defense_point = best_defense_point;
931 if (attack_point)
932 *attack_point = best_attack_point;
933 }
934 }
935
936 if (defense_point && *defense_point != NO_MOVE) {
937 ASSERT_ON_BOARD1(*defense_point);
938 }
939 if (attack_point && *attack_point != NO_MOVE) {
940 ASSERT_ON_BOARD1(*attack_point);
941 }
942}
943
944
945static void
946guess_eye_space(int pos, int effective_eyesize, int margins,
947 int bulk_score, struct eye_data eye[BOARDMAX],
948 struct eyevalue *value, int *pessimistic_min)
949{
950 if (effective_eyesize > 3) {
951 set_eyevalue(value, 2, 2, 2, 2);
952 *pessimistic_min = 1;
953
954 if ((margins == 0 && effective_eyesize > 7)
955 || (margins > 0 && effective_eyesize > 9)) {
956 int eyes = 2 + (effective_eyesize - 2 * (margins > 0) - 8) / 2;
957 int threshold = (4 * (eye[pos].esize - 2)
958 + (effective_eyesize - 8) * (effective_eyesize - 9));
959
960 DEBUG(DEBUG_EYES, "size: %d(%d), threshold: %d, bulk score: %d\n",
961 eye[pos].esize, effective_eyesize, threshold, bulk_score);
962
963 if (bulk_score > threshold && effective_eyesize < 15)
964 eyes = gg_max(2, eyes - ((bulk_score - threshold) / eye[pos].esize));
965
966 if (bulk_score < threshold + eye[pos].esize || effective_eyesize >= 15)
967 *pessimistic_min = eyes;
968
969 set_eyevalue(value, eyes, eyes, eyes, eyes);
970 }
971 }
972 else if (effective_eyesize > 0) {
973 set_eyevalue(value, 1, 1, 1, 1);
974 if (margins > 0)
975 *pessimistic_min = 0;
976 else
977 *pessimistic_min = 1;
978 }
979 else {
980 if (eye[pos].esize - margins > 2)
981 set_eyevalue(value, 0, 0, 1, 1);
982 else
983 set_eyevalue(value, 0, 0, 0, 0);
984 *pessimistic_min = 0;
985 }
986}
987
988
989/* This function does some minor reading to improve the results of
990 * recognize_eye(). Currently, it has two duties. One is to read
991 * positions like this:
992 *
993 * .XXXX| with half eye with proper eye
994 * XXOOO|
995 * XO.O.| . (1 eye) . (2 eyes)
996 * XXOa.| !.. .*
997 * -----+
998 *
999 * recognize_eye() sees the eyespace of the white dragon as shown
1000 * (there's a half eye at a and it is considered the same as '!.' by
1001 * the optics code). Normally, that eye shape gives only one secure
1002 * eye, and owl thinks that the white dragon is dead unconditionally.
1003 * This function tries to turn such ko-dependent half eyes into proper
1004 * eyes and chooses the best alternative. Note that we don't have any
1005 * attack/defense codes here, since owl will determine them itself.
1006 *
1007 * Another one is related to some cases when replacing half eyes with
1008 * '!.' doesn't work. E.g. consider this eye (optics:328):
1009 *
1010 * XXXOO eye graph is 310:
1011 * X..X.
1012 * XOXX. !.! (second '!' is due to the halfeye)
1013 * OXO..
1014 * O.O..
1015 *
1016 * When this function detects such a half eye that can be attacked
1017 * and/or defended inside its eyespace, it tries to turn it into a
1018 * proper eye and see what happens. In case it gives an improvement
1019 * for attacker and/or defender, the function keeps new result but
1020 * only if new vital points are also vital points for the half eye.
1021 * The heuristics used here might need improvements since they are
1022 * based on a single game position.
1023 *
1024 * If add_moves != 0, this function may add move reasons for (color)
1025 * at the vital points which are found by recognize_eye(). If add_moves
1026 * == 0, set color to be EMPTY.
1027 */
1028static int
1029read_eye(int pos, int *attack_point, int *defense_point,
1030 struct eyevalue *value, struct eye_data eye[BOARDMAX],
1031 struct half_eye_data heye[BOARDMAX],
1032 int add_moves)
1033{
1034 int eye_color;
1035 int k;
1036 int pos2;
1037 int combination_halfeye = NO_MOVE;
1038 int combination_attack = NO_MOVE;
1039 int combination_defense = NO_MOVE;
1040 int num_ko_halfeyes = 0;
1041 int ko_halfeye = NO_MOVE;
1042 struct vital_points vp;
1043 struct vital_points ko_vp;
1044 struct vital_points *best_vp = &vp;
1045
1046 eye_color = recognize_eye(pos, attack_point, defense_point, value,
1047 eye, heye, &vp);
1048 if (!eye_color)
1049 return 0;
1050
1051 /* Find ko half eyes and "combination" half eyes if any. */
1052 for (pos2 = BOARDMIN; pos2 < BOARDMAX; pos2++) {
1053 if (ON_BOARD(pos2)
1054 && eye[pos2].origin == pos
1055 && heye[pos2].type == HALF_EYE) {
1056 if (combination_halfeye == NO_MOVE) {
1057 int apos = NO_MOVE;
1058 int dpos = NO_MOVE;
1059
1060 for (k = 0; k < heye[pos2].num_attacks; k++) {
1061 if (eye[heye[pos2].attack_point[k]].origin == pos) {
1062 apos = heye[pos2].attack_point[k];
1063 break;
1064 }
1065 }
1066
1067 for (k = 0; k < heye[pos2].num_defenses; k++) {
1068 if (eye[heye[pos2].defense_point[k]].origin == pos) {
1069 dpos = heye[pos2].defense_point[k];
1070 break;
1071 }
1072 }
1073
1074 if (apos || dpos) {
1075 combination_halfeye = pos2;
1076 combination_attack = apos;
1077 combination_defense = dpos;
1078 }
1079 }
1080
1081 if (heye[pos2].value < 3.0) {
1082 num_ko_halfeyes++;
1083 ko_halfeye = pos2;
1084 }
1085 }
1086 }
1087
1088 /* In case we have a "combination" half eye, turn it into a proper eye
1089 * vertex for a while and see what happens.
1090 */
1091 if (combination_halfeye != NO_MOVE) {
1092 int result;
1093 int apos = NO_MOVE;
1094 int dpos = NO_MOVE;
1095 struct eyevalue combination_value;
1096 struct vital_points combination_vp;
1097
1098 heye[combination_halfeye].type = 0;
1099 result = recognize_eye(pos, &apos, &dpos, &combination_value, eye,
1100 heye, &combination_vp);
1101 heye[combination_halfeye].type = HALF_EYE;
1102
1103 if (result) {
1104 if (combination_attack
1105 && min_eyes(value) > min_eyes(&combination_value)) {
1106 /* FIXME: I'm not sure we can ever get here. */
1107 for (k = 0; k < combination_vp.num_attacks; k++) {
1108 if (combination_vp.attacks[k] == combination_attack) {
1109 value->a = combination_value.a;
1110 value->b = combination_value.b;
1111 *attack_point = apos;
1112 best_vp->num_attacks = 1;
1113 best_vp->attacks[0] = combination_attack;
1114 break;
1115 }
1116 }
1117 }
1118
1119 if (combination_defense
1120 && max_eyes(value) < max_eyes(&combination_value)) {
1121 /* Turning the half eye into a proper eye gives an improvement.
1122 * However, we can only accept this result if there is a vital
1123 * point that defends both the half eye and the whole eyespace.
1124 */
1125 for (k = 0; k < combination_vp.num_defenses; k++) {
1126 if (combination_vp.defenses[k] == combination_defense) {
1127 value->c = combination_value.c;
1128 value->d = combination_value.d;
1129 *defense_point = dpos;
1130 best_vp->num_defenses = 1;
1131 best_vp->defenses[0] = combination_defense;
1132 break;
1133 }
1134 }
1135 }
1136
1137 if (min_eyes(value) != max_eyes(value)) {
1138 ASSERT1(combination_attack || combination_defense, combination_halfeye);
1139 if (*attack_point == NO_MOVE) {
1140 *attack_point = combination_attack;
1141 if (*attack_point == NO_MOVE)
1142 *attack_point = combination_defense;
1143 }
1144
1145 if (*defense_point == NO_MOVE) {
1146 *defense_point = combination_defense;
1147 if (*defense_point == NO_MOVE)
1148 *defense_point = combination_defense;
1149 }
1150 }
1151 }
1152 }
1153
1154 /* The same with ko half eye (we cannot win two kos at once, therefore we
1155 * give up if there is more than one ko half eye).
1156 */
1157 if (num_ko_halfeyes == 1) {
1158 int result;
1159 int apos = NO_MOVE;
1160 int dpos = NO_MOVE;
1161 struct eyevalue ko_value;
1162
1163 heye[ko_halfeye].type = 0;
1164 result = recognize_eye(pos, &apos, &dpos, &ko_value, eye,
1165 heye, &ko_vp);
1166 heye[ko_halfeye].type = HALF_EYE;
1167
1168 if (result && max_eyes(value) < max_eyes(&ko_value)) {
1169 /* It is worthy to win the ko. */
1170 *value = ko_value;
1171 *attack_point = apos;
1172 *defense_point = dpos;
1173 best_vp = &ko_vp;
1174 }
1175 }
1176
1177 if (add_moves) {
1178 struct vital_eye_points *vital;
1179 if (eye_color == WHITE)
1180 vital = white_vital_points;
1181 else
1182 vital = black_vital_points;
1183 for (k = 0; k < best_vp->num_defenses && k < MAX_EYE_ATTACKS; k++)
1184 vital[pos].defense_points[k] = best_vp->defenses[k];
1185 for (k = 0; k < best_vp->num_attacks && k < MAX_EYE_ATTACKS; k++)
1186 vital[pos].attack_points[k] = best_vp->attacks[k];
1187 }
1188
1189 return 1;
1190}
1191
1192
1193/* recognize_eye(pos, *attack_point, *defense_point, *max, *min, eye_data,
1194 * half_eye_data, color, vp), where pos is the origin of an eyespace, returns
1195 * owner of eye (his color) if there is a pattern in eyes.db matching the
1196 * eyespace, or 0 if no match is found. If there is a key point for attack,
1197 * (*attack_point) is set to its location, or NO_MOVE if there is none.
1198 * Similarly (*defense_point) is the location of a vital defense point.
1199 * *value is set according to the pattern found. Vital attack/defense points
1200 * exist if and only if min_eyes(value) != max_eyes(value).
1201 */
1202
1203static int
1204recognize_eye(int pos, int *attack_point, int *defense_point,
1205 struct eyevalue *value,
1206 struct eye_data eye[BOARDMAX],
1207 struct half_eye_data heye[BOARDMAX],
1208 struct vital_points *vp)
1209{
1210 int pos2;
1211 int eye_color;
1212 int eye_size = 0;
1213 int num_marginals = 0;
1214 int vpos[MAXEYE];
1215 signed char marginal[MAXEYE], edge[MAXEYE], neighbors[MAXEYE];
1216 int graph;
1217 int map[MAXEYE];
1218 int best_score;
1219 int r;
1220
1221 gg_assert(attack_point != NULL);
1222 gg_assert(defense_point != NULL);
1223
1224 /* Set `eye_color' to the owner of the eye. */
1225 eye_color = eye[pos].color;
1226
1227 if (eye[pos].esize-eye[pos].msize > 8)
1228 return 0;
1229
1230 if (eye[pos].msize > MAXEYE)
1231 return 0;
1232
1233 /* Create list of eye vertices */
1234 for (pos2 = BOARDMIN; pos2 < BOARDMAX; pos2++) {
1235 if (!ON_BOARD(pos2))
1236 continue;
1237 if (eye[pos2].origin == pos) {
1238 vpos[eye_size] = pos2;
1239 marginal[eye_size] = eye[pos2].marginal;
1240 if (marginal[eye_size])
1241 num_marginals++;
1242 neighbors[eye_size] = eye[pos2].neighbors;
1243 if (0) {
1244 if (marginal[eye_size])
1245 TRACE("(%1m)", vpos[eye_size]);
1246 else
1247 TRACE(" %1m ", vpos[eye_size]);
1248 TRACE("\n");
1249 }
1250
1251 if (is_corner_vertex(pos2))
1252 edge[eye_size] = 2;
1253 else if (is_edge_vertex(pos2))
1254 edge[eye_size] = 1;
1255 else
1256 edge[eye_size] = 0;
1257
1258 if (is_halfeye(heye, pos2)) {
1259 neighbors[eye_size]++; /* Increase neighbors of half eye. */
1260 eye_size++;
1261 /* Use a virtual marginal vertex for mapping purposes. We set it
1262 * to be at NO_MOVE so it won't accidentally count as a
1263 * neighbor for another vertex. Note that the half eye precedes
1264 * the virtual marginal vertex in the list.
1265 */
1266 vpos[eye_size] = NO_MOVE;
1267 marginal[eye_size] = 1;
1268 num_marginals++;
1269 edge[eye_size] = 0;
1270 neighbors[eye_size] = 1;
1271 }
1272
1273 eye_size++;
1274 }
1275 }
1276
1277 /* We attempt to construct a map from the graph to the eyespace
1278 * preserving the adjacency structure. If this can be done, we've
1279 * identified the eyeshape.
1280 */
1281
1282 for (graph = 0; graphs[graph].vertex != NULL; graph++) {
1283 int q;
1284
1285 if (graphs[graph].esize != eye_size
1286 || graphs[graph].msize != num_marginals)
1287 continue;
1288
1289 reset_map(eye_size);
1290 q = 0;
1291 first_map(&map[0]);
1292
1293 while (1) {
1294 struct eye_vertex *gv = &graphs[graph].vertex[q];
1295 int mv = map[q];
1296 int ok = 1;
1297
1298 if (0)
1299 TRACE("q=%d: %d %d %d %d %d %d\n",
1300 q, map[0], map[1], map[2], map[3], map[4], map[5]);
1301
1302 if (neighbors[mv] != gv->neighbors
1303 || marginal[mv] != gv->marginal
1304 || edge[mv] < gv->edge)
1305 ok = 0;
1306
1307 if (ok) {
1308 if (IS_STONE(board[vpos[mv]])) {
1309 if (!(gv->flags & CAN_CONTAIN_STONE))
1310 ok = 0;
1311 }
1312 /* Virtual half eye marginals also fall here since they are off
1313 * board.
1314 */
1315 else if (!(gv->flags & CAN_BE_EMPTY))
1316 ok = 0;
1317 }
1318
1319 if (ok) {
1320 int k;
1321
1322 for (k = 0; k < gv->neighbors; k++) {
1323 if (gv->n[k] < q) {
1324 int mn = map[gv->n[k]];
1325
1326 /* Two eye vertices are neighbours if they are adjacent on the
1327 * board or one of them is a half eye and the other is its
1328 * virtual marginal vertex (and follows it in vpos[] array).
1329 */
1330 if (vpos[mv] != SOUTH(vpos[mn])
1331 && vpos[mv] != WEST(vpos[mn])
1332 && vpos[mv] != NORTH(vpos[mn])
1333 && vpos[mv] != EAST(vpos[mn])
1334 && (mv != mn - 1
1335 || vpos[mv] == NO_MOVE
1336 || heye[vpos[mv]].type != HALF_EYE)
1337 && (mn != mv - 1
1338 || vpos[mn] == NO_MOVE
1339 || heye[vpos[mn]].type != HALF_EYE)) {
1340 ok = 0;
1341 break;
1342 }
1343 }
1344 }
1345 }
1346
1347 if (!ok) {
1348 if (!next_map(&q, map))
1349 break;
1350
1351 if (0)
1352 gprintf(" q=%d, esize=%d: %d %d %d %d %d\n",
1353 q, eye_size,
1354 map[0], map[1], map[2], map[3], map[4]);
1355 }
1356 else {
1357 q++;
1358 if (q == eye_size)
1359 break; /* A match! */
1360
1361 first_map(&map[q]);
1362 }
1363 }
1364
1365 if (q == eye_size) {
1366 /* We have found a match! Now sort out the vital moves. */
1367 *value = graphs[graph].value;
1368 vp->num_attacks = 0;
1369 vp->num_defenses = 0;
1370
1371 if (eye_move_urgency(value) > 0) {
1372 /* Collect all attack and defense points in the pattern. */
1373 int k;
1374
1375 for (k = 0; k < eye_size; k++) {
1376 struct eye_vertex *ev = &graphs[graph].vertex[k];
1377
1378 if (ev->flags & EYE_ATTACK_POINT) {
1379 /* Check for a marginal vertex matching a half eye virtual
1380 * marginal. This is the case if a half eye preceeds the
1381 * current vertex in the list.
1382 */
1383 if (ev->marginal
1384 && map[k] > 0
1385 && vpos[map[k] - 1] != NO_MOVE
1386 && is_halfeye(heye, vpos[map[k] - 1])) {
1387 /* Add all diagonals as vital. */
1388 int ix;
1389 struct half_eye_data *he = &heye[vpos[map[k] - 1]];
1390
1391 for (ix = 0; ix < he->num_attacks; ix++)
1392 vp->attacks[vp->num_attacks++] = he->attack_point[ix];
1393 }
1394 else
1395 vp->attacks[vp->num_attacks++] = vpos[map[k]];
1396 }
1397
1398 if (ev->flags & EYE_DEFENSE_POINT) {
1399 /* Check for a half eye virtual marginal vertex. */
1400 if (ev->marginal
1401 && map[k] > 0
1402 && vpos[map[k] - 1] != NO_MOVE
1403 && is_halfeye(heye, vpos[map[k] - 1])) {
1404 /* Add all diagonals as vital. */
1405 int ix;
1406 struct half_eye_data *he = &heye[vpos[map[k] - 1]];
1407
1408 for (ix = 0; ix < he->num_defenses; ix++)
1409 vp->defenses[vp->num_defenses++] = he->defense_point[ix];
1410 }
1411 else
1412 vp->defenses[vp->num_defenses++] = vpos[map[k]];
1413 }
1414 }
1415
1416 gg_assert(vp->num_attacks > 0 && vp->num_defenses > 0);
1417
1418 /* We now have all vital attack and defense points listed but
1419 * we are also expected to single out of one of each to return
1420 * in *attack_point and *defense_point. Since sometimes those
1421 * are the only vital points considered, we want to choose the
1422 * best ones, in the sense that they minimize the risk for
1423 * error in the eye space analysis.
1424 *
1425 * One example is this position
1426 *
1427 * |..XXXX
1428 * |XXX..X
1429 * |..!O.X
1430 * |OO.O.X
1431 * |.O.!XX
1432 * +------
1433 *
1434 * where O has an eyespace of the !..! type. The graph
1435 * matching finds that both marginal vertices are vital points
1436 * but here the one at 3-3 fails to defend. (For attack both
1437 * points work but the 3-3 one is still worse since it leaves
1438 * a ko threat.)
1439 *
1440 * In order to differentiate between the marginal points we
1441 * count the number of straight and diagonal neighbors within
1442 * the eye space. In the example above both have one straight
1443 * neighbor each but the edge margin wins because it also has
1444 * a diagonal margin.
1445 */
1446
1447 best_score = -10;
1448 for (k = 0; k < vp->num_attacks; k++) {
1449 int apos = vp->attacks[k];
1450 int score = 0;
1451 for (r = 0; r < 8; r++)
1452 if (ON_BOARD(apos + delta[r])
1453 && eye[apos + delta[r]].color == eye[pos].color
1454 && !eye[apos + delta[r]].marginal) {
1455 score++;
1456 if (r < 4) {
1457 score++;
1458 if (board[apos + delta[r]] != EMPTY)
1459 score++;
1460 }
1461 }
1462
1463 /* If a vital point is not adjacent to any point in the eye
1464 * space, it must be a move to capture or defend a string
1465 * related to a halfeye, e.g. the move * in this position,
1466 *
1467 * ......|
1468 * .XXXX.|
1469 * .X.O..|
1470 * .XO.OO|
1471 * .*XO..|
1472 * ------+
1473 *
1474 * Playing this is probably a good idea.
1475 */
1476 if (score == 0)
1477 score += 2;
1478
1479 if (0)
1480 gprintf("attack point %1m score %d\n", apos, score);
1481
1482 if (score > best_score) {
1483 *attack_point = apos;
1484 best_score = score;
1485 }
1486 }
1487
1488 best_score = -10;
1489 for (k = 0; k < vp->num_defenses; k++) {
1490 int dpos = vp->defenses[k];
1491 int score = 0;
1492 for (r = 0; r < 8; r++)
1493 if (ON_BOARD(dpos + delta[r])
1494 && eye[dpos + delta[r]].color == eye[pos].color
1495 && !eye[dpos + delta[r]].marginal) {
1496 score++;
1497 if (r < 4) {
1498 score++;
1499 if (board[dpos + delta[r]] != EMPTY)
1500 score++;
1501 }
1502 }
1503
1504 /* If possible, choose a non-sacrificial defense point.
1505 * Compare white T8 and T6 in lazarus:21.
1506 */
1507 if (safe_move(dpos, eye_color) != WIN)
1508 score -= 5;
1509
1510 /* See comment to the same code for attack points. */
1511 if (score == 0)
1512 score += 2;
1513
1514 if (0)
1515 gprintf("defense point %1m score %d\n", dpos, score);
1516
1517 if (score > best_score) {
1518 *defense_point = dpos;
1519 best_score = score;
1520 }
1521 }
1522
1523 DEBUG(DEBUG_EYES, " vital points: %1m (attack) %1m (defense)\n",
1524 *attack_point, *defense_point);
1525 DEBUG(DEBUG_EYES, " pattern matched: %d\n", graphs[graph].patnum);
1526
1527 }
1528 TRACE("eye space at %1m of type %d\n", pos, graphs[graph].patnum);
1529
1530 return eye_color;
1531 }
1532 }
1533
1534 return 0;
1535}
1536
1537
1538/* a MAP is a map of the integers 0,1,2, ... ,q into
1539 * 0,1, ... , esize-1 where q < esize. This determines a
1540 * bijection of the first q+1 elements of the graph into the
1541 * eyespace. The following three functions work with maps.
1542 */
1543
1544/* Reset internal data structure used by first_map() and
1545 * next_map() functions.
1546 */
1547static void
1548reset_map(int size)
1549{
1550 map_size = size;
1551 memset(used_index, 0, size * sizeof(used_index[0]));
1552}
1553
1554
1555/* The function first_map finds the smallest valid
1556 * value of a map element.
1557 */
1558static void
1559first_map(int *map_value)
1560{
1561 int k = 0;
1562
1563 while (used_index[k])
1564 k++;
1565
1566 used_index[k] = 1;
1567 *map_value = k;
1568}
1569
1570
1571/* The function next_map produces the next map in lexicographical
1572 * order. If no next map can be found, q is decremented, then we
1573 * try again. If the entire map is lexicographically last, the
1574 * function returns false.
1575 */
1576static int
1577next_map(int *q, int map[MAXEYE])
1578{
1579 int k;
1580
1581 do {
1582 used_index[map[*q]] = 0;
1583 for (k = map[*q]; ++k < map_size;) {
1584 if (!used_index[k]) {
1585 used_index[k] = 1;
1586 map[*q] = k;
1587 return 1;
1588 }
1589 }
1590
1591 (*q)--;
1592 } while (*q >= 0);
1593
1594 return 0;
1595}
1596
1597
1598/* add_false_eye() turns a proper eyespace into a margin. */
1599
1600static void
1601add_false_eye(int pos, struct eye_data eye[BOARDMAX],
1602 struct half_eye_data heye[BOARDMAX])
1603{
1604 int k;
1605 ASSERT1(heye[pos].type == FALSE_EYE, pos);
1606 DEBUG(DEBUG_EYES, "false eye found at %1m\n", pos);
1607
1608 if (eye[pos].color == GRAY || eye[pos].marginal != 0)
1609 return;
1610
1611 eye[pos].marginal = 1;
1612 eye[eye[pos].origin].msize++;
1613 for (k = 0; k < 4; k++)
1614 if (ON_BOARD(pos + delta[k])
1615 && eye[pos + delta[k]].origin == eye[pos].origin)
1616 eye[pos + delta[k]].marginal_neighbors++;
1617 propagate_eye(eye[pos].origin, eye);
1618}
1619
1620
1621/* These functions are used from constraints to identify eye spaces,
1622 * primarily for late endgame moves.
1623 */
1624int
1625is_eye_space(int pos)
1626{
1627 return (white_eye[pos].color == WHITE
1628 || black_eye[pos].color == BLACK);
1629}
1630
1631int
1632is_proper_eye_space(int pos)
1633{
1634 return ((white_eye[pos].color == WHITE && !white_eye[pos].marginal)
1635 || (black_eye[pos].color == BLACK && !black_eye[pos].marginal));
1636}
1637
1638/* Return the maximum number of eyes that can be obtained from the
1639 * eyespace at (i, j). This is most useful in order to determine
1640 * whether the eyespace can be assumed to produce any territory at
1641 * all.
1642 */
1643int
1644max_eye_value(int pos)
1645{
1646 int max_white = 0;
1647 int max_black = 0;
1648
1649 if (white_eye[pos].color == WHITE)
1650 max_white = max_eyes(&white_eye[pos].value);
1651
1652 if (black_eye[pos].color == BLACK)
1653 max_black = max_eyes(&black_eye[pos].value);
1654
1655 return gg_max(max_white, max_black);
1656}
1657
1658int
1659is_marginal_eye_space(int pos)
1660{
1661 return (white_eye[pos].marginal || black_eye[pos].marginal);
1662}
1663
1664int
1665is_halfeye(struct half_eye_data heye[BOARDMAX], int pos)
1666{
1667 return heye[pos].type == HALF_EYE;
1668}
1669
1670int
1671is_false_eye(struct half_eye_data heye[BOARDMAX], int pos)
1672{
1673 return heye[pos].type == FALSE_EYE;
1674}
1675
1676
1677/* Find topological half eyes and false eyes by analyzing the
1678 * diagonal intersections, as described in the Texinfo
1679 * documentation (Eyes/Eye Topology).
1680 */
1681void
1682find_half_and_false_eyes(int color, struct eye_data eye[BOARDMAX],
1683 struct half_eye_data heye[BOARDMAX],
1684 int find_mask[BOARDMAX])
1685{
1686 int eye_color = color;
1687 int pos;
1688 float sum;
1689
1690 for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
1691 /* skip eyespaces which owl doesn't want to be searched */
1692 if (!ON_BOARD(pos) || (find_mask && find_mask[eye[pos].origin] <= 1))
1693 continue;
1694
1695 /* skip every vertex which can't be a false or half eye */
1696 if (eye[pos].color != eye_color
1697 || eye[pos].marginal
1698 || eye[pos].neighbors > 1)
1699 continue;
1700
1701 sum = topological_eye(pos, color, eye, heye);
1702 if (sum >= 4.0) {
1703 /* false eye */
1704 heye[pos].type = FALSE_EYE;
1705 if (eye[pos].esize == 1
1706 || is_legal(pos, OTHER_COLOR(color))
1707 || board[pos] == OTHER_COLOR(color))
1708 add_false_eye(pos, eye, heye);
1709 }
1710 else if (sum > 2.0) {
1711 /* half eye */
1712 heye[pos].type = HALF_EYE;
1713 ASSERT1(heye[pos].num_attacks > 0, pos);
1714 ASSERT_ON_BOARD1(heye[pos].attack_point[0]);
1715 ASSERT1(heye[pos].num_defenses > 0, pos);
1716 ASSERT_ON_BOARD1(heye[pos].defense_point[0]);
1717 }
1718 }
1719}
1720
1721
1722/* See Texinfo documentation (Eyes:Eye Topology). Returns:
1723 * - 2 or less if (pos) is a proper eye for (color);
1724 * - between 2 and 3 if the eye can be made false only by ko
1725 * - 3 if (pos) is a half eye;
1726 * - between 3 and 4 if the eye can be made real only by ko
1727 * - 4 or more if (pos) is a false eye.
1728 *
1729 * Attack and defense points for control of the diagonals are stored
1730 * in the heye[] array.
1731 *
1732 * my_eye is the eye space information with respect to (color).
1733 */
1734
1735static float
1736topological_eye(int pos, int color,
1737 struct eye_data my_eye[BOARDMAX],
1738 struct half_eye_data heye[BOARDMAX])
1739{
1740 float sum = 0.0;
1741 float val;
1742 int num_attacks = 0;
1743 int num_defenses = 0;
1744 int attack_values[4];
1745 int defense_values[4];
1746 int k;
1747 int r;
1748 int attack_point;
1749 int defense_point;
1750 int attack_value;
1751 int defense_value;
1752
1753 memset(attack_values, 0, sizeof(attack_values));
1754 memset(defense_values, 0, sizeof(defense_values));
1755
1756 /* Loop over the diagonal directions. */
1757 for (k = 4; k < 8; k++) {
1758 int diag = pos + delta[k];
1759 val = evaluate_diagonal_intersection(I(pos) + deltai[k],
1760 J(pos) + deltaj[k], color,
1761 &attack_point, &defense_point,
1762 my_eye);
1763
1764 /*
1765 * Eyespaces with cutting points are problematic. In this position
1766 *
1767 * .....XXXXX
1768 * XXXXX.OO.X
1769 * X.OOOO.O.X
1770 * X.O.XXXO.X
1771 * ----------
1772 *
1773 * the eyespace will be .XXX. which evaluates to two eyes (seki)
1774 * unless countermeasures are taken.
1775 *
1776 * This can be worked around in the topological analysis by
1777 * sometimes setting the diagonal value to 2.0 for vertices inside
1778 * the eyespace which are occupied by opponent stones. More
1779 * precisely all of the following conditions must hold:
1780 *
1781 * a) The value is not already 2.0.
1782 * a) The (potential) eyepoint is empty.
1783 * b) The diagonal is occupied by an opponent string,
1784 * c) which is also adjacent to the (potential) eye and
1785 * d) at least three stones long.
1786 * e) The (potential) eye is not on the edge (to steer clear of all the
1787 * hairy cases that are handled by eyes.db anyway).
1788 * f) At least two own strings are adjacent to the (potential) eye.
1789 * g) At least one of the own strings adjacent to the (potential) eye has
1790 * only one liberty which is an eye space and not decided false, yet.
1791 *
1792 * With this revision the eyespace above becomes .XXXh or
1793 * equivalently .XXX.! which is almost evaluated correctly, eye
1794 * value 0122 instead of the correct 1122. Compared to the
1795 * previous value 2222 it's a major improvement.
1796 *
1797 * FIXME: This approach has a number of shortcomings.
1798 *
1799 * 1. d) is kind of arbitrary and there may be exceptional
1800 * cases.
1801 *
1802 * 2. This diagonal value modification should not apply to
1803 * two diagonals of the same strings inside the eyespace.
1804 * E.g. if we have a partial eyespace looking like
1805 *
1806 * .OOO.
1807 * OO.OO
1808 * OXXXO
1809 *
1810 * it doesn't make sense to mark the middle vertex as a
1811 * false eye. Possibly this doesn't make any difference
1812 * in practice but it's at the very least confusing.
1813 *
1814 * 3. Actually it doesn't make sense to mark vertices as
1815 * false otherwise either due to these revisions (half
1816 * eyes make good sense though) as can be seen if a
1817 * stone is added to the initial diagram,
1818 *
1819 * .....XXXXX
1820 * XXXXXXOO.X
1821 * X.OOOO.O.X
1822 * X.O.XXXO.X
1823 * ----------
1824 *
1825 * Now the eyespace instead becomes .XXX! which has the
1826 * eye value 0011 but if X tries to attack the eye O
1827 * suddenly gets two solid eyes!
1828 *
1829 * The correct analysis would be to remove the vertex
1830 * from the eyespace rather than turning it into a false
1831 * eye. Then we would have the eyespace .XXX which is
1832 * correctly evaluated to one eye (eye value 1112).
1833 *
1834 * The problem with this is that removing eye points is
1835 * messy. It can surely be done but currently there is
1836 * no support in the code for doing that. It has existed
1837 * at an earlier time but was removed because the
1838 * implementation was not robust enough and there was no
1839 * longer any apparent need for it. To correct this
1840 * problem is sufficient reason to reimplement that
1841 * functionality.
1842 *
1843 * 4. The test of condition g) has a result which
1844 * potentially depends on the ordering of the eyespaces
1845 * and thus presumably on the orientation of the board.
1846 * It might make more sense to examine whether the
1847 * string neighbors more than one empty vertex in the
1848 * same eyespace.
1849 */
1850 if (val < 2.0 && board[pos] == EMPTY && board[diag] == OTHER_COLOR(color)
1851 && !is_edge_vertex(pos) && neighbor_of_string(pos, diag)
1852 && countstones(diag) >= 3) {
1853 int strings[3];
1854 int string_count;
1855 int s;
1856 string_count = 0;
1857 for (r = 0; r < 4; r++) {
1858 int str;
1859 str = pos + delta[r];
1860
1861 if (board[str] != color)
1862 continue;
1863
1864 ASSERT1(string_count < 3, pos);
1865 for (s = 0; s < string_count; s++)
1866 if (same_string(str, strings[s]))
1867 break;
1868 if (s != string_count)
1869 continue;
1870
1871 strings[string_count++] = str;
1872 }
1873 if (string_count > 1) {
1874 for (s = 0; s < string_count; s++) {
1875 int libs[MAX_LIBERTIES];
1876 int adj_eye_count;
1877 int lib_count;
1878 adj_eye_count = 0;
1879 lib_count = findlib(strings[s], MAX_LIBERTIES, libs);
1880 if (lib_count > MAX_LIBERTIES)
1881 continue;
1882
1883 for (r = 0; r < lib_count && adj_eye_count < 2; r++)
1884 if (my_eye[libs[r]].color == OTHER_COLOR(color)
1885 && !my_eye[libs[r]].marginal)
1886 adj_eye_count++;
1887 if (adj_eye_count < 2) {
1888 val = 2.0;
1889 break;
1890 }
1891 }
1892 }
1893 }
1894
1895 sum += val;
1896
1897 if (val > 0.0 && val < 2.0) {
1898 /* Diagonals off the edge has value 1.0 but no attack or defense
1899 * point.
1900 */
1901 if (attack_point != NO_MOVE && defense_point != NO_MOVE) {
1902 ASSERT_ON_BOARD1(attack_point);
1903 ASSERT_ON_BOARD1(defense_point);
1904 /* Store these in sorted (descending) order. We remap val
1905 * differently for attack and defense points according to:
1906 *
1907 * val attack_value defense_value
1908 * --- ------------ -------------
1909 * 1.0 3 3
1910 * <1.0 2 1
1911 * >1.0 1 2
1912 *
1913 * This means that we primarily want to take control of
1914 * diagonals without ko and secondarily of diagonals we can
1915 * take unconditionally but not the opponent.
1916 */
1917 if (val == 1.0) {
1918 attack_value = 3;
1919 defense_value = 3;
1920 }
1921 else if (val < 1.0) {
1922 attack_value = 2;
1923 defense_value = 1;
1924 }
1925 else {
1926 attack_value = 1;
1927 defense_value = 2;
1928 }
1929
1930 for (r = 0; r < 4; r++) {
1931 if (attack_values[r] < attack_value) {
1932 int tmp_value = attack_values[r];
1933 int tmp_point;
1934 if (tmp_value)
1935 tmp_point = heye[pos].attack_point[r];
1936 else
1937 tmp_point = 0;
1938 attack_values[r] = attack_value;
1939 heye[pos].attack_point[r] = attack_point;
1940 attack_value = tmp_value;
1941 attack_point = tmp_point;
1942 }
1943
1944 if (defense_values[r] < defense_value) {
1945 int tmp_value = defense_values[r];
1946 int tmp_point;
1947 if (tmp_value)
1948 tmp_point = heye[pos].defense_point[r];
1949 else
1950 tmp_point = 0;
1951 defense_values[r] = defense_value;
1952 heye[pos].defense_point[r] = defense_point;
1953 defense_value = tmp_value;
1954 defense_point = tmp_point;
1955 }
1956 }
1957
1958 num_attacks++;
1959 num_defenses++;
1960 }
1961 }
1962 }
1963
1964 /* Remove attacks and defenses with smaller value than the best
1965 * ones. (These might be useful to save as well, but not unless we
1966 * also store the attack/defense values in the half_eye_data.)
1967 */
1968 for (r = 0; r < num_attacks; r++) {
1969 if (attack_values[r] < attack_values[0]) {
1970 num_attacks = r;
1971 break;
1972 }
1973 }
1974
1975 for (r = 0; r < num_defenses; r++) {
1976 if (defense_values[r] < defense_values[0]) {
1977 num_defenses = r;
1978 break;
1979 }
1980 }
1981
1982 heye[pos].num_attacks = num_attacks;
1983 heye[pos].num_defenses = num_defenses;
1984 heye[pos].value = sum;
1985
1986 return sum;
1987}
1988
1989
1990
1991/* Evaluate an intersection (m, n) which is diagonal to an eye space,
1992 * as described in the Texinfo documentation (Eyes/Eye Topology).
1993 *
1994 * Returns:
1995 *
1996 * 0 if both coordinates are off the board
1997 * 1 if one coordinate is off the board
1998 *
1999 * 0 if (color) has control over the vertex
2000 * a if (color) can take control over the vertex unconditionally and
2001 * the opponent can take control by winning a ko.
2002 * 1 if both (color) and the opponent can take control of the vertex
2003 * unconditionally
2004 * b if (color) can take control over the vertex by winning a ko and
2005 * the opponent can take control unconditionally.
2006 * 2 if the opponent has control over the vertex
2007 *
2008 * The values a and b are discussed in the documentation. We are
2009 * currently using a = 0.75 and b = 1.25.
2010 *
2011 * Notice that it's necessary to pass the coordinates separately
2012 * instead of as a 1D coordinate. The reason is that the 1D mapping
2013 * can't uniquely identify "off the corner" points.
2014 *
2015 * my_eye has to be the eye_data with respect to color.
2016 */
2017static float
2018evaluate_diagonal_intersection(int m, int n, int color,
2019 int *attack_point, int *defense_point,
2020 struct eye_data my_eye[BOARDMAX])
2021{
2022 float value = 0;
2023 int other = OTHER_COLOR(color);
2024 int pos = POS(m, n);
2025 int acode = 0;
2026 int apos = NO_MOVE;
2027 int dcode = 0;
2028 int dpos = NO_MOVE;
2029 int off_edge = 0;
2030 const float a = 0.75;
2031 const float b = 2 - a;
2032
2033 *attack_point = NO_MOVE;
2034 *defense_point = NO_MOVE;
2035
2036 /* Check whether intersection is off the board. We must do this for
2037 * each board coordinate separately because points "off the corner"
2038 * are special cases.
2039 */
2040 if (m < 0 || m >= board_size)
2041 off_edge++;
2042
2043 if (n < 0 || n >= board_size)
2044 off_edge++;
2045
2046 /* Must return 0 if both coordinates out of bounds. */
2047 if (off_edge > 0)
2048 return (float) (off_edge % 2);
2049
2050 /* Discard points within own eyespace, unless marginal or ko point.
2051 *
2052 * Comment: For some time discardment of points within own eyespace
2053 * was contingent on this being the same eyespace as that of the
2054 * examined vertex. This caused problems, e.g. in this position,
2055 *
2056 * |........
2057 * |XXXXX...
2058 * |OOOOX...
2059 * |aO.OX...
2060 * |OXXOX...
2061 * |.XXOX...
2062 * +--------
2063 *
2064 * where the empty vertex at a was evaluated as a false eye and the
2065 * whole group as dead (instead of living in seki).
2066 *
2067 * The reason for the requirement of less than two marginal
2068 * neighbors is this position:
2069 *
2070 * |.XXXX...
2071 * |.OOOX...
2072 * |O..OX...
2073 * |aOO.X...
2074 * |O..XX...
2075 * |..O.X...
2076 * |.X..X...
2077 * |..XXX...
2078 *
2079 * where the empty vertex at a should not count as a solid eye.
2080 * (The eyespace diagonally below a looks like this:
2081 * .!
2082 * !
2083 * so we can clearly see why having two marginal vertices makes a
2084 * difference.)
2085 */
2086 if (my_eye[pos].color == color
2087 && !my_eye[pos].marginal
2088 && my_eye[pos].marginal_neighbors < 2
2089 && !(board[pos] == EMPTY && does_capture_something(pos, other)))
2090 return 0.0;
2091
2092 if (board[pos] == EMPTY) {
2093 int your_safety = safe_move(pos, other);
2094
2095 apos = pos;
2096 dpos = pos;
2097
2098 /* We should normally have a safe move, but occasionally it may
2099 * happen that it's not safe. There are complications, however,
2100 * with a position like this:
2101 *
2102 * .XXXX|
2103 * XXOO.|
2104 * XO.O.|
2105 * XXO.O|
2106 * -----+
2107 *
2108 * Therefore we ignore our own safety if opponent's safety depends
2109 * on ko.
2110 */
2111 if (your_safety == 0)
2112 value = 0.0;
2113 else if (your_safety != WIN)
2114 value = a;
2115 else { /* So your_safety == WIN. */
2116 int our_safety = safe_move(pos, color);
2117
2118 if (our_safety == 0) {
2119 int k;
2120
2121 value = 2.0;
2122
2123 /* This check is intended to fix a certain special case, but might
2124 * be helpful in other situations as well. Consider this position,
2125 * happened in owl reading deep enough:
2126 *
2127 * |XXXXX
2128 * |XOOXX
2129 * |O.OOX
2130 * |.OXX.
2131 * +-----
2132 *
2133 * Without this check, the corner eye is considered false, not half-
2134 * eye. Thus, owl thinks that the capture gains at most one eye and
2135 * gives up.
2136 */
2137 for (k = 4; k < 8; k++) {
2138 int diagonal = pos + delta[k];
2139 int lib;
2140
2141 if (board[diagonal] == other && findlib(diagonal, 1, &lib) == 1) {
2142 if (lib != pos && does_secure(color, lib, pos)) {
2143 value = 1.0;
2144 apos = lib;
2145 break;
2146 }
2147 }
2148 }
2149 }
2150 else if (our_safety == WIN)
2151 value = 1.0;
2152 else /* our_safety depends on ko. */
2153 value = b;
2154 }
2155 }
2156 else if (board[pos] == color) {
2157 /* This stone had better be safe, otherwise we wouldn't have an
2158 * eyespace in the first place.
2159 */
2160 value = 0.0;
2161 }
2162 else if (board[pos] == other) {
2163 if (stackp == 0) {
2164 acode = worm[pos].attack_codes[0];
2165 apos = worm[pos].attack_points[0];
2166 dcode = worm[pos].defense_codes[0];
2167 dpos = worm[pos].defense_points[0];
2168 }
2169 else
2170 attack_and_defend(pos, &acode, &apos, &dcode, &dpos);
2171
2172 /* Must test acode first since dcode only is reliable if acode is
2173 * non-zero.
2174 */
2175 if (acode == 0)
2176 value = 2.0;
2177 else if (dcode == 0)
2178 value = 0.0;
2179 else if (acode == WIN && dcode == WIN)
2180 value = 1.0;
2181 else if (acode == WIN && dcode != WIN)
2182 value = a;
2183 else if (acode != WIN && dcode == WIN)
2184 value = b;
2185 else if (acode != WIN && dcode != WIN)
2186 value = 1.0; /* Both contingent on ko. Probably can't happen. */
2187 }
2188
2189 if (value > 0.0 && value < 2.0) {
2190 /* FIXME:
2191 * Usually there are several attack and defense moves that would
2192 * be equally valid. It's not good that we make an arbitrary
2193 * choice at this point.
2194 */
2195 ASSERT_ON_BOARD1(apos);
2196 ASSERT_ON_BOARD1(dpos);
2197 /* Notice:
2198 * The point to ATTACK the half eye is the point which DEFENDS
2199 * the stones on the diagonal intersection and vice versa. Thus
2200 * we must switch attack and defense points here.
2201 * If the vertex is empty, dpos == apos and it doesn't matter
2202 * whether we switch.
2203 */
2204 *attack_point = dpos;
2205 *defense_point = apos;
2206 }
2207
2208 return value;
2209}
2210
2211
2212/* Conservative relative of topological_eye(). Essentially the same
2213 * algorithm is used, but only tactically safe opponent strings on
2214 * diagonals are considered. This may underestimate the false/half eye
2215 * status, but it should never be overestimated.
2216 */
2217int
2218obvious_false_eye(int pos, int color)
2219{
2220 int i = I(pos);
2221 int j = J(pos);
2222 int k;
2223 int diagonal_sum = 0;
2224 for (k = 4; k < 8; k++) {
2225 int di = deltai[k];
2226 int dj = deltaj[k];
2227
2228 if (!ON_BOARD2(i+di, j) && !ON_BOARD2(i, j+dj))
2229 diagonal_sum--;
2230
2231 if (!ON_BOARD2(i+di, j+dj))
2232 diagonal_sum++;
2233 else if (BOARD(i+di, j+dj) == OTHER_COLOR(color)
2234 && !attack(POS(i+di, j+dj), NULL))
2235 diagonal_sum += 2;
2236 }
2237
2238 return diagonal_sum >= 4;
2239}
2240
2241
2242/* Set the parameters into struct eyevalue as follows:
2243a = number of eyes if attacker plays first twice
2244b = number of eyes if attacker plays first
2245c = number of eyes if defender plays first
2246d =number of eyes if defender plays first twice
2247*/
2248
2249void
2250set_eyevalue(struct eyevalue *e, int a, int b, int c, int d)
2251{
2252 e->a = a;
2253 e->b = b;
2254 e->c = c;
2255 e->d = d;
2256}
2257
2258/* Number of eyes if attacker plays first twice (the threat of the first
2259 * move by attacker).
2260 */
2261int
2262min_eye_threat(struct eyevalue *e)
2263{
2264 return e->a;
2265}
2266
2267/* Number of eyes if attacker plays first followed by alternating play. */
2268int
2269min_eyes(struct eyevalue *e)
2270{
2271 return e->b;
2272}
2273
2274/* Number of eyes if defender plays first followed by alternating play. */
2275int
2276max_eyes(struct eyevalue *e)
2277{
2278 return e->c;
2279}
2280
2281/* Number of eyes if defender plays first twice (the threat of the first
2282 * move by defender).
2283 */
2284int
2285max_eye_threat(struct eyevalue *e)
2286{
2287 return e->d;
2288}
2289
2290/* Add the eyevalues *e1 and *e2, leaving the result in *sum. It is
2291 * safe to let sum be the same as e1 or e2.
2292 */
2293void
2294add_eyevalues(struct eyevalue *e1, struct eyevalue *e2, struct eyevalue *sum)
2295{
2296 struct eyevalue res;
2297 res.a = gg_min(gg_min(e1->a + e2->c, e1->c + e2->a),
2298 gg_max(e1->a + e2->b, e1->b + e2->a));
2299 res.b = gg_min(gg_max(e1->b + e2->b, gg_min(e1->a + e2->d, e1->b + e2->c)),
2300 gg_max(e1->b + e2->b, gg_min(e1->d + e2->a, e1->c + e2->b)));
2301 res.c = gg_max(gg_min(e1->c + e2->c, gg_max(e1->d + e2->a, e1->c + e2->b)),
2302 gg_min(e1->c + e2->c, gg_max(e1->a + e2->d, e1->b + e2->c)));
2303 res.d = gg_max(gg_max(e1->d + e2->b, e1->b + e2->d),
2304 gg_min(e1->d + e2->c, e1->c + e2->d));
2305
2306 /* The rules above give 0011 + 0002 = 0012, which is incorrect. Thus
2307 * we need this annoying exception.
2308 */
2309 if ((e1->d - e1->c == 2 && e2->c - e2->b == 1)
2310 || (e1->c - e1->b == 1 && e2->d - e2->c == 2)) {
2311 res.d = gg_max(gg_min(e1->c + e2->d, e1->d + e2->b),
2312 gg_min(e1->d + e2->c, e1->b + e2->d));
2313 }
2314
2315 /* The temporary storage in res is necessary if sum is the same as
2316 * e1 or e2.
2317 */
2318 sum->a = res.a;
2319 sum->b = res.b;
2320 sum->c = res.c;
2321 sum->d = res.d;
2322}
2323
2324/* The impact on the number of eyes (counting up to two) if a vital
2325 * move is made. The possible values are
2326 * 0 - settled eye, no vital move
2327 * 2 - 1/2 eye or 3/2 eyes
2328 * 3 - 3/4 eyes or 5/4 eyes
2329 * 4 - 1* eyes (a chimera)
2330 */
2331int
2332eye_move_urgency(struct eyevalue *e)
2333{
2334 int a = gg_min(e->a, 2);
2335 int b = gg_min(e->b, 2);
2336 int c = gg_min(e->c, 2);
2337 int d = gg_min(e->d, 2);
2338 if (b == c)
2339 return 0;
2340 else
2341 return d + c - b - a;
2342}
2343
2344/* Produces a string representing the eyevalue.
2345 *
2346 * Note: the result string is stored in a statically allocated buffer
2347 * which will be overwritten the next time this function is called.
2348 */
2349char *
2350eyevalue_to_string(struct eyevalue *e)
2351{
2352 static char result[30];
2353 if (e->a < 10 && e->b < 10 && e->c < 10 && e->d < 10)
2354 gg_snprintf(result, 29, "%d%d%d%d", e->a, e->b, e->c, e->d);
2355 else
2356 gg_snprintf(result, 29, "[%d,%d,%d,%d]", e->a, e->b, e->c, e->d);
2357 return result;
2358}
2359
2360
2361
2362/* Test whether the optics code evaluates an eyeshape consistently. */
2363void
2364test_eyeshape(int eyesize, int *eye_vertices)
2365{
2366 int k;
2367 int n, N;
2368 int mx[BOARDMAX];
2369 int pos;
2370 int str = NO_MOVE;
2371 int attack_code;
2372 int attack_point;
2373 int defense_code;
2374 int defense_point;
2375 int save_verbose;
2376 struct board_state starting_position;
2377
2378 /* Clear the board and initialize the engine properly. */
2379 clear_board();
2380 reset_engine();
2381
2382 /* Mark the eyespace in the mx array. */
2383 memset(mx, 0, sizeof(mx));
2384 for (k = 0; k < eyesize; k++) {
2385 ASSERT_ON_BOARD1(eye_vertices[k]);
2386 mx[eye_vertices[k]] = 1;
2387 }
2388
2389 /* Play white stones surrounding the eyespace, including diagonals. */
2390 for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
2391 if (!ON_BOARD(pos) || mx[pos] == 1)
2392 continue;
2393 for (k = 0; k < 8; k++) {
2394 if (ON_BOARD(pos + delta[k]) && mx[pos + delta[k]] == 1) {
2395 play_move(pos, WHITE);
2396 str = pos;
2397 break;
2398 }
2399 }
2400 }
2401
2402 /* Play black stones surrounding the white group, but leaving all
2403 * liberties empty.
2404 */
2405 for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
2406 if (mx[pos] == 1 || board[pos] != EMPTY || liberty_of_string(pos, str))
2407 continue;
2408 for (k = 0; k < 8; k++) {
2409 if (ON_BOARD(pos + delta[k])
2410 && liberty_of_string(pos + delta[k], str)) {
2411 play_move(pos, BLACK);
2412 break;
2413 }
2414 }
2415 }
2416
2417 /* Show the board if verbose is on. Then turn off traces so we don't
2418 * get any from make_worms(), make_dragons(), or the owl reading.
2419 */
2420 if (verbose)
2421 showboard(0);
2422 save_verbose = verbose;
2423 verbose = 0;
2424
2425
2426 /* Store this position so we can come back to it. */
2427 store_board(&starting_position);
2428
2429 /* Loop over all configurations of black stones inserted in the
2430 * eyeshape. There are N = 2^(eyesize) configurations and we can
2431 * straightforwardly use binary representation to enumerate them.
2432 */
2433 N = 1 << eyesize;
2434 for (n = 0; n < N; n++) {
2435 int valid = 1;
2436 int internal_stones = 0;
2437
2438 restore_board(&starting_position);
2439 /* Play the stones for this configuration. */
2440 for (k = 0; k < eyesize; k++) {
2441 if (n & (1 << k)) {
2442 if (!is_legal(eye_vertices[k], BLACK)) {
2443 valid = 0;
2444 break;
2445 }
2446 play_move(eye_vertices[k], BLACK);
2447 internal_stones++;
2448 }
2449 }
2450
2451 if (!valid)
2452 continue;
2453
2454 if (save_verbose > 1)
2455 showboard(0);
2456
2457 /* Now we are ready to test the consistency. This is most easily
2458 * done with help from the owl code. First we must prepare for
2459 * this though.
2460 */
2461 examine_position(EXAMINE_DRAGONS_WITHOUT_OWL, 0);
2462
2463 attack_code = owl_attack(str, &attack_point, NULL, NULL);
2464
2465 if (attack_code == 0) {
2466 /* The owl code claims there is no attack. We test this by
2467 * trying to attack on all empty spaces in the eyeshape.
2468 */
2469 for (k = 0; k < eyesize; k++) {
2470 if (board[eye_vertices[k]] == EMPTY
2471 && is_legal(eye_vertices[k], BLACK)
2472 && owl_does_attack(eye_vertices[k], str, NULL)) {
2473 gprintf("%1m alive, but %1m attacks:\n", str, eye_vertices[k]);
2474 showboard(0);
2475 gprintf("\n");
2476 }
2477 }
2478
2479 /* Furthermore, if the eyespace is almost filled, white should
2480 * be able to play on the remaining eyespace point and still be
2481 * alive.
2482 */
2483 if (internal_stones == eyesize - 1) {
2484 for (k = 0; k < eyesize; k++) {
2485 if (board[eye_vertices[k]] == EMPTY
2486 && !owl_does_defend(eye_vertices[k], str, NULL)) {
2487 gprintf("%1m alive, but almost filled with nakade:\n", str);
2488 showboard(0);
2489 }
2490 }
2491 }
2492 }
2493 else {
2494 defense_code = owl_defend(str, &defense_point, NULL, NULL);
2495 if (defense_code == 0) {
2496 /* The owl code claims there is no defense. We test this by
2497 * trying to defend on all empty spaces in the eyeshape.
2498 */
2499 for (k = 0; k < eyesize; k++) {
2500 if (board[eye_vertices[k]] == EMPTY
2501 && is_legal(eye_vertices[k], WHITE)
2502 && owl_does_defend(eye_vertices[k], str, NULL)) {
2503 gprintf("%1m dead, but %1m defends:\n", str, eye_vertices[k]);
2504 showboard(0);
2505 gprintf("\n");
2506 }
2507 }
2508 }
2509 else {
2510 /* The owl code claims the dragon is critical. Verify the
2511 * attack and defense points.
2512 */
2513 if (board[attack_point] != EMPTY
2514 || !is_legal(attack_point, BLACK)) {
2515 gprintf("Bad attack point %1m:\n", attack_point);
2516 showboard(0);
2517 }
2518 else if (!owl_does_attack(attack_point, str, NULL)) {
2519 gprintf("Attack point %1m failed:\n", attack_point);
2520 showboard(0);
2521 }
2522
2523 if (board[defense_point] != EMPTY
2524 || !is_legal(defense_point, WHITE)) {
2525 gprintf("Bad defense point %1m:\n", defense_point);
2526 showboard(0);
2527 }
2528 else if (!owl_does_defend(defense_point, str, NULL)) {
2529 gprintf("Defense point %1m failed:\n", defense_point);
2530 showboard(0);
2531 }
2532 }
2533 }
2534 }
2535 verbose = save_verbose;
2536}
2537
2538/********************************************************************
2539 * The following static functions are helpers for analyze_eyegraph()
2540 * further down. The purpose is to evaluate eye graphs according to
2541 * the rules for local games, as described in doc/eyes.texi.
2542 *
2543 * The technique to do this is to convert the eye evaluation problem
2544 * into a tactical style life and death reading problem. Tactical in
2545 * the sense of needing to decide whether certain stones can be
2546 * captured, but not in the sense of the tactical reading that five
2547 * liberties are considered safe.
2548 *
2549 * We illustrate how this works with an example. Consider the eye shape
2550 *
2551 * !
2552 * .X
2553 * !...
2554 *
2555 * The basic idea is to embed the eyespace in a perfectly connected
2556 * group without additional eyes or eye potential. This is most easily
2557 * done by the somewhat brutal trick to fill the entire board with
2558 * stones. We let the group consist of white stones (O) and get this
2559 * result, disregarding the two marginal eye vertices:
2560 *
2561 * A B C D E F G H J K L M N O P Q R S T
2562 * 19 O O O O O O O O O O O O O O O O O O O 19
2563 * 18 O O O O O O O O O O O O O O O O O O O 18
2564 * 17 O O O O O O O O O O O O O O O O O O O 17
2565 * 16 O O O O O O O O O O O O O O O O O O O 16
2566 * 15 O O O O O O O O O O O O O O O O O O O 15
2567 * 14 O O O O O O O O O O O O O O O O O O O 14
2568 * 13 O O O O O O O O O O O O O O O O O O O 13
2569 * 12 O O O O O O O O . O O O O O O O O O O 12
2570 * 11 O O O O O O O . X O O O O O O O O O O 11
2571 * 10 O O O O O O . . . . O O O O O O O O O 10
2572 * 9 O O O O O O O O O O O O O O O O O O O 9
2573 * 8 O O O O O O O O O O O O O O O O O O O 8
2574 * 7 O O O O O O O O O O O O O O O O O O O 7
2575 * 6 O O O O O O O O O O O O O O O O O O O 6
2576 * 5 O O O O O O O O O O O O O O O O O O O 5
2577 * 4 O O O O O O O O O O O O O O O O O O O 4
2578 * 3 O O O O O O O O O O O O O O O O O O O 3
2579 * 2 O O O O O O O O O O O O O O O O O O O 2
2580 * 1 O O O O O O O O O O O O O O O O O O O 1
2581 * A B C D E F G H J K L M N O P Q R S T
2582 *
2583 * The question now is whether black can capture all the white stones
2584 * under alternating play where only white may pass. However, first we
2585 * need to make the top and leftmost eye vertices marginal. This is
2586 * done by inserting small invincible black groups in the sea of white
2587 * stones, in contact with the marginal vertices.
2588 *
2589 * A B C D E F G H J K L M N O P Q R S T
2590 * 19 . O O O O O O O O O O O O O O O O O O 19
2591 * 18 O O O O O O O O X X X O O O O O O O O 18
2592 * 17 O O O O O O O O X . X O O O O O O O O 17
2593 * 16 O O O O O O O O X X X O O O O O O O O 16
2594 * 15 O O O O O O O O X . X O O O O O O O O 15
2595 * 14 O O O O O O O O X X X O O O O O O O O 14
2596 * 13 O O O O O O O O X O O O O O O O O O O 13
2597 * 12 O O O O O O O O . O O O O O O O O O O 12
2598 * 11 O O O O O O O . X O O O O O O O O O O 11
2599 * 10 O O O O O O . . . . O O O O O O O O O 10
2600 * 9 O O O O O O X O O O O O O O O O O O O 9
2601 * 8 O O O O X X X O O O O O O O O O O O O 8
2602 * 7 O O O O X . X O O O O O O O O O O O O 7
2603 * 6 O O O O X X X O O O O O O O O O O O O 6
2604 * 5 O O O O X . X O O O O O O O O O O O O 5
2605 * 4 . O O O X X X O O O O O O O O O O O O 4
2606 * 3 X X . O O O O O O O O O O O O O O O O 3
2607 * 2 X . X O O O O O O O O O O O O O O O O 2
2608 * 1 . X X O O O O O O O O O O O O O O O O 1
2609 * A B C D E F G H J K L M N O P Q R S T
2610 *
2611 * In this diagram we have also added an invincible black group in the
2612 * lower left corner in order to add two outer liberties (at A4 and
2613 * C3) for the white group (this is sometimes needed for the tactical
2614 * life and death reading to make sense). Furthermore there is an
2615 * extra eye at A19. This is used when we want to distinguish between
2616 * 0 and 1 (or 2) eyes since the tactical life and death reading by
2617 * itself only cares about two eyes or not. When trying to distinguish
2618 * between 1 (or 0) and 2 eyes we first fill in A19 again.
2619 *
2620 * Depending on the tactical life and death status with or without the
2621 * extra eye we can determine the number of eyes. By evaluating
2622 * tactical life and death status after having made a move we can also
2623 * identify ko threats and critical moves.
2624 *
2625 * This code is organized as follows:
2626 *
2627 * analyze_eyegraph() converts the eyegraph into the tactical board
2628 * position as demonstrated, then calls evaluate_eyespace() to its eye
2629 * value.
2630 *
2631 * white_area() is a helper to add a small invincible black group on
2632 * the board.
2633 *
2634 * evaluate_eyespace() calls tactical_life() and itself recursively to
2635 * determine the eye value and the critical points.
2636 *
2637 * tactical_life() determines whether the white stones on the board
2638 * (assumed to be a single string) can be captured under alternating
2639 * play.
2640 *
2641 * tactical_life_attack() and tactical_life_defend() are two mutually
2642 * recursive functions which perform the actual reading for
2643 * tactical_life().
2644 *
2645 * Worth to mention in this overview is also the cache used for
2646 * tactical_life_attack() and tactical_life_defend(). Since we have a
2647 * limited number of vertices (eye space points + two outer liberties
2648 * + possibly an extra eye) to play on we use a complete cache with a
2649 * unique entry for every possible configuration of stones on the
2650 * considered vertices.
2651 *
2652 * For each cache entry four bits are used, two for attack results and
2653 * two four defense results. Each of these can take the values 0-3
2654 * with the following interpretations:
2655 * 0 - not yet considered
2656 * 1 - result is being computed
2657 * 2 - result has been computed and was a failure (0)
2658 * 3 - result has been computed and was a success (1)
2659 */
2660
2661/* Like trymove() except that it does a superko check. This does,
2662 * however, only disallow repetition (besides simple ko) if the move
2663 * does not capture any stones.
2664 */
2665static int
2666eyegraph_trymove(int pos, int color, const char *message, int str)
2667{
2668 static Hash_data remembered_board_hashes[MAXSTACK];
2669 int k;
2670 int does_capture = does_capture_something(pos, color);
2671
2672 remembered_board_hashes[stackp] = board_hash;
2673
2674 if (!trymove(pos, color, message, str))
2675 return 0;
2676
2677 if (does_capture)
2678 return 1;
2679
2680 for (k = 0; k < stackp; k++)
2681 if (hashdata_is_equal(board_hash, remembered_board_hashes[k])) {
2682 popgo();
2683 return 0;
2684 }
2685
2686 return 1;
2687}
2688
2689static int
2690eyegraph_is_margin_or_outer_liberty(int vertex)
2691{
2692 int k;
2693 int r;
2694 int num_libs;
2695 int libs[MAXLIBS];
2696 int eyes;
2697
2698 for (k = 0; k < 4; k++) {
2699 if (board[vertex + delta[k]] == BLACK) {
2700 eyes = 0;
2701 num_libs = findlib(vertex + delta[k], MAXLIBS, libs);
2702
2703 for (r = 0; r < num_libs; r++)
2704 if (is_suicide(libs[r], WHITE))
2705 eyes++;
2706
2707 if (eyes >= 2)
2708 return 1;
2709 }
2710 }
2711 return 0;
2712}
2713
2714static int
2715eyegraph_order_moves(int num_vertices, int *vertices, int color_to_move, int *moves)
2716{
2717 int num_moves = 0;
2718 int scores[BOARDMAX];
2719 int move;
2720 int score;
2721 int k;
2722 int r;
2723
2724 for (k = 0; k < num_vertices; k++) {
2725 if (k >= num_vertices - 3) {
2726 /* Never useful for white to fill in outer liberties or a second eye. */
2727 if (color_to_move == WHITE)
2728 break;
2729 /* No use playing the second outer liberty before the first one. */
2730 if (k == num_vertices - 2 && board[vertices[num_vertices - 3]] == EMPTY)
2731 continue;
2732 }
2733
2734 move = vertices[k];
2735 score = 0;
2736
2737 if (board[move] != EMPTY)
2738 continue;
2739
2740 if (eyegraph_is_margin_or_outer_liberty(move)) {
2741 if (k < num_vertices - 3)
2742 score = 5; /* margin */
2743 else
2744 score = -10; /* outer liberty */
2745 }
2746
2747 if (accuratelib(move, color_to_move, 2, NULL) == 1)
2748 score -= 3;
2749
2750 for (r = 0; r < 4; r++) {
2751 if (board[move + delta[r]] == EMPTY)
2752 score += 2;
2753 else if (board[move + delta[r]] == BLACK)
2754 score += 3;
2755 }
2756
2757 moves[num_moves] = move;
2758 scores[num_moves] = score;
2759 num_moves++;
2760 }
2761
2762 for (k = 0; k < num_moves; k++) {
2763 int maxscore = scores[k];
2764 int max_at = 0;
2765
2766 /* Find the move with the biggest score. */
2767 for (r = k + 1; r < num_moves; r++) {
2768 if (scores[r] > maxscore) {
2769 maxscore = scores[r];
2770 max_at = r;
2771 }
2772 }
2773
2774 /* Now exchange the move at k with the move at max_at.
2775 * Don't forget to exchange the scores as well.
2776 */
2777 if (max_at != 0) {
2778 int temp = moves[max_at];
2779 moves[max_at] = moves[k];
2780 moves[k] = temp;
2781 temp = scores[max_at];
2782 scores[max_at] = scores[k];
2783 scores[k] = temp;
2784 }
2785 }
2786
2787 return num_moves;
2788}
2789
2790/* Place a small invincible black group on the board.
2791 * It is required that previously there were white stones at all
2792 * involved vertices and on the surrounding vertices.
2793 *
2794 * Returns 1 if a group was placed, 0 otherwise.
2795 */
2796static int
2797white_area(int mx[BOARDMAX], int pos, int up, int right, int marginpos,
2798 int distance)
2799{
2800 int u, v;
2801 int k;
2802 int edge = is_edge_vertex(marginpos);
2803
2804 for (k = 1; k < distance; k++)
2805 if (!ON_BOARD(marginpos + k * up)
2806 || mx[marginpos + k * up] != WHITE)
2807 return 0;
2808
2809 for (u = -1; u <= 4; u++)
2810 for (v = -1; v <= 4; v++) {
2811 int pos2 = pos + u * up + v * right;
2812 if (!ON_BOARD(pos2)) {
2813 if (!edge)
2814 return 0;
2815 else if (u >= 0 && u <= 3 && v >= 0 && v <= 3)
2816 return 0;
2817 else if (I(pos2) != I(NORTH(marginpos))
2818 && I(pos2) != I(SOUTH(marginpos))
2819 && J(pos2) != J(WEST(marginpos))
2820 && J(pos2) != J(EAST(marginpos)))
2821 return 0;
2822 }
2823 else if (mx[pos2] != WHITE)
2824 return 0;
2825 }
2826
2827 for (u = 0; u <= 3; u++)
2828 for (v = 0; v <= 3; v++) {
2829 int pos2 = pos + u * up + v * right;
2830 mx[pos2] = BLACK;
2831 }
2832
2833 mx[pos + up + right] = EMPTY;
2834 mx[pos + 2 * up + 2 * right] = EMPTY;
2835
2836 return 1;
2837}
2838
2839
2840#define EYEGRAPH_RETURN(result, trace) \
2841 do { \
2842 if (sgf_dumptree) \
2843 sgftreeAddComment(sgf_dumptree, (trace)); \
2844 return (result); \
2845 } while (0);
2846
2847static int tactical_life_defend(int str, int num_vertices, int *vertices,
2848 unsigned char *results);
2849
2850/* Determine whether black can capture all white stones. */
2851static int
2852tactical_life_attack(int str, int num_vertices, int *vertices,
2853 unsigned char *results)
2854{
2855 int k;
2856 int hash = 0;
2857 int cached_result;
2858 int result;
2859 int num_moves;
2860 int moves[BOARDMAX];
2861
2862 /* Compute hash value to index the result cache with. */
2863 for (k = 0; k < num_vertices; k++) {
2864 hash *= 3;
2865 hash += board[vertices[k]];
2866 }
2867 hash *= 2;
2868 hash += (board_ko_pos != NO_MOVE);
2869
2870 /* Is the result known from the cache? */
2871 cached_result = results[hash] & 3;
2872
2873 if (0) {
2874 showboard(0);
2875 gprintf("%d %d (%d)\n", hash, cached_result, results[hash]);
2876 }
2877
2878 if (cached_result == 2)
2879 EYEGRAPH_RETURN(0, "tactical_life_attack: 0 (cached)");
2880 if (cached_result == 3)
2881 EYEGRAPH_RETURN(1, "tactical_life_attack: win (cached)");
2882 if (cached_result == 1)
2883 EYEGRAPH_RETURN(1, "tactical_life_attack: win (open node in cache)");
2884
2885 /* Mark this entry in the cache as currently being computed. */
2886 results[hash] |= 1;
2887
2888 /* Try to play on all relevant vertices. */
2889 num_moves = eyegraph_order_moves(num_vertices, vertices,
2890 OTHER_COLOR(board[str]), moves);
2891 for (k = 0; k < num_moves; k++) {
2892 int move = moves[k];
2893 if (eyegraph_trymove(move, OTHER_COLOR(board[str]),
2894 "tactical_life_attack", str)) {
2895 /* We were successful if the white stones were captured or if no
2896 * defense can be found.
2897 */
2898 if (board[str] == EMPTY)
2899 result = 1;
2900 else
2901 result = !tactical_life_defend(str, num_vertices, vertices, results);
2902
2903 popgo();
2904
2905 if (result == 1) {
2906 /* Store the result (success) in the cache. */
2907 results[hash] = (results[hash] & (~3)) | 3;
2908 EYEGRAPH_RETURN(1, "tactical_life_attack: win");
2909 }
2910 }
2911 }
2912
2913 /* Store the result (failure) in the cache. */
2914 results[hash] = (results[hash] & (~3)) | 2;
2915 EYEGRAPH_RETURN(0, "tactical_life_attack: 0");
2916}
2917
2918/* Determine whether white can live with all stones. */
2919static int
2920tactical_life_defend(int str, int num_vertices, int *vertices,
2921 unsigned char *results)
2922{
2923 int k;
2924 int hash = 0;
2925 int cached_result;
2926 int result;
2927 int num_moves;
2928 int moves[BOARDMAX];
2929
2930 /* Compute hash value to index the result cache with. */
2931 for (k = 0; k < num_vertices; k++) {
2932 hash *= 3;
2933 ASSERT1(board[vertices[k]] <= 2, vertices[k]);
2934 hash += board[vertices[k]];
2935 }
2936 hash *= 2;
2937 hash += (board_ko_pos != NO_MOVE);
2938
2939 /* Is the result known from the cache? */
2940 cached_result = (results[hash] >> 2) & 3;
2941
2942 if (0) {
2943 showboard(0);
2944 gprintf("%d %d (%d)\n", hash, cached_result, results[hash]);
2945 }
2946
2947 if (cached_result == 2)
2948 EYEGRAPH_RETURN(0, "tactical_life_defend: 0 (cached)");
2949 if (cached_result == 3)
2950 EYEGRAPH_RETURN(1, "tactical_life_defend: win (cached)");
2951 if (cached_result == 1)
2952 EYEGRAPH_RETURN(1, "tactical_life_defend: win (node open in cache)");
2953
2954 /* Mark this entry in the cache as currently being computed. */
2955 results[hash] |= (1 << 2);
2956
2957 /* Try to play on all relevant vertices. */
2958 num_moves = eyegraph_order_moves(num_vertices, vertices, board[str], moves);
2959 for (k = 0; k < num_moves; k++) {
2960 int move = moves[k];
2961 if ((!is_suicide(move, OTHER_COLOR(board[str]))
2962 || does_capture_something(move, board[str]))
2963 && eyegraph_trymove(move, board[str], "tactical_life_defend", str)) {
2964 /* We were successful if no attack can be found. */
2965 result = !tactical_life_attack(str, num_vertices, vertices, results);
2966
2967 popgo();
2968
2969 if (result == 1) {
2970 /* Store the result (success) in the cache. */
2971 results[hash] = (results[hash] & (~12)) | (3 << 2);
2972 EYEGRAPH_RETURN(1, "tactical_life_defend: win");
2973 }
2974 }
2975 }
2976
2977 /* If no move worked, also try passing. */
2978 if (!tactical_life_attack(str, num_vertices, vertices, results)) {
2979 /* Store the result (success) in the cache. */
2980 results[hash] = (results[hash] & (~12)) | (3 << 2);
2981 EYEGRAPH_RETURN(1, "tactical_life_defend: win");
2982 }
2983
2984 /* Store the result (failure) in the cache. */
2985 results[hash] = (results[hash] & (~12)) | (2 << 2);
2986 EYEGRAPH_RETURN(0, "tactical_life_defend: 0");
2987}
2988
2989/* Determine the tactical life and death status of all white stones.
2990 * Also find all attack and defense moves. The parameter have_eye
2991 * determines whether the extra eye in the upper left corner should be
2992 * used or filled in before starting reading.
2993 */
2994static void
2995tactical_life(int have_eye, int num_vertices, int *vertices,
2996 int *attack_code, int *num_attacks, int *attack_points,
2997 int *defense_code, int *num_defenses, int *defense_points,
2998 unsigned char *results)
2999{
3000 int k;
3001 int str;
3002 int num_moves;
3003 int moves[BOARDMAX];
3004
3005 gg_assert(attack_code != NULL && defense_code != NULL);
3006
3007 /* We know that the large white group includes A18. This is the
3008 * vertex we test to determine whether the white stones have been
3009 * captured.
3010 */
3011 str = POS(1, 0);
3012
3013 if (board[str] == EMPTY) {
3014 /* The stones have already been captured, too late to defend. */
3015 *attack_code = WIN;
3016 *defense_code = 0;
3017 return;
3018 }
3019
3020 /* Fill in the extra eye if have_eye is 0. If filling in would be
3021 * suicide the white stones can be considered dead.
3022 */
3023 if (!have_eye) {
3024 if (!eyegraph_trymove(POS(0, 0), WHITE, "tactical_life-A", NO_MOVE)) {
3025 *attack_code = WIN;
3026 *defense_code = 0;
3027 return;
3028 }
3029 }
3030
3031 *attack_code = 0;
3032 *defense_code = 0;
3033
3034 /* Call tactical_life_attack() and tactical_life_defend() to
3035 * determine status.
3036 */
3037 if (tactical_life_attack(str, num_vertices, vertices, results)) {
3038 *attack_code = WIN;
3039 if (tactical_life_defend(str, num_vertices, vertices, results))
3040 *defense_code = WIN;
3041 }
3042 else
3043 *defense_code = WIN;
3044
3045
3046 /* If the status is critical, try to play at each relevant vertex
3047 * and call tactical_life_defend() or tactical_life_attack() to
3048 * determine whether the move works as attack or defense.
3049 */
3050 if (*attack_code != 0 && *defense_code != 0) {
3051 if (num_attacks != NULL && attack_points != NULL) {
3052 *num_attacks = 0;
3053 num_moves = eyegraph_order_moves(num_vertices, vertices,
3054 OTHER_COLOR(board[str]), moves);
3055 for (k = 0; k < num_moves; k++) {
3056 int move = moves[k];
3057 if (eyegraph_trymove(move, OTHER_COLOR(board[str]), "tactical_life-B",
3058 str)) {
3059 if (board[str] == EMPTY
3060 || !tactical_life_defend(str, num_vertices, vertices, results))
3061 attack_points[(*num_attacks)++] = move;
3062 popgo();
3063 }
3064 }
3065 }
3066
3067 if (num_defenses != NULL && defense_points != NULL) {
3068 *num_defenses = 0;
3069 num_moves = eyegraph_order_moves(num_vertices, vertices, board[str],
3070 moves);
3071 for (k = 0; k < num_moves; k++) {
3072 int move = moves[k];
3073 if (eyegraph_trymove(move, board[str], "tactical_life-C", str)) {
3074 if (!tactical_life_attack(str, num_vertices, vertices, results))
3075 defense_points[(*num_defenses)++] = move;
3076 popgo();
3077 }
3078 }
3079 }
3080 }
3081
3082 /* Unfill the extra eye if we didn't use it. */
3083 if (!have_eye)
3084 popgo();
3085}
3086
3087/* Determine the eye value of the eyespace for the big white group on
3088 * the board and vital moves. The possible eye values are documented
3089 * in the preamble to eyes.db. By calling tactical_life() multiple
3090 * times, with and without using an extra eye, we can compute the eye
3091 * values. To determine ko threats and vital moves, tactical_life() is
3092 * called again after trying to play on one of the relevant vertices.
3093 * In order to find out whether ko threats really are effective and to
3094 * distinguish between 0122/1122 and 0012/0011 eye values (see
3095 * discussion on pattern 6141 in the preamble of eyes.db), we may also
3096 * need to recursively call ourselves after a move has been made.
3097 */
3098static void
3099evaluate_eyespace(struct eyevalue *result, int num_vertices, int *vertices,
3100 int *num_vital_attacks, int *vital_attacks,
3101 int *num_vital_defenses, int *vital_defenses,
3102 unsigned char *tactical_life_results)
3103{
3104 int k;
3105 int attack_code;
3106 int num_attacks;
3107 int attack_points[BOARDMAX];
3108 int defense_code;
3109 int num_defenses;
3110 int defense_points[BOARDMAX];
3111 int attack_code2;
3112 int num_attacks2;
3113 int attack_points2[BOARDMAX];
3114 int defense_code2;
3115 struct eyevalue result2;
3116 int num_vital_attacks2;
3117 int vital_attacks2[BOARDMAX];
3118 int num_vital_defenses2;
3119 int vital_defenses2[BOARDMAX];
3120 int num_moves;
3121 int moves[BOARDMAX];
3122
3123 *num_vital_attacks = 0;
3124 *num_vital_defenses = 0;
3125
3126 /* Determine tactical life without an extra eye. */
3127 tactical_life(0, num_vertices, vertices,
3128 &attack_code, &num_attacks, attack_points,
3129 &defense_code, &num_defenses, defense_points,
3130 tactical_life_results);
3131
3132 if (attack_code == 0) {
3133 /* Alive without extra eye.
3134 * Possible results: 0222, 1222, 2222
3135 *
3136 * Determine whether there are ko threats and how serious.
3137 */
3138 int a = 2;
3139
3140 if (sgf_dumptree)
3141 sgftreeAddComment(sgf_dumptree, "Alive without extra eye.\n");
3142
3143 num_moves = eyegraph_order_moves(num_vertices, vertices, BLACK, moves);
3144 for (k = 0; k < num_moves; k++) {
3145 int acode, dcode;
3146 int move = moves[k];
3147 if (eyegraph_trymove(move, BLACK, "evaluate_eyespace-A", NO_MOVE)) {
3148 tactical_life(0, num_vertices, vertices, &acode, NULL, NULL,
3149 &dcode, NULL, NULL, tactical_life_results);
3150 if (acode != 0) {
3151 tactical_life(1, num_vertices, vertices, &acode, NULL, NULL,
3152 &dcode, NULL, NULL, tactical_life_results);
3153 if (acode != 0) {
3154 if (a == 1)
3155 *num_vital_attacks = 0;
3156 a = 0;
3157 vital_attacks[(*num_vital_attacks)++] = move;
3158 if (sgf_dumptree)
3159 sgftreeAddComment(sgf_dumptree,
3160 "Ko threat to remove both eyes.\n");
3161 }
3162 else {
3163 if (a != 0) {
3164 vital_attacks[(*num_vital_attacks)++] = move;
3165 a = 1;
3166 }
3167 if (sgf_dumptree)
3168 sgftreeAddComment(sgf_dumptree, "Ko threat to remove one eye.\n");
3169 }
3170 }
3171 popgo();
3172 }
3173 }
3174 set_eyevalue(result, a, 2, 2, 2);
3175 if (sgf_dumptree) {
3176 if (a == 0)
3177 sgftreeAddComment(sgf_dumptree, "Eyevalue 0222.\n");
3178 else if (a == 1)
3179 sgftreeAddComment(sgf_dumptree, "Eyevalue 1222.\n");
3180 else
3181 sgftreeAddComment(sgf_dumptree, "Eyevalue 2222.\n");
3182 }
3183 }
3184 else if (defense_code != 0) {
3185 /* Critical without extra eye.
3186 * Possible results: 0022, 0122, 1122
3187 */
3188 if (sgf_dumptree)
3189 sgftreeAddComment(sgf_dumptree, "Critical without extra eye.\n");
3190 tactical_life(1, num_vertices, vertices,
3191 &attack_code2, &num_attacks2, attack_points2,
3192 &defense_code2, NULL, NULL, tactical_life_results);
3193 for (k = 0; k < num_defenses; k++)
3194 vital_defenses[(*num_vital_defenses)++] = defense_points[k];
3195 if (attack_code2 == WIN) {
3196 /* A chimera. 0022. */
3197 set_eyevalue(result, 0, 0, 2, 2);
3198 for (k = 0; k < num_attacks2; k++)
3199 vital_attacks[(*num_vital_attacks)++] = attack_points2[k];
3200 if (sgf_dumptree)
3201 sgftreeAddComment(sgf_dumptree, "Eyevalue: 0022.\n");
3202 }
3203 else {
3204 int a = 1;
3205 for (k = 0; k < num_attacks; k++) {
3206 int move = attack_points[k];
3207 if (eyegraph_trymove(move, BLACK, "evaluate_eyespace-B", NO_MOVE)) {
3208 evaluate_eyespace(&result2, num_vertices, vertices,
3209 &num_vital_attacks2, vital_attacks2,
3210 &num_vital_defenses2, vital_defenses2,
3211 tactical_life_results);
3212 /* If result2 is 0011 for some move we have 0122 as final
3213 * result, otherwise 1122.
3214 */
3215 if (min_eyes(&result2) == 0
3216 && max_eyes(&result2) == 1
3217 && max_eye_threat(&result2) == 1) {
3218 if (a == 1)
3219 *num_vital_attacks = 0;
3220 a = 0;
3221 vital_attacks[(*num_vital_attacks)++] = move;
3222 }
3223 else if (a == 1)
3224 vital_attacks[(*num_vital_attacks)++] = move;
3225 popgo();
3226 }
3227 }
3228 set_eyevalue(result, a, 1, 2, 2);
3229 if (sgf_dumptree) {
3230 if (a == 0)
3231 sgftreeAddComment(sgf_dumptree, "Eyevalue: 0122.\n");
3232 else
3233 sgftreeAddComment(sgf_dumptree, "Eyevalue: 1122.\n");
3234 }
3235 }
3236 }
3237 else {
3238 /* Dead without extra eye.
3239 * Possible results: 0000, 0001, 0002, 0011, 0012, 0111, 0112, 1111, 1112
3240 *
3241 * Now determine tactical life with an extra eye.
3242 */
3243 if (sgf_dumptree)
3244 sgftreeAddComment(sgf_dumptree, "Dead without extra eye.\n");
3245 tactical_life(1, num_vertices, vertices,
3246 &attack_code, &num_attacks, attack_points,
3247 &defense_code, &num_defenses, defense_points,
3248 tactical_life_results);
3249 if (attack_code == 0) {
3250 /* Alive with extra eye.
3251 * Possible results: 0111, 0112, 1111, 1112
3252 */
3253 int a = 1;
3254 int d = 1;
3255 if (sgf_dumptree)
3256 sgftreeAddComment(sgf_dumptree, "Alive with extra eye.\n");
3257 num_moves = eyegraph_order_moves(num_vertices, vertices, BLACK, moves);
3258 for (k = 0; k < num_moves; k++) {
3259 int acode, dcode;
3260 int move = moves[k];
3261 if (eyegraph_trymove(move, BLACK, "evaluate_eyespace-C", NO_MOVE)) {
3262 tactical_life(1, num_vertices, vertices, &acode, NULL, NULL,
3263 &dcode, NULL, NULL, tactical_life_results);
3264 if (acode != 0) {
3265 evaluate_eyespace(&result2, num_vertices, vertices,
3266 &num_vital_attacks2, vital_attacks2,
3267 &num_vital_defenses2, vital_defenses2,
3268 tactical_life_results);
3269 /* This is either 0011 or 0012. Only the first is acceptable. */
3270 if (max_eye_threat(&result2) == 1) {
3271 vital_attacks[(*num_vital_attacks)++] = move;
3272 a = 0;
3273 if (sgf_dumptree)
3274 sgftreeAddComment(sgf_dumptree, "Attacking ko threat.\n");
3275 }
3276 }
3277 popgo();
3278 }
3279 }
3280
3281 num_moves = eyegraph_order_moves(num_vertices, vertices, WHITE, moves);
3282 for (k = 0; k < num_moves; k++) {
3283 int acode, dcode;
3284 int move = moves[k];
3285 if (eyegraph_trymove(move, WHITE, "evaluate_eyespace-D", NO_MOVE)) {
3286 tactical_life(0, num_vertices, vertices, &acode, NULL, NULL,
3287 &dcode, NULL, NULL, tactical_life_results);
3288 if (dcode != 0) {
3289 evaluate_eyespace(&result2, num_vertices, vertices,
3290 &num_vital_attacks2, vital_attacks2,
3291 &num_vital_defenses2, vital_defenses2,
3292 tactical_life_results);
3293 /* This is either 1122 or 0122. Only the first is acceptable. */
3294 if (min_eye_threat(&result2) == 1) {
3295 vital_defenses[(*num_vital_defenses)++] = move;
3296 d = 2;
3297 if (sgf_dumptree)
3298 sgftreeAddComment(sgf_dumptree, "Defending ko threat.\n");
3299 }
3300 }
3301 popgo();
3302 }
3303 }
3304 set_eyevalue(result, a, 1, 1, d);
3305 if (sgf_dumptree) {
3306 if (a == 0 && d == 1)
3307 sgftreeAddComment(sgf_dumptree, "Eyevalue 0111.\n");
3308 else if (a == 0 && d == 2)
3309 sgftreeAddComment(sgf_dumptree, "Eyevalue 0112.\n");
3310 else if (a == 1 && d == 1)
3311 sgftreeAddComment(sgf_dumptree, "Eyevalue 1111.\n");
3312 else
3313 sgftreeAddComment(sgf_dumptree, "Eyevalue 1112.\n");
3314 }
3315 }
3316 else if (defense_code != 0) {
3317 /* Critical with extra eye.
3318 * Possible results: 0011, 0012
3319 */
3320 int d = 1;
3321 if (sgf_dumptree)
3322 sgftreeAddComment(sgf_dumptree, "Critical with extra eye.\n");
3323 for (k = 0; k < num_attacks; k++)
3324 vital_attacks[(*num_vital_attacks)++] = attack_points[k];
3325 for (k = 0; k < num_defenses; k++) {
3326 int move = defense_points[k];
3327 if (eyegraph_trymove(move, WHITE, "evaluate_eyespace-E", NO_MOVE)) {
3328 evaluate_eyespace(&result2, num_vertices, vertices,
3329 &num_vital_attacks2, vital_attacks2,
3330 &num_vital_defenses2, vital_defenses2,
3331 tactical_life_results);
3332 /* If result2 is 1122 for some move we have 0012 as final
3333 * result, otherwise 0011.
3334 */
3335 if (min_eye_threat(&result2) == 1
3336 && min_eyes(&result2) == 1
3337 && max_eyes(&result2) == 2) {
3338 if (d == 1)
3339 *num_vital_defenses = 0;
3340 d = 2;
3341 vital_defenses[(*num_vital_defenses)++] = move;
3342 }
3343 else if (d == 1)
3344 vital_defenses[(*num_vital_defenses)++] = move;
3345 popgo();
3346 }
3347 }
3348 set_eyevalue(result, 0, 0, 1, d);
3349 if (sgf_dumptree) {
3350 if (d == 1)
3351 sgftreeAddComment(sgf_dumptree, "Eyevalue: 0011.\n");
3352 else
3353 sgftreeAddComment(sgf_dumptree, "Eyevalue: 0012.\n");
3354 }
3355 }
3356 else {
3357 /* Dead with extra eye.
3358 * Possible results: 0000, 0001, 0002
3359 *
3360 * Determine whether there are ko threats and how serious.
3361 */
3362 int d = 0;
3363 if (sgf_dumptree)
3364 sgftreeAddComment(sgf_dumptree, "Dead with extra eye.\n");
3365 num_moves = eyegraph_order_moves(num_vertices, vertices, WHITE, moves);
3366 for (k = 0; k < num_moves; k++) {
3367 int acode, dcode;
3368 int move = moves[k];
3369 if (eyegraph_trymove(move, WHITE, "evaluate_eyespace-F", NO_MOVE)) {
3370 tactical_life(1, num_vertices, vertices, &acode, NULL, NULL,
3371 &dcode, NULL, NULL, tactical_life_results);
3372 if (dcode != 0) {
3373 tactical_life(0, num_vertices, vertices, &acode, NULL, NULL,
3374 &dcode, NULL, NULL, tactical_life_results);
3375 if (dcode != 0) {
3376 if (d == 1)
3377 *num_vital_defenses = 0;
3378 d = 2;
3379 vital_defenses[(*num_vital_defenses)++] = move;
3380 if (sgf_dumptree)
3381 sgftreeAddComment(sgf_dumptree,
3382 "Ko threat to make two eyes.\n");
3383 }
3384 else {
3385 if (d != 2) {
3386 vital_defenses[(*num_vital_defenses)++] = move;
3387 d = 1;
3388 }
3389 if (sgf_dumptree)
3390 sgftreeAddComment(sgf_dumptree,
3391 "Ko threat to make one eye.\n");
3392 }
3393 }
3394 popgo();
3395 }
3396 }
3397 set_eyevalue(result, 0, 0, 0, d);
3398 if (sgf_dumptree) {
3399 if (d == 0)
3400 sgftreeAddComment(sgf_dumptree, "Eyevalue 0000.\n");
3401 else if (d == 1)
3402 sgftreeAddComment(sgf_dumptree, "Eyevalue 0001.\n");
3403 else
3404 sgftreeAddComment(sgf_dumptree, "Eyevalue 0002.\n");
3405 }
3406 }
3407 }
3408}
3409
3410/* Add small invincible black groups in contact with the marginal
3411 * vertices, without destroying the connectivity of the white stones.
3412 *
3413 */
3414static int
3415add_margins(int num_margins, int *margins, int mx[BOARDMAX])
3416{
3417 int k;
3418 int i, j;
3419 int old_mx[BOARDMAX];
3420 int pos;
3421
3422 if (num_margins == 0)
3423 return 1;
3424
3425 memcpy(old_mx, mx, sizeof(old_mx));
3426
3427 pos = margins[num_margins - 1];
3428
3429 for (k = 0; k < 4; k++) {
3430 int up = delta[k];
3431 int right = delta[(k + 1) % 4];
3432
3433 if (!ON_BOARD(pos + up))
3434 continue;
3435
3436 if (mx[pos + up] == WHITE
3437 && (!ON_BOARD(pos + up + right) || mx[pos + up + right] == WHITE)
3438 && (!ON_BOARD(pos + up - right) || mx[pos + up - right] == WHITE)) {
3439 for (i = -3; i <= 0; i++) {
3440 for (j = 2; j < 6; j++) {
3441 if (white_area(mx, pos + j * up + i * right, up, right, pos, j)) {
3442 int s = 1;
3443 while (mx[pos + s * up] == WHITE) {
3444 mx[pos + s * up] = BLACK;
3445 s++;
3446 }
3447 if (add_margins(num_margins - 1, margins, mx))
3448 return 1;
3449 else
3450 memcpy(mx, old_mx, sizeof(old_mx));
3451 }
3452 }
3453 }
3454 }
3455 }
3456
3457 return 0;
3458}
3459
3460/* Analyze an eye graph to determine the eye value and vital moves.
3461 *
3462 * The eye graph is given by a string which is encoded with "%" for
3463 * newlines and "O" for spaces. E.g., the eye graph
3464 *
3465 * !
3466 * .X
3467 * !...
3468 *
3469 * is encoded as "OO!%O.X%!...". (The encoding is needed for the GTP
3470 * interface to this function.)
3471 *
3472 * The result is an eye value and a (nonencoded) pattern showing the
3473 * vital moves, using the same notation as eyes.db. In the example above
3474 * we would get the eye value 0112 and the graph (showing ko threat moves)
3475 *
3476 * @
3477 * .X
3478 * !.*.
3479 *
3480 * If the eye graph cannot be realized, 0 is returned, 1 otherwise.
3481 */
3482int
3483analyze_eyegraph(const char *coded_eyegraph, struct eyevalue *value,
3484 char *analyzed_eyegraph)
3485{
3486 int k;
3487 int i, j;
3488 int mini, minj;
3489 int mx[BOARDMAX];
3490 char mg[BOARDMAX];
3491 int pos;
3492
3493 int num_vital_attacks;
3494 int vital_attacks[BOARDMAX]; /* Way larger than necessary. */
3495 int num_vital_defenses;
3496 int vital_defenses[BOARDMAX]; /* Way larger than necessary. */
3497
3498 int maxwidth;
3499 int current_width;
3500 int num_rows;
3501 int horizontal_edge;
3502 int vertical_edge;
3503
3504 int num_margins;
3505 int margins[BOARDMAX]; /* Way larger than necessary. */
3506
3507 int num_vertices;
3508 int vertices[BOARDMAX]; /* Way larger than necessary. */
3509
3510 int table_size;
3511 unsigned char *tactical_life_results;
3512
3513 if (0)
3514 gprintf("Analyze eyegraph %s\n", coded_eyegraph);
3515
3516 /* Mark the eyespace in the mx array. We construct the position in
3517 * the mx array and copy it to the actual board later.
3518 */
3519 for (pos = BOARDMIN; pos < BOARDMAX; pos++)
3520 if (ON_BOARD(pos))
3521 mx[pos] = WHITE;
3522
3523 /* Find out the size of the eye graph pattern so that we can center
3524 * it properly.
3525 */
3526 maxwidth = 0;
3527 current_width = 0;
3528 num_rows = 1;
3529 horizontal_edge = -1;
3530 vertical_edge = -1;
3531 for (k = 0; k < (int) strlen(coded_eyegraph); k++) {
3532 if (coded_eyegraph[k] == '\n')
3533 continue;
3534 if (coded_eyegraph[k] == '%') {
3535 num_rows++;
3536 if (current_width > maxwidth)
3537 maxwidth = current_width;
3538 current_width = 0;
3539 }
3540 else {
3541 if (coded_eyegraph[k] == '-')
3542 horizontal_edge = num_rows - 1;
3543 else if (coded_eyegraph[k] == '|')
3544 vertical_edge = current_width;
3545 current_width++;
3546 }
3547 }
3548 if (current_width > maxwidth)
3549 maxwidth = current_width;
3550
3551 /* Cut out the eyespace from the solid white string. */
3552 num_margins = 0;
3553 num_vertices = 0;
3554
3555 if (horizontal_edge == 0)
3556 mini = -1;
3557 else if (horizontal_edge > 0)
3558 mini = board_size - num_rows + 1;
3559 else
3560 mini = (board_size - num_rows) / 2;
3561
3562 if (vertical_edge == 0)
3563 minj = -1;
3564 else if (vertical_edge > 0)
3565 minj = board_size - maxwidth + 1;
3566 else
3567 minj = (board_size - maxwidth) / 2;
3568
3569 i = mini;
3570 j = minj;
3571 for (k = 0; k < (int) strlen(coded_eyegraph); k++) {
3572 char c = coded_eyegraph[k];
3573 if (c == '\n')
3574 continue;
3575 if (c == '%') {
3576 i++;
3577 j = minj - 1;
3578 }
3579 else if (c == 'X' || c == '$')
3580 mx[POS(i, j)] = BLACK;
3581 else if (c == '.' || c == '*' || c == '<' || c == '>'
3582 || c == '!' || c == '@' || c == '(' || c == ')')
3583 mx[POS(i, j)] = EMPTY;
3584 if (c == '!' || c == '@' || c == '(' || c == ')' || c == '$')
3585 margins[num_margins++] = POS(i, j);
3586 if (c != '|' && c != '-' && c != '+' && c != '%'
3587 && ON_BOARD(POS(i, j)) && mx[POS(i, j)] != WHITE)
3588 vertices[num_vertices++] = POS(i, j);
3589 j++;
3590 }
3591
3592 /* Add an invincible black group in the lower left plus two outer
3593 * liberties for the white string. However, if the eyespace is
3594 * placed in or near the lower left corner, we put this group in the
3595 * upper right instead.
3596 */
3597 pos = POS(board_size - 2, 1);
3598 if ((vertical_edge == 0 && horizontal_edge != 0)
3599 || (horizontal_edge > 0 && vertical_edge <= 0))
3600 pos = POS(1, board_size - 2);
3601 mx[pos] = EMPTY;
3602 mx[NORTH(pos)] = BLACK;
3603 mx[NW(pos)] = BLACK;
3604 mx[NE(pos)] = EMPTY;
3605 mx[WEST(pos)] = BLACK;
3606 mx[EAST(pos)] = BLACK;
3607 mx[SW(pos)] = EMPTY;
3608 mx[SOUTH(pos)] = BLACK;
3609 mx[SE(pos)] = BLACK;
3610 if (ON_BOARD(NN(pos)))
3611 mx[NN(pos)] = EMPTY;
3612 else
3613 mx[SS(pos)] = EMPTY;
3614
3615 /* Add the two outer liberties in the lower left or upper right to
3616 * the list of vertices.
3617 */
3618 if (ON_BOARD(NN(pos))) {
3619 vertices[num_vertices++] = NE(pos);
3620 vertices[num_vertices++] = NN(pos);
3621 }
3622 else {
3623 vertices[num_vertices++] = SW(pos);
3624 vertices[num_vertices++] = SS(pos);
3625 }
3626
3627 /* Add an extra eye in the upper left corner. */
3628 mx[POS(0, 0)] = EMPTY;
3629 vertices[num_vertices++] = POS(0, 0);
3630
3631 if (!add_margins(num_margins, margins, mx))
3632 return 0;
3633
3634 /* Copy the mx array over to the board. */
3635 clear_board();
3636 for (pos = BOARDMIN; pos < BOARDMAX; pos++)
3637 if (ON_BOARD(pos)) {
3638 if (mx[pos] == WHITE)
3639 add_stone(pos, WHITE);
3640 else if (mx[pos] == BLACK)
3641 add_stone(pos, BLACK);
3642 }
3643
3644 if (verbose)
3645 showboard(0);
3646
3647 /* If there are any isolated O stones, those should also be added to
3648 * the playable vertices.
3649 */
3650 for (pos = BOARDMIN; pos < BOARDMAX; pos++)
3651 if (board[pos] == WHITE && !same_string(pos, POS(1, 0))) {
3652 vertices[num_vertices] = vertices[num_vertices - 1];
3653 vertices[num_vertices - 1] = vertices[num_vertices - 2];
3654 vertices[num_vertices - 2] = vertices[num_vertices - 3];
3655 vertices[num_vertices - 3] = pos;
3656 num_vertices++;
3657 }
3658
3659 if (verbose) {
3660 int k;
3661 gprintf("\nPlayable vertices:\n");
3662 for (k = 0; k < num_vertices; k++)
3663 gprintf("%1m ", vertices[k]);
3664 gprintf("\n\n");
3665 }
3666
3667 /* Disable this test if you need to evaluate larger eyespaces, have
3668 * no shortage of memory, and know what you're doing.
3669 */
3670 if (num_vertices > 17) {
3671 gprintf("analyze_eyegraph: too large eyespace, %d vertices\n",
3672 num_vertices);
3673 gg_assert(num_vertices <= 17);
3674 }
3675
3676 /* The cache must have 2*3^num_vertices entries. */
3677 table_size = 2;
3678 for (k = 0; k < num_vertices; k++)
3679 table_size *= 3;
3680
3681 /* Allocate memory for the cache. */
3682 tactical_life_results = malloc(table_size);
3683 if (!tactical_life_results) {
3684 gprintf("analyze_eyegraph: failed to allocate %d bytes\n", table_size);
3685 gg_assert(tactical_life_results != NULL);
3686 }
3687 memset(tactical_life_results, 0, table_size);
3688
3689 if (sgf_dumptree)
3690 sgffile_printboard(sgf_dumptree);
3691
3692 /* Evaluate the eyespace on the board. */
3693 evaluate_eyespace(value, num_vertices, vertices,
3694 &num_vital_attacks, vital_attacks,
3695 &num_vital_defenses, vital_defenses,
3696 tactical_life_results);
3697
3698 /* Return the cache memory. */
3699 free(tactical_life_results);
3700
3701 if (verbose) {
3702 gprintf("Eyevalue: %s\n", eyevalue_to_string(value));
3703 for (k = 0; k < num_vital_attacks; k++)
3704 gprintf(" vital attack point %1m\n", vital_attacks[k]);
3705 for (k = 0; k < num_vital_defenses; k++)
3706 gprintf(" vital defense point %1m\n", vital_defenses[k]);
3707 }
3708
3709 /* Encode the attack and defense points with symbols in the mg[] array. */
3710 memset(mg, ' ', sizeof(mg));
3711
3712 for (k = 0; k < num_vertices - 2; k++)
3713 mg[vertices[k]] = (board[vertices[k]] == BLACK ? 'X' : '.');
3714
3715 for (k = 0; k < num_margins; k++)
3716 mg[margins[k]] = (mg[margins[k]] == 'X' ? '$' : '!');
3717
3718 for (k = 0; k < num_vital_attacks; k++)
3719 mg[vital_attacks[k]] = (mg[vital_attacks[k]] == '!' ? '(' : '<');
3720
3721 for (k = 0; k < num_vital_defenses; k++) {
3722 int pos = vital_defenses[k];
3723 if (mg[pos] == '.')
3724 mg[pos] = '>';
3725 else if (mg[pos] == '!')
3726 mg[pos] = ')';
3727 else if (mg[pos] == '<')
3728 mg[pos] = '*';
3729 else if (mg[pos] == '(')
3730 mg[pos] = '@';
3731 }
3732
3733 /* Return the central part of the mg[] array (corresponding to the
3734 * input eye graph).
3735 */
3736 k = 0;
3737 for (i = mini; i < mini + num_rows; i++) {
3738 for (j = minj; j < minj + maxwidth; j++) {
3739 if ((i < 0 || i >= board_size) && (j < 0 || j >= board_size))
3740 analyzed_eyegraph[k++] = '+';
3741 else if (i < 0 || i >= board_size)
3742 analyzed_eyegraph[k++] = '-';
3743 else if (j < 0 || j >= board_size)
3744 analyzed_eyegraph[k++] = '|';
3745 else
3746 analyzed_eyegraph[k++] = mg[POS(i, j)];
3747 }
3748 analyzed_eyegraph[k++] = '\n';
3749 }
3750 analyzed_eyegraph[k - 1] = 0;
3751
3752 return 1;
3753}
3754
3755
3756/*
3757 * Local Variables:
3758 * tab-width: 8
3759 * c-basic-offset: 2
3760 * End:
3761 */