11 #include "joseki/base.h"
12 #include "playout/light.h"
13 #include "playout/moggy.h"
14 #include "replay/replay.h"
16 /* Internal engine state. */
21 struct joseki_dict
*jdict
;
22 struct playout_policy
*playout
;
26 suicide_stats(int suicide
)
29 static int suicides
= 0;
30 if (suicide
) suicides
++;
31 if (++total
% 100 == 0)
32 fprintf(stderr
, "Suicides: %i/%i (%i%%)\n", suicides
, total
, suicides
* 100 / total
);
36 replay_sample_moves(struct engine
*e
, struct board
*b
, enum stone color
,
37 int *played
, int *pmost_played
)
39 struct replay
*r
= e
->data
;
40 struct playout_setup setup
; memset(&setup
, 0, sizeof(setup
));
41 struct move m
= { .coord
= pass
, .color
= color
};
44 /* Find out what moves policy plays most in this situation */
45 for (int i
= 0; i
< r
->runs
; i
++) {
49 if (DEBUGL(4)) fprintf(stderr
, "---------------------------------\n");
50 coord_t c
= play_random_move(&setup
, &b2
, color
, r
->playout
);
51 if (DEBUGL(4)) fprintf(stderr
, "-> %s\n", coord2sstr(c
, &b2
));
54 if (played
[c
] > most_played
) {
55 most_played
++; m
.coord
= c
;
58 board_done_noalloc(&b2
);
61 *pmost_played
= most_played
;
66 replay_genmove(struct engine
*e
, struct board
*b
, struct time_info
*ti
, enum stone color
, bool pass_all_alive
)
68 struct replay
*r
= e
->data
;
69 struct move m
= { .coord
= pass
, .color
= color
};
72 printf("genmove: %s to play. Sampling moves (%i runs)\n", stone2str(color
), r
->runs
);
74 int played_
[b
->size2
+ 2]; memset(played_
, 0, sizeof(played_
));
75 int *played
= played_
+ 2; // allow storing pass/resign
77 m
.coord
= replay_sample_moves(e
, b
, color
, played
, &most_played
);
79 if (DEBUGL(3)) { /* Show moves stats */
80 for (int k
= most_played
; k
> 0; k
--)
81 for (coord_t c
= resign
; c
< b
->size2
; c
++)
83 fprintf(stderr
, "%3s: %.2f%%\n", coord2str(c
, b
), (float)k
* 100 / r
->runs
);
84 fprintf(stderr
, "\n");
88 fprintf(stderr
, "genmove: %s %s %.2f%% (%i runs)\n\n",
89 (color
== S_BLACK
? "B" : "W"),
90 coord2str(m
.coord
, b
), (float)most_played
* 100 / r
->runs
, r
->runs
);
92 if (r
->no_suicide
) { /* Check group suicides */
93 struct board b2
; board_copy(&b2
, b
);
94 int res
= board_play(&b2
, &m
); assert(res
>= 0);
95 int suicide
= !group_at(&b2
, m
.coord
);
96 board_done_noalloc(&b2
);
98 suicide_stats(suicide
);
101 fprintf(stderr
, "EEEK, group suicide, will pass instead !\n");
102 /* XXX: We should check for non-suicide alternatives. */
103 return coord_copy(pass
);
107 return coord_copy(m
.coord
);
111 replay_done(struct engine
*e
)
113 struct replay
*r
= e
->data
;
114 playout_policy_done(r
->playout
);
115 joseki_done(r
->jdict
);
119 replay_state_init(char *arg
, struct board
*b
)
121 struct replay
*r
= calloc2(1, sizeof(struct replay
));
126 r
->jdict
= joseki_load(b
->size
);
129 char *optspec
, *next
= arg
;
132 next
+= strcspn(next
, ",");
133 if (*next
) { *next
++ = 0; } else { *next
= 0; }
135 char *optname
= optspec
;
136 char *optval
= strchr(optspec
, '=');
137 if (optval
) *optval
++ = 0;
139 if (!strcasecmp(optname
, "debug")) {
141 r
->debug_level
= atoi(optval
);
144 } else if (!strcasecmp(optname
, "runs") && optval
) {
145 /* runs=n set number of playout runs to sample.
146 * use runs=1 for raw playout policy */
147 r
->runs
= atoi(optval
);
148 } else if (!strcasecmp(optname
, "no_suicide")) {
149 /* ensure engine doesn't allow group suicides
150 * (off by default) */
152 } else if (!strcasecmp(optname
, "playout") && optval
) {
153 char *playoutarg
= strchr(optval
, ':');
156 if (!strcasecmp(optval
, "moggy")) {
157 r
->playout
= playout_moggy_init(playoutarg
, b
, r
->jdict
);
158 } else if (!strcasecmp(optval
, "light")) {
159 r
->playout
= playout_light_init(playoutarg
, b
);
161 fprintf(stderr
, "Replay: Invalid playout policy %s\n", optval
);
164 fprintf(stderr
, "Replay: Invalid engine argument %s or missing value\n", optname
);
171 r
->playout
= playout_moggy_init(NULL
, b
, r
->jdict
);
172 r
->playout
->debug_level
= r
->debug_level
;
179 engine_replay_init(char *arg
, struct board
*b
)
181 struct replay
*r
= replay_state_init(arg
, b
);
182 /* TODO engine_done(), free policy */
184 struct engine
*e
= calloc2(1, sizeof(struct engine
));
185 e
->name
= "PlayoutReplay";
186 e
->comment
= "I select the most probable move from moggy playout policy";
187 e
->genmove
= replay_genmove
;
188 e
->done
= replay_done
;