board_undo: define QUICK_BOARD_CODE to get compiler error with forbidden fields.
[pachi.git] / tactics / selfatari.c
blobb1aec1bd7dd165dfa9084b9425ae67182e89aefa
1 #include <assert.h>
2 #include <stdio.h>
3 #include <stdlib.h>
5 #define QUICK_BOARD_CODE
7 #define DEBUG
8 #include "board.h"
9 #include "debug.h"
10 #include "mq.h"
11 #include "random.h"
12 #include "tactics/1lib.h"
13 #include "tactics/selfatari.h"
14 #include "nakade.h"
17 struct selfatari_state {
18 int groupcts[S_MAX];
19 group_t groupids[S_MAX][4];
20 coord_t groupneis[S_MAX][4];
22 /* This is set if this move puts a group out of _all_
23 * liberties; we need to watch out for snapback then. */
24 bool friend_has_no_libs;
25 /* We may have one liberty, but be looking for one more.
26 * In that case, @needs_more_lib is id of group
27 * already providing one, don't consider it again. */
28 group_t needs_more_lib;
29 /* ID of the first liberty, providing it again is not
30 * interesting. */
31 coord_t needs_more_lib_except;
34 static bool
35 three_liberty_suicide(struct board *b, group_t g, enum stone color, coord_t to, struct selfatari_state *s)
37 /* If a group has three liberties, by playing on one of
38 * them it is possible to kill the group clumsily. Check
39 * against that condition: "After our move, the opponent
40 * can unconditionally capture the group."
42 * Examples:
44 * O O O O O O O X X O O O O O O v-v- ladder
45 * O X X X X X O . O X X X X X O . . . O O
46 * O X ! . ! X O . O X ! . ! O . O X X . O
47 * O X X X X X O # # # # # # # # O O O O O */
49 /* Extract the other two liberties. */
50 coord_t other_libs[2];
51 bool other_libs_adj[2];
52 for (int i = 0, j = 0; i < 3; i++) {
53 coord_t lib = board_group_info(b, g).lib[i];
54 if (lib != to) {
55 other_libs_adj[j] = coord_is_adjecent(lib, to, b);
56 other_libs[j++] = lib;
60 /* Make sure this move is not useful by gaining liberties,
61 * splitting the other two liberties (quite possibly splitting
62 * 3-eyespace!) or connecting to a different group. */
63 if (immediate_liberty_count(b, to) - (other_libs_adj[0] || other_libs_adj[1]) > 0)
64 return false;
65 assert(!(other_libs_adj[0] && other_libs_adj[1]));
66 if (s->groupcts[color] > 1)
67 return false;
69 /* Playing on the third liberty might be useful if it enables
70 * capturing some group (are we doing nakade or semeai?). */
71 for (int i = 0; i < s->groupcts[stone_other(color)]; i++)
72 if (board_group_info(b, s->groupids[stone_other(color)][i]).libs <= 3)
73 return false;
76 /* Okay. This looks like a pretty dangerous situation. The
77 * move looks useless, it definitely converts us to a 2-lib
78 * group. But we still want to play it e.g. if it takes off
79 * liberties of some unconspicous enemy group, and of course
80 * also at the game end to leave just single-point eyes. */
82 if (DEBUGL(6))
83 fprintf(stderr, "3-lib danger\n");
85 /* Therefore, the final suicidal test is: (After filling this
86 * liberty,) when opponent fills liberty [0], playing liberty
87 * [1] will not help the group, or vice versa. */
88 bool other_libs_neighbors = coord_is_adjecent(other_libs[0], other_libs[1], b);
89 for (int i = 0; i < 2; i++) {
90 int null_libs = other_libs_neighbors + other_libs_adj[i];
91 if (board_is_one_point_eye(b, other_libs[1 - i], color)) {
92 /* The other liberty is an eye, happily go ahead.
93 * There are of course situations where this will
94 * take off semeai liberties, but without this check,
95 * many terminal endgame plays will be messed up. */
96 return false;
98 if (immediate_liberty_count(b, other_libs[i]) - null_libs > 1) {
99 /* Gains liberties. */
100 /* TODO: Check for ladder! */
101 next_lib:
102 continue;
104 foreach_neighbor(b, other_libs[i], {
105 if (board_at(b, c) == color
106 && group_at(b, c) != g
107 && board_group_info(b, group_at(b, c)).libs > 1) {
108 /* Can connect to a friend. */
109 /* TODO: > 2? But maybe the group can capture
110 * a neighbor! But then better let it do that
111 * first? */
112 goto next_lib;
115 /* If we can capture a neighbor, better do it now
116 * before wasting a liberty. So no need to check. */
117 /* Ok, the last liberty has no way to get out. */
118 if (DEBUGL(6))
119 fprintf(stderr, "3-lib dangerous: %s\n", coord2sstr(other_libs[i], b));
120 return true;
123 return false;
126 static int
127 examine_friendly_groups(struct board *b, enum stone color, coord_t to, struct selfatari_state *s)
129 for (int i = 0; i < s->groupcts[color]; i++) {
130 /* We can escape by connecting to this group if it's
131 * not in atari. */
132 group_t g = s->groupids[color][i];
134 if (board_group_info(b, g).libs == 1) {
135 if (!s->needs_more_lib)
136 s->friend_has_no_libs = true;
137 // or we already have a friend with 1 lib
138 continue;
141 /* Could we self-atari the group here? */
142 if (board_group_info(b, g).libs > 2) {
143 if (board_group_info(b, g).libs == 3
144 && three_liberty_suicide(b, g, color, to, s))
145 return true;
146 return false;
149 /* We need to have another liberty, and
150 * it must not be the other liberty of
151 * the group. */
152 int lib2 = board_group_other_lib(b, g, to);
153 /* Maybe we already looked at another
154 * group providing one liberty? */
155 if (s->needs_more_lib && s->needs_more_lib != g
156 && s->needs_more_lib_except != lib2)
157 return false;
159 /* Can we get the liberty locally? */
160 /* Yes if we are route to more liberties... */
161 if (s->groupcts[S_NONE] > 1)
162 return false;
163 /* ...or one liberty, but not lib2. */
164 if (s->groupcts[S_NONE] > 0
165 && !coord_is_adjecent(lib2, to, b))
166 return false;
168 /* ...ok, then we can still contribute a liberty
169 * later by capturing something. */
170 s->needs_more_lib = g;
171 s->needs_more_lib_except = lib2;
172 s->friend_has_no_libs = false;
175 return -1;
178 static int
179 examine_enemy_groups(struct board *b, enum stone color, coord_t to, struct selfatari_state *s)
181 /* We may be able to gain a liberty by capturing this group. */
182 group_t can_capture = 0;
184 /* Examine enemy groups: */
185 for (int i = 0; i < s->groupcts[stone_other(color)]; i++) {
186 /* We can escape by capturing this group if it's in atari. */
187 group_t g = s->groupids[stone_other(color)][i];
188 if (board_group_info(b, g).libs > 1)
189 continue;
191 /* But we need to get to at least two liberties by this;
192 * we already have one outside liberty, or the group is
193 * more than 1 stone (in that case, capturing is always
194 * nice!). */
195 if (s->groupcts[S_NONE] > 0 || !group_is_onestone(b, g))
196 return false;
197 /* ...or, it's a ko stone, */
198 if (neighbor_count_at(b, g, color) + neighbor_count_at(b, g, S_OFFBOARD) == 3) {
199 /* and we don't have a group to save: then, just taking
200 * single stone means snapback! */
201 if (!s->friend_has_no_libs)
202 return false;
204 /* ...or, we already have one indirect liberty provided
205 * by another group. */
206 if (s->needs_more_lib || (can_capture && can_capture != g))
207 return false;
208 can_capture = g;
212 if (DEBUGL(6))
213 fprintf(stderr, "no cap group\n");
215 if (!s->needs_more_lib && !can_capture && !s->groupcts[S_NONE]) {
216 /* We have no hope for more fancy tactics - this move is simply
217 * a suicide, not even a self-atari. */
218 if (DEBUGL(6))
219 fprintf(stderr, "suicide\n");
220 return true;
222 /* XXX: I wonder if it makes sense to continue if we actually
223 * just !s->needs_more_lib. */
225 return -1;
228 static inline bool
229 is_neighbor_group(struct board *b, enum stone color, group_t g, struct selfatari_state *s)
231 for (int i = 0; i < s->groupcts[color]; i++)
232 if (g == s->groupids[color][i])
233 return true;
234 return false;
238 /* Instead of playing this self-atari, could we have connected/escaped by
239 * playing on the other liberty of a neighboring group ?
240 * Or there's a strong enemy group there (only checked if @check_enemy is set)
242 static inline bool
243 is_bad_nakade(struct board *b, enum stone color, coord_t to, coord_t lib2,
244 bool check_enemy, struct selfatari_state *s)
246 /* Let's look at neighbors of the other liberty: */
247 foreach_neighbor(b, lib2, {
248 /* If the other liberty has empty neighbor,
249 * it must be the original liberty; otherwise,
250 * since the whole group has only 2 liberties,
251 * the other liberty may not be internal and
252 * we are nakade'ing eyeless group from outside,
253 * which is stupid. */
254 if (board_at(b, c) == S_NONE) {
255 if (c == to)
256 continue;
257 else
258 return true;
259 }});
262 /* Let's look at neighbors of the other liberty: */
263 foreach_neighbor(b, lib2, {
264 if (board_at(b, c) != color)
265 continue;
267 group_t g2 = group_at(b, c);
268 /* Looking for a group we don't know about */
269 if (is_neighbor_group(b, color, g2, s))
270 continue;
272 /* Should connect these groups instead of self-atari
273 * on the other side. */
274 if (board_at(b, c) == color)
275 return true;
278 /* FIXME Do we really need this ? */
279 if (!check_enemy)
280 continue;
282 /* The neighbor is enemy color. It's ok if this is its
283 * only liberty or it's one of our neighbor groups. */
284 if (board_group_info(b, g2).libs == 1)
285 continue;
286 if (board_group_info(b, g2).libs == 2
287 && (board_group_info(b, g2).lib[0] == to
288 || board_group_info(b, g2).lib[1] == to))
289 continue;
291 /* Stronger enemy group. No nakade. */
292 return true;
294 return false;
297 /* Instead of playing this self-atari, could we have connected/escaped by
298 * playing on the other liberty of a neighboring group ? */
299 static inline bool
300 can_escape_instead(struct board *b, enum stone color, coord_t to, struct selfatari_state *s)
302 for (int i = 0; i < s->groupcts[color]; i++) {
303 group_t g = s->groupids[color][i];
304 if (board_group_info(b, g).libs != 2)
305 continue;
306 coord_t other = board_group_other_lib(b, g, to);
308 /* Let's look at the other liberty of that group. */
309 if (immediate_liberty_count(b, other) >= 2 || /* Can escape ! */
310 is_bad_nakade(b, color, to, other, false, s)) /* Should connect instead */
311 return true;
313 return false;
316 static inline bool
317 unreachable_lib_from_neighbors(struct board *b, enum stone color, coord_t to, struct selfatari_state *s,
318 coord_t lib)
320 for (int i = 0; i < s->groupcts[color]; i++) {
321 group_t g = s->groupids[color][i];
322 for (int j = 0; j < board_group_info(b, g).libs; j++)
323 if (board_group_info(b, g).lib[j] == lib)
324 return false;
326 return true;
329 /* This only looks at existing empty spots, not captures */
330 static inline bool
331 capture_would_make_extra_eye(struct board *b, enum stone color, coord_t to, struct selfatari_state *s)
333 foreach_neighbor(b, to, {
334 if (board_at(b, c) == S_NONE)
335 if (unreachable_lib_from_neighbors(b, color, to, s, c))
336 return true;
338 return false;
341 static bool
342 nakade_making_dead_shape(struct board *b, enum stone color, coord_t to, struct selfatari_state *s,
343 bool atariing_group, int stones)
345 int r;
346 struct move m;
347 group_t g;
348 int cap_would_make_eye = false;
349 struct board b2;
351 if (!stones)
352 return false;
353 assert(stones != 1);
354 assert(stones <= 5);
356 /* If not atariing surrounding group it's a good move if:
357 * - Shape after capturing us is dead AND
358 * - Oponent gets extra eye if he plays first OR
359 * - would create living shape
361 * If atariing surrounding group we only care about dead shape. */
363 if (!atariing_group)
364 cap_would_make_eye = capture_would_make_extra_eye(b, color, to, s);
365 /* TODO: If there's so much eye space that even with filling + capture
366 * opponent still makes an extra eye it's a silly move. */
368 /* Can oponent make living shape if we don't play ?
369 * (don't bother killing stuff that's already dead...) */
370 do if (!atariing_group && !cap_would_make_eye && s->groupcts[color] == 1)
372 board_copy(&b2, b);
374 /* Play opponent color where we want to play */
375 m.coord = to;
376 m.color = stone_other(color);
377 if (board_play(&b2, &m) == -1) /* Illegal move (eye ...) */
378 { board_done_noalloc(&b2); break; }
380 /* Had 2 libs ? One more move to capture us then */
381 if (neighbor_count_at(b, to, color) == neighbor_count_at(&b2, to, color)) {
382 group_t standing = -1;
383 foreach_neighbor(&b2, to, {
384 g = group_at(&b2, c);
385 if (board_at(&b2, c) == color) {
386 assert(board_group_info(&b2, g).libs == 1); /* Should be in atari */
387 standing = g;
390 assert(standing != -1);
392 m.coord = board_group_info(&b2, standing).lib[0];
393 r = board_play(&b2, &m); assert(r != -1);
396 /* Empty now since it's been captured */
397 coord_t empty = group_base(s->groupids[color][0]);
398 int would_live = !nakade_dead_shape(&b2, empty, stone_other(color));
399 board_done_noalloc(&b2);
400 if (!would_live) /* And !cap_would_make_eye here */
401 return false; /* Bad nakade */
402 } while (0);
404 board_copy(&b2, b);
406 /* Play self-atari */
407 m.coord = to;
408 m.color = color;
409 r = board_play(&b2, &m); assert(r != -1);
411 /* Play capture */
412 g = group_at(&b2, to);
413 m.coord = board_group_info(&b2, g).lib[0];
414 m.color = stone_other(color);
415 r = board_play(&b2, &m); assert(r != -1);
417 int dead_shape = nakade_dead_shape(&b2, to, stone_other(color));
418 board_done_noalloc(&b2);
419 return dead_shape;
423 /* More complex throw-in, or in-progress capture from
424 * the inside - we are in one of several situations:
425 * a O O O O X b O O O X c O O O X d O O O O O
426 * O . X . O O X . . O . X . O . X . O
427 * # # # # # # # # # # # # # # # # # #
428 * Throw-ins have been taken care of in check_throwin(),
429 * so it's either b or d now:
430 * - b is desirable here (since maybe O has no backup two eyes)
431 * - d is desirable if putting group in atari (otherwise we
432 * would never capture a single-eyed group). */
433 #define check_throw_in_or_inside_capture(b, color, to, s, capturing) \
434 if (s->groupcts[color] == 1 && group_is_onestone(b, s->groupids[color][0])) { \
435 group_t g2 = s->groupids[color][0]; \
436 assert(board_group_info(b, g2).libs <= 2); \
437 if (board_group_info(b, g2).libs == 1) \
438 return false; /* b */ \
439 return !capturing; \
443 static int
444 setup_nakade_or_snapback(struct board *b, enum stone color, coord_t to, struct selfatari_state *s)
446 /* There is another possibility - we can self-atari if it is
447 * a nakade: we put an enemy group in atari from the inside. */
448 /* This branch also allows eyes falsification:
449 * O O O . . (This is different from throw-in to false eye
450 * X X O O . checked below in that there is no X stone at the
451 * X . X O . right of the star point in this diagram.)
452 * X X X O O
453 * X O * . . */
454 /* We also allow to only nakade if the created shape is dead
455 * (http://senseis.xmp.net/?Nakade). */
457 /* This branch also covers snapback, which is kind of special
458 * nakade case. ;-) */
459 /* FIXME looks like check_throwin() does it actually. */
461 /* Look at the enemy groups and determine the other contended
462 * liberty. We must make sure the liberty:
463 * (i) is an internal liberty
464 * (ii) filling it to capture our group will not gain safety */
465 coord_t lib2 = pass;
466 for (int i = 0; i < s->groupcts[stone_other(color)]; i++) {
467 group_t g = s->groupids[stone_other(color)][i];
468 if (board_group_info(b, g).libs != 2)
469 continue;
471 coord_t this_lib2 = board_group_other_lib(b, g, to);
472 if (is_pass(lib2))
473 lib2 = this_lib2;
474 else if (this_lib2 != lib2) {
475 /* If we have two neighboring groups that do
476 * not share the other liberty, this for sure
477 * is not a good nakade. */
478 return -1;
481 if (is_pass(lib2)) {
482 /* Not putting any group in atari.
483 * Could be creating dead shape though */
485 /* Before checking if it's a useful nakade
486 * make sure it can't connect out ! */
487 if (can_escape_instead(b, color, to, s))
488 return -1;
490 check_throw_in_or_inside_capture(b, color, to, s, false);
492 int stones = 0;
493 for (int j = 0; j < s->groupcts[color]; j++) {
494 group_t g2 = s->groupids[color][j];
495 stones += group_stone_count(b, g2, 6);
496 if (stones > 5)
497 return true;
500 return (nakade_making_dead_shape(b, color, to, s, false, stones) ? false : -1);
503 /* Let's look at neighbors of the other liberty: */
504 if (is_bad_nakade(b, color, to, lib2, true, s) ||
505 can_escape_instead(b, color, to, s))
506 return -1;
508 /* Now, we must distinguish between nakade and eye
509 * falsification; moreover, we must not falsify an eye
510 * by more than two stones. */
512 if (s->groupcts[color] < 1)
513 return false; /* Simple throw-in, an easy case */
515 check_throw_in_or_inside_capture(b, color, to, s, true);
517 /* We would create more than 2-stone group; in that
518 * case, the liberty of our result must be lib2,
519 * indicating this really is a nakade. */
520 int stones = 0;
521 for (int j = 0; j < s->groupcts[color]; j++) {
522 group_t g2 = s->groupids[color][j];
523 assert(board_group_info(b, g2).libs <= 2);
524 if (board_group_info(b, g2).libs == 2) {
525 if (board_group_info(b, g2).lib[0] != lib2
526 && board_group_info(b, g2).lib[1] != lib2)
527 return -1;
528 } else
529 assert(board_group_info(b, g2).lib[0] == to);
530 /* See below: */
531 stones += group_stone_count(b, g2, 6);
532 if (stones > 5)
533 return true;
536 return !nakade_making_dead_shape(b, color, to, s, true, stones);
539 #if 0
540 /* Fast but there are issues with this (triangle six is not dead !)
541 * We also need to know status if opponent plays first */
542 static inline int
543 nakade_making_dead_shape_hack(struct board *b, enum stone color, coord_t to, int lib2,
544 struct selfatari_state *s, int stones)
546 /* It also remains to be seen whether it is nakade
547 * and not seki destruction. To do this properly, we
548 * would have to look at the group shape. But we can
549 * cheat too! Brett Combs helps to introduce a static
550 * rule that should in fact cover *all* cases:
551 * 1. Total number of pre-selfatari nakade stones must
552 * be 5 or smaller. (See above for that.)
553 * 2. If the selfatari is 8-touching all nakade stones,
554 * it is proper nakade.
555 * 3. Otherwise, there must be only a single nakade
556 * group, it must be at least 4-stone and its other
557 * liberty must be 8-touching the same number of
558 * stones as us. */
559 int touch8 = neighbor_count_at(b, to, color);
560 foreach_diag_neighbor(b, to) {
561 if (board_at(b, c) != color) continue;
562 /* Consider only internal stones. Otherwise, e.g.
563 * X O . X
564 * X . O X can make trouble, bottom O is
565 * O X X X irrelevant. */
566 if (board_group_info(b, group_at(b, c)).lib[0] == to
567 || board_group_info(b, group_at(b, c)).lib[1] == to)
568 touch8++;
569 } foreach_diag_neighbor_end;
570 if (touch8 == stones)
571 return true;
573 if (s->groupcts[color] > 1)
574 return false;
575 if (stones == 3) // 4 stones and self-atari not 8-connected to all of them -> living shape
576 return false;
577 if (stones < 3) // always dead shape
578 return true;
580 int ltouch8 = neighbor_count_at(b, lib2, color);
581 foreach_diag_neighbor(b, lib2) {
582 if (board_at(b, c) != color) continue;
583 if (board_group_info(b, group_at(b, c)).lib[0] == to
584 || board_group_info(b, group_at(b, c)).lib[1] == to)
585 ltouch8++;
586 } foreach_diag_neighbor_end;
587 return ltouch8 == touch8;
589 #endif
592 static int
593 check_throwin(struct board *b, enum stone color, coord_t to, struct selfatari_state *s)
595 /* We can be throwing-in to false eye:
596 * X X X O X X X O X X X X X
597 * X . * X * O . X * O O . X
598 * # # # # # # # # # # # # # */
599 /* We cannot sensibly throw-in into a corner. */
600 if (neighbor_count_at(b, to, S_OFFBOARD) < 2
601 && neighbor_count_at(b, to, stone_other(color))
602 + neighbor_count_at(b, to, S_OFFBOARD) == 3
603 && board_is_false_eyelike(b, to, stone_other(color))) {
604 assert(s->groupcts[color] <= 1);
605 /* Single-stone throw-in may be ok... */
606 if (s->groupcts[color] == 0) {
607 /* O X . There is one problem - when it's
608 * . * X actually not a throw-in!
609 * # # # */
610 foreach_neighbor(b, to, {
611 if (board_at(b, c) == S_NONE) {
612 /* Is the empty neighbor an escape path? */
613 /* (Note that one S_NONE neighbor is already @to.) */
614 if (neighbor_count_at(b, c, stone_other(color))
615 + neighbor_count_at(b, c, S_OFFBOARD) < 2)
616 return -1;
619 return false;
622 /* Multi-stone throwin...? */
623 assert(s->groupcts[color] == 1);
624 group_t g = s->groupids[color][0];
626 assert(board_group_info(b, g).libs <= 2);
627 /* Suicide is definitely NOT ok, no matter what else
628 * we could test. */
629 if (board_group_info(b, g).libs == 1)
630 return true;
632 /* In that case, we must be connected to at most one stone,
633 * or throwin will not destroy any eyes. */
634 if (group_is_onestone(b, g))
635 return false;
637 return -1;
640 bool
641 is_bad_selfatari_slow(struct board *b, enum stone color, coord_t to)
643 if (DEBUGL(5))
644 fprintf(stderr, "sar check %s %s\n", stone2str(color), coord2sstr(to, b));
645 /* Assess if we actually gain any liberties by this escape route.
646 * Note that this is not 100% as we cannot check whether we are
647 * connecting out or just to ourselves. */
649 struct selfatari_state s;
650 memset(&s, 0, sizeof(s));
651 int d;
653 foreach_neighbor(b, to, {
654 enum stone color = board_at(b, c);
655 group_t group = group_at(b, c);
656 bool dup = false;
657 for (int i = 0; i < s.groupcts[color]; i++)
658 if (s.groupids[color][i] == group) {
659 dup = true;
660 break;
662 if (!dup) {
663 s.groupneis[color][s.groupcts[color]] = c;
664 s.groupids[color][s.groupcts[color]++] = group_at(b, c);
668 /* We have shortage of liberties; that's the point. */
669 assert(s.groupcts[S_NONE] <= 1);
671 d = examine_friendly_groups(b, color, to, &s);
672 if (d >= 0)
673 return d;
674 if (DEBUGL(6))
675 fprintf(stderr, "no friendly group\n");
677 d = examine_enemy_groups(b, color, to, &s);
678 if (d >= 0)
679 return d;
680 if (DEBUGL(6))
681 fprintf(stderr, "no capture\n");
683 d = check_throwin(b, color, to, &s);
684 if (d >= 0)
685 return d;
687 if (DEBUGL(6))
688 fprintf(stderr, "no throw-in group\n");
690 d = setup_nakade_or_snapback(b, color, to, &s);
691 if (d >= 0)
692 return d;
693 if (DEBUGL(6))
694 fprintf(stderr, "no nakade group\n");
697 /* No way to pull out, no way to connect out. This really
698 * is a bad self-atari! */
699 return true;
703 coord_t
704 selfatari_cousin(struct board *b, enum stone color, coord_t coord, group_t *bygroup)
706 group_t groups[4]; int groups_n = 0;
707 int groupsbycolor[4] = {0, 0, 0, 0};
708 if (DEBUGL(6))
709 fprintf(stderr, "cousin group search: ");
710 foreach_neighbor(b, coord, {
711 enum stone s = board_at(b, c);
712 group_t g = group_at(b, c);
713 if (board_group_info(b, g).libs == 2) {
714 groups[groups_n++] = g;
715 groupsbycolor[s]++;
716 if (DEBUGL(6))
717 fprintf(stderr, "%s(%s) ", coord2sstr(c, b), stone2str(s));
720 if (DEBUGL(6))
721 fprintf(stderr, "\n");
723 if (!groups_n)
724 return pass;
726 int gn;
727 if (groupsbycolor[stone_other(color)]) {
728 /* Prefer to fill the other liberty of an opponent
729 * group to filling own approach liberties. */
730 int gl = fast_random(groups_n);
731 for (gn = gl; gn < groups_n; gn++)
732 if (board_at(b, groups[gn]) == stone_other(color))
733 goto found;
734 for (gn = 0; gn < gl; gn++)
735 if (board_at(b, groups[gn]) == stone_other(color))
736 goto found;
737 found:;
738 } else {
739 gn = fast_random(groups_n);
741 int gl = gn;
742 for (; gn - gl < groups_n; gn++) {
743 int gnm = gn % groups_n;
744 group_t group = groups[gnm];
746 coord_t lib2;
747 /* Can we get liberties by capturing a neighbor? */
748 struct move_queue ccq; ccq.moves = 0;
749 if (can_countercapture(b, color, group, color, &ccq, 0)) {
750 lib2 = mq_pick(&ccq);
752 } else {
753 lib2 = board_group_other_lib(b, group, coord);
754 if (board_is_one_point_eye(b, lib2, board_at(b, group)))
755 continue;
756 if (is_bad_selfatari(b, color, lib2))
757 continue;
759 if (bygroup)
760 *bygroup = group;
761 return lib2;
763 return pass;