Avoid memory leak in uct_genmoves().
[pachi/derm.git] / ownermap.c
blob81665814702e9a1b42c7a101cc39020d1e85ccc7
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, float 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_group(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 if (pj == PJ_UNKNOWN) {
65 /* Fate is uncertain. */
66 judge->gs[g] = GS_UNKNOWN;
68 } else if (judge->gs[g] != GS_UNKNOWN) {
69 /* Update group state. */
70 enum gj_state new;
71 if (pj == color) {
72 new = GS_ALIVE;
73 } else if (pj == stone_other(color)) {
74 new = GS_DEAD;
75 } else { assert(pj == PJ_DAME);
76 /* Exotic! */
77 new = GS_UNKNOWN;
80 if (judge->gs[g] == GS_NONE) {
81 judge->gs[g] = new;
82 } else if (judge->gs[g] != new) {
83 /* Contradiction. :( */
84 judge->gs[g] = GS_UNKNOWN;
87 } foreach_point_end;
90 void
91 groups_of_status(struct board *b, struct group_judgement *judge, enum gj_state s, struct move_queue *mq)
93 foreach_point(b) { /* foreach_group, effectively */
94 group_t g = group_at(b, c);
95 if (!g || g != c) continue;
97 assert(judge->gs[g] != GS_NONE);
98 if (judge->gs[g] == s)
99 mq_add(mq, g);
100 } foreach_point_end;