Change type of mercymin to 'int' to avoid gcc sign-compare warning.
[pachi/nmclean.git] / ownermap.c
blob906b5ed88aef0d8301df92c1e268af0de7369059
1 #include <assert.h>
2 #include <stdio.h>
3 #include <stdlib.h>
5 #include "board.h"
6 #include "debug.h"
7 #include "move.h"
8 #include "mq.h"
9 #include "ownermap.h"
12 void
13 board_ownermap_fill(struct board_ownermap *ownermap, struct board *b)
15 ownermap->playouts++;
16 foreach_point(b) {
17 enum stone color = board_at(b, c);
18 if (color == S_NONE)
19 color = board_get_one_point_eye(b, c);
20 ownermap->map[c][color]++;
21 } foreach_point_end;
24 void
25 board_ownermap_merge(int bsize2, struct board_ownermap *dst, struct board_ownermap *src)
27 dst->playouts += src->playouts;
28 for (int i = 0; i < bsize2; i++)
29 for (int j = 0; j < S_MAX; j++)
30 dst->map[i][j] += src->map[i][j];
33 enum point_judgement
34 board_ownermap_judge_point(struct board_ownermap *ownermap, coord_t c, floating_t thres)
36 assert(ownermap->map);
37 int n = ownermap->map[c][S_NONE];
38 int b = ownermap->map[c][S_BLACK];
39 int w = ownermap->map[c][S_WHITE];
40 int total = ownermap->playouts;
41 if (n >= total * thres)
42 return PJ_DAME;
43 else if (n + b >= total * thres)
44 return PJ_BLACK;
45 else if (n + w >= total * thres)
46 return PJ_WHITE;
47 else
48 return PJ_UNKNOWN;
51 void
52 board_ownermap_judge_groups(struct board *b, struct board_ownermap *ownermap, struct group_judgement *judge)
54 assert(ownermap->map);
55 assert(judge->gs);
56 memset(judge->gs, GS_NONE, board_size2(b) * sizeof(judge->gs[0]));
58 foreach_point(b) {
59 enum stone color = board_at(b, c);
60 group_t g = group_at(b, c);
61 if (!g) continue;
63 enum point_judgement pj = board_ownermap_judge_point(ownermap, c, judge->thres);
64 // assert(judge->gs[g] == GS_NONE || judge->gs[g] == pj);
65 if (pj == PJ_UNKNOWN) {
66 /* Fate is uncertain. */
67 judge->gs[g] = GS_UNKNOWN;
69 } else if (judge->gs[g] != GS_UNKNOWN) {
70 /* Update group state. */
71 enum gj_state new;
73 // Comparing enum types, casting (int) avoids compiler warnings
74 if ((int)pj == (int)color) {
75 new = GS_ALIVE;
76 } else if ((int)pj == (int)stone_other(color)) {
77 new = GS_DEAD;
78 } else { assert(pj == PJ_DAME);
79 /* Exotic! */
80 new = GS_UNKNOWN;
83 if (judge->gs[g] == GS_NONE) {
84 judge->gs[g] = new;
85 } else if (judge->gs[g] != new) {
86 /* Contradiction. :( */
87 judge->gs[g] = GS_UNKNOWN;
90 } foreach_point_end;
93 void
94 groups_of_status(struct board *b, struct group_judgement *judge, enum gj_state s, struct move_queue *mq)
96 foreach_point(b) { /* foreach_group, effectively */
97 group_t g = group_at(b, c);
98 if (!g || g != c) continue;
100 assert(judge->gs[g] != GS_NONE);
101 if (judge->gs[g] == s)
102 mq_add(mq, g, 0);
103 } foreach_point_end;