t-unit: display stats at the end
[pachi.git] / ownermap.c
bloba093529799aabb6b3364bf90c27f1cffca4ae2d4
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 float
34 board_ownermap_estimate_point(struct board_ownermap *ownermap, coord_t c)
36 assert(ownermap->map);
37 int b = ownermap->map[c][S_BLACK];
38 int w = ownermap->map[c][S_WHITE];
39 int total = ownermap->playouts;
40 return 1.0 * (b - w) / total;
43 enum point_judgement
44 board_ownermap_judge_point(struct board_ownermap *ownermap, coord_t c, floating_t thres)
46 assert(ownermap->map);
47 int n = ownermap->map[c][S_NONE];
48 int b = ownermap->map[c][S_BLACK];
49 int w = ownermap->map[c][S_WHITE];
50 int total = ownermap->playouts;
51 if (n >= total * thres)
52 return PJ_DAME;
53 else if (n + b >= total * thres)
54 return PJ_BLACK;
55 else if (n + w >= total * thres)
56 return PJ_WHITE;
57 else
58 return PJ_UNKNOWN;
61 void
62 board_ownermap_judge_groups(struct board *b, struct board_ownermap *ownermap, struct group_judgement *judge)
64 assert(ownermap->map);
65 assert(judge->gs);
66 memset(judge->gs, GS_NONE, board_size2(b) * sizeof(judge->gs[0]));
68 foreach_point(b) {
69 enum stone color = board_at(b, c);
70 group_t g = group_at(b, c);
71 if (!g) continue;
73 enum point_judgement pj = board_ownermap_judge_point(ownermap, c, judge->thres);
74 // assert(judge->gs[g] == GS_NONE || judge->gs[g] == pj);
75 if (pj == PJ_UNKNOWN) {
76 /* Fate is uncertain. */
77 judge->gs[g] = GS_UNKNOWN;
79 } else if (judge->gs[g] != GS_UNKNOWN) {
80 /* Update group state. */
81 enum gj_state new;
83 // Comparing enum types, casting (int) avoids compiler warnings
84 if ((int)pj == (int)color) {
85 new = GS_ALIVE;
86 } else if ((int)pj == (int)stone_other(color)) {
87 new = GS_DEAD;
88 } else { assert(pj == PJ_DAME);
89 /* Exotic! */
90 new = GS_UNKNOWN;
93 if (judge->gs[g] == GS_NONE) {
94 judge->gs[g] = new;
95 } else if (judge->gs[g] != new) {
96 /* Contradiction. :( */
97 judge->gs[g] = GS_UNKNOWN;
100 } foreach_point_end;
103 void
104 groups_of_status(struct board *b, struct group_judgement *judge, enum gj_state s, struct move_queue *mq)
106 foreach_point(b) { /* foreach_group, effectively */
107 group_t g = group_at(b, c);
108 if (!g || g != c) continue;
110 assert(judge->gs[g] != GS_NONE);
111 if (judge->gs[g] == s)
112 mq_add(mq, g, 0);
113 } foreach_point_end;