12 printhook(struct board
*board
, coord_t c
, char *s
, char *end
, void *data
)
14 struct board_ownermap
*ownermap
= data
;
19 const char chr
[] = ":XO,"; // dame, black, white, unclear
20 const char chm
[] = ":xo,";
21 char ch
= chr
[board_ownermap_judge_point(ownermap
, c
, GJ_THRES
)];
22 if (ch
== ',') { // less precise estimate then?
23 ch
= chm
[board_ownermap_judge_point(ownermap
, c
, 0.67)];
25 s
+= snprintf(s
, end
- s
, "%c ", ch
);
30 board_print_ownermap(struct board
*b
, FILE *f
, struct board_ownermap
*ownermap
)
32 board_print_custom(b
, stderr
, printhook
, ownermap
);
36 board_ownermap_fill(struct board_ownermap
*ownermap
, struct board
*b
)
40 enum stone color
= board_at(b
, c
);
42 color
= board_get_one_point_eye(b
, c
);
43 ownermap
->map
[c
][color
]++;
48 board_ownermap_merge(int bsize2
, struct board_ownermap
*dst
, struct board_ownermap
*src
)
50 dst
->playouts
+= src
->playouts
;
51 for (int i
= 0; i
< bsize2
; i
++)
52 for (int j
= 0; j
< S_MAX
; j
++)
53 dst
->map
[i
][j
] += src
->map
[i
][j
];
57 board_ownermap_estimate_point(struct board_ownermap
*ownermap
, coord_t c
)
59 assert(ownermap
->map
);
60 int b
= ownermap
->map
[c
][S_BLACK
];
61 int w
= ownermap
->map
[c
][S_WHITE
];
62 int total
= ownermap
->playouts
;
63 return 1.0 * (b
- w
) / total
;
67 board_ownermap_judge_point(struct board_ownermap
*ownermap
, coord_t c
, floating_t thres
)
69 assert(ownermap
->map
);
70 int n
= ownermap
->map
[c
][S_NONE
];
71 int b
= ownermap
->map
[c
][S_BLACK
];
72 int w
= ownermap
->map
[c
][S_WHITE
];
73 int total
= ownermap
->playouts
;
74 if (n
>= total
* thres
)
76 else if (n
+ b
>= total
* thres
)
78 else if (n
+ w
>= total
* thres
)
85 board_ownermap_judge_groups(struct board
*b
, struct board_ownermap
*ownermap
, struct group_judgement
*judge
)
87 assert(ownermap
->map
);
89 memset(judge
->gs
, GS_NONE
, board_size2(b
) * sizeof(judge
->gs
[0]));
92 enum stone color
= board_at(b
, c
);
93 group_t g
= group_at(b
, c
);
96 enum point_judgement pj
= board_ownermap_judge_point(ownermap
, c
, judge
->thres
);
97 // assert(judge->gs[g] == GS_NONE || judge->gs[g] == pj);
98 if (pj
== PJ_UNKNOWN
) {
99 /* Fate is uncertain. */
100 judge
->gs
[g
] = GS_UNKNOWN
;
102 } else if (judge
->gs
[g
] != GS_UNKNOWN
) {
103 /* Update group state. */
106 // Comparing enum types, casting (int) avoids compiler warnings
107 if ((int)pj
== (int)color
) {
109 } else if ((int)pj
== (int)stone_other(color
)) {
111 } else { assert(pj
== PJ_DAME
);
116 if (judge
->gs
[g
] == GS_NONE
) {
118 } else if (judge
->gs
[g
] != new) {
119 /* Contradiction. :( */
120 judge
->gs
[g
] = GS_UNKNOWN
;
127 groups_of_status(struct board
*b
, struct group_judgement
*judge
, enum gj_state s
, struct move_queue
*mq
)
129 foreach_point(b
) { /* foreach_group, effectively */
130 group_t g
= group_at(b
, c
);
131 if (!g
|| g
!= c
) continue;
133 assert(judge
->gs
[g
] != GS_NONE
);
134 if (judge
->gs
[g
] == s
)