15 /* Whether to set global debug level to the same as the playout
16 * has, in case it is different. This can make sure e.g. tactical
17 * reading produces proper level of debug prints during simulations.
18 * But it is safe to enable this only in single-threaded instances! */
19 //#define DEBUGL_BY_PLAYOUT
21 #define PLDEBUGL(n) DEBUGL_(policy->debug_level, n)
25 play_random_move(struct playout_setup
*setup
,
26 struct board
*b
, enum stone color
,
27 struct playout_policy
*policy
)
31 if (setup
->prepolicy_hook
) {
32 coord
= setup
->prepolicy_hook(policy
, setup
, b
, color
);
33 // fprintf(stderr, "prehook: %s\n", coord2sstr(coord, b));
37 coord
= policy
->choose(policy
, setup
, b
, color
);
38 // fprintf(stderr, "policy: %s\n", coord2sstr(coord, b));
41 if (is_pass(coord
) && setup
->postpolicy_hook
) {
42 coord
= setup
->postpolicy_hook(policy
, setup
, b
, color
);
43 // fprintf(stderr, "posthook: %s\n", coord2sstr(coord, b));
48 /* Defer to uniformly random move choice. */
49 /* This must never happen if the policy is tracking
50 * internal board state, obviously. */
51 assert(!policy
->setboard
|| policy
->setboard_randomok
);
52 board_play_random(b
, color
, &coord
, (ppr_permit
) policy
->permit
, policy
);
56 m
.coord
= coord
; m
.color
= color
;
57 if (board_play(b
, &m
) < 0) {
59 fprintf(stderr
, "Pre-picked move %d,%d is ILLEGAL:\n",
60 coord_x(coord
, b
), coord_y(coord
, b
));
61 board_print(b
, stderr
);
71 play_random_game(struct playout_setup
*setup
,
72 struct board
*b
, enum stone starting_color
,
73 struct playout_amafmap
*amafmap
,
74 struct board_ownermap
*ownermap
,
75 struct playout_policy
*policy
)
77 assert(setup
&& policy
);
79 int gamelen
= setup
->gamelen
- b
->moves
;
82 policy
->setboard(policy
, b
);
83 #ifdef DEBUGL_BY_PLAYOUT
84 int debug_level_orig
= debug_level
;
85 debug_level
= policy
->debug_level
;
88 enum stone color
= starting_color
;
90 int passes
= is_pass(b
->last_move
.coord
) && b
->moves
> 0;
92 while (gamelen
-- && passes
< 2) {
93 coord_t coord
= play_random_move(setup
, b
, color
, policy
);
96 /* For UCT, superko test here is downright harmful since
97 * in superko-likely situation we throw away literally
98 * 95% of our playouts; UCT will deal with this fine by
100 if (unlikely(b
->superko_violation
)) {
101 /* We ignore superko violations that are suicides. These
102 * are common only at the end of the game and are
103 * rather harmless. (They will not go through as a root
105 if (group_at(b
, coord
)) {
107 fprintf(stderr
, "Superko fun at %d,%d in\n", coord_x(coord
, b
), coord_y(coord
, b
));
109 board_print(b
, stderr
);
114 fprintf(stderr
, "Ignoring superko at %d,%d in\n", coord_x(coord
, b
), coord_y(coord
, b
));
115 board_print(b
, stderr
);
117 b
->superko_violation
= false;
123 fprintf(stderr
, "%s %s\n", stone2str(color
), coord2sstr(coord
, b
));
125 board_print(b
, stderr
);
128 if (unlikely(is_pass(coord
))) {
134 assert(amafmap
->gamelen
< MAX_GAMELEN
);
135 amafmap
->is_ko_capture
[amafmap
->gamelen
] = board_playing_ko_threat(b
);
136 amafmap
->game
[amafmap
->gamelen
++] = coord
;
139 if (setup
->mercymin
&& abs(b
->captures
[S_BLACK
] - b
->captures
[S_WHITE
]) > setup
->mercymin
)
142 color
= stone_other(color
);
145 floating_t score
= board_fast_score(b
);
146 int result
= (starting_color
== S_WHITE
? score
* 2 : - (score
* 2));
149 fprintf(stderr
, "Random playout result: %d (W %f)\n", result
, score
);
151 board_print(b
, stderr
);
155 board_ownermap_fill(ownermap
, b
);
160 #ifdef DEBUGL_BY_PLAYOUT
161 debug_level
= debug_level_orig
;