9 #include "tactics/2lib.h"
10 #include "tactics/nlib.h"
11 #include "tactics/selfatari.h"
12 #include "tactics/goals.h"
16 group_nlib_defense_check(struct board
*b
, group_t group
, enum stone to_play
, struct libmap_mq
*q
, int tag
)
18 enum stone color
= to_play
;
19 assert(color
!= S_OFFBOARD
&& color
!= S_NONE
20 && color
== board_at(b
, group_base(group
)));
23 fprintf(stderr
, "[%s] nlib defense check of color %d\n",
24 coord2sstr(group
, b
), color
);
27 /* XXX: The code below is specific for 3-liberty groups. Its impact
28 * needs to be tested first, and possibly moved to a more appropriate
31 /* First, look at our liberties. */
32 int continuous
= 0, enemy
= 0, spacy
= 0, eyes
= 0;
33 for (int i
= 0; i
< 3; i
++) {
34 coord_t c
= board_group_info(b
, group
).lib
[i
];
35 eyes
+= board_is_one_point_eye(b
, c
, to_play
);
36 continuous
+= coord_is_adjecent(c
, board_group_info(b
, group
).lib
[(i
+ 1) % 3], b
);
37 enemy
+= neighbor_count_at(b
, c
, stone_other(color
));
38 spacy
+= immediate_liberty_count(b
, c
) > 1;
41 /* Safe groups are boring. */
45 /* If all our liberties are in single line and they are internal,
46 * this is likely a tiny three-point eyespace that we rather want
48 assert(continuous
< 3);
49 if (continuous
== 2 && !enemy
&& spacy
== 1) {
52 for (i
= 0; i
< 3; i
++)
53 if (immediate_liberty_count(b
, board_group_info(b
, group
).lib
[i
]) == 2)
55 /* Play at middle point. */
56 mq_add(q
, board_group_info(b
, group
).lib
[i
], tag
);
62 /* "Escaping" (gaining more liberties) with many-liberty group
63 * is difficult. Do not even try. */
65 /* There is another way to gain safety - through winning semeai
66 * with another group. */
67 /* We will not look at taking liberties of enemy n-groups, since
68 * we do not try to gain liberties for own n-groups. That would
69 * be really unbalanced (and most of our liberty-taking moves
70 * would be really stupid, most likely). */
72 /* However, it is possible that we must start capturing a 2-lib
73 * neighbor right now, because of approach liberties. Therefore,
74 * we will check for this case. If we take a liberty of a group
75 * even if we could have waited another move, no big harm done
78 foreach_in_group(b
, group
) {
79 foreach_neighbor(b
, c
, {
80 if (board_at(b
, c
) != stone_other(color
))
82 group_t g2
= group_at(b
, c
);
83 if (board_group_info(b
, g2
).libs
!= 2)
85 struct libmap_group lmg
;
87 lmg
.hash
= group_to_libmap(b
, group
);
89 can_atari_group(b
, g2
, stone_other(color
), to_play
, q
, tag
, lmg
, group_to_libmap(b
, g2
), true /* XXX */);
91 } foreach_in_group_end
;