Split libmap_hash to libmap_group array, create libmap_group slots only to pre-simula...
[pachi.git] / tactics / nlib.c
blob9cdc9fc27a9718c5b95cc05cdccf0a645698ed7b
1 #include <assert.h>
2 #include <stdio.h>
3 #include <stdlib.h>
5 #define DEBUG
6 #include "board.h"
7 #include "debug.h"
8 #include "mq.h"
9 #include "tactics/2lib.h"
10 #include "tactics/nlib.h"
11 #include "tactics/selfatari.h"
12 #include "tactics/goals.h"
15 void
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)));
22 if (DEBUGL(5))
23 fprintf(stderr, "[%s] nlib defense check of color %d\n",
24 coord2sstr(group, b), color);
26 #if 0
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
29 * place. */
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. */
42 if (eyes > 1)
43 return;
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
47 * to live at! */
48 assert(continuous < 3);
49 if (continuous == 2 && !enemy && spacy == 1) {
50 assert(!eyes);
51 int i;
52 for (i = 0; i < 3; i++)
53 if (immediate_liberty_count(b, board_group_info(b, group).lib[i]) == 2)
54 break;
55 /* Play at middle point. */
56 mq_add(q, board_group_info(b, group).lib[i], tag);
57 mq_nodup(q);
58 return;
60 #endif
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
76 * either. */
78 foreach_in_group(b, group) {
79 foreach_neighbor(b, c, {
80 if (board_at(b, c) != stone_other(color))
81 continue;
82 group_t g2 = group_at(b, c);
83 if (board_group_info(b, g2).libs != 2)
84 continue;
85 struct libmap_move_groupinfo lmgi;
86 lmgi.group = group;
87 lmgi.color = color;
88 lmgi.hash = group_to_libmap(b, group);
89 lmgi.goal = to_play;
90 can_atari_group(b, g2, stone_other(color), to_play, q, tag, lmgi, group_to_libmap(b, g2), true /* XXX */);
91 });
92 } foreach_in_group_end;