From 409b110ea022fff86c6e7c158926e9fab5310e6a Mon Sep 17 00:00:00 2001 From: Petr Baudis Date: Sun, 2 Mar 2008 04:49:26 +0100 Subject: [PATCH] Playout: Add playout_policy support --- montecarlo/hint.c | 33 +++++++++++++++------------------ montecarlo/hint.h | 2 +- montecarlo/montecarlo.c | 2 +- playout.c | 9 ++++----- playout.h | 7 ++++++- 5 files changed, 27 insertions(+), 26 deletions(-) diff --git a/montecarlo/hint.c b/montecarlo/hint.c index 65a5ff5..b1e43d2 100644 --- a/montecarlo/hint.c +++ b/montecarlo/hint.c @@ -146,11 +146,11 @@ domain_hint_local(struct montecarlo *mc, struct board *b, coord_t coord) return pass; } -void -domain_hint(struct montecarlo *mc, struct board *b, coord_t *urgent, enum stone our_real_color) +coord_t +domain_hint(struct montecarlo *mc, struct board *b, enum stone our_real_color) { if (is_pass(b->last_move.coord)) - return; + return pass; /* Now now, if we ignored an urgent move, the opponent will * take it! */ @@ -161,42 +161,39 @@ domain_hint(struct montecarlo *mc, struct board *b, coord_t *urgent, enum stone && unlikely(!coord_eq(b->last_move.coord, mc->last_hint)) && b->last_move.color == our_real_color && fast_random(100) < mc->last_hint_value) { - *urgent = mc->last_hint; + coord_t urgent = mc->last_hint; mc->last_hint = pass; - return; + return urgent; } /* In some of the cases, we pick atari response instead of random move. * If there is an atari, capturing tends to be huge. */ if (mc->atari_rate && fast_random(100) < mc->atari_rate) { - *urgent = domain_hint_atari(mc, b, b->last_move.coord); - if (!is_pass(*urgent)) { - mc->last_hint = *urgent; + mc->last_hint = domain_hint_atari(mc, b, b->last_move.coord); + if (!is_pass(mc->last_hint)) { mc->last_hint_value = mc->atari_rate; - return; + return mc->last_hint; } } /* Cutting is kinda urgent, too. */ if (mc->cut_rate && fast_random(100) < mc->cut_rate) { - *urgent = domain_hint_cut(mc, b, b->last_move.coord); - if (!is_pass(*urgent)) { - mc->last_hint = *urgent; + mc->last_hint = domain_hint_cut(mc, b, b->last_move.coord); + if (!is_pass(mc->last_hint)) { mc->last_hint_value = mc->cut_rate; - return; + return mc->last_hint; } } /* For the non-urgent moves, some of them will be contact play (tsuke * or diagonal). These tend to be likely urgent. */ if (mc->local_rate && fast_random(100) < mc->local_rate) { - *urgent = domain_hint_local(mc, b, b->last_move.coord); - if (!is_pass(*urgent)) { - mc->last_hint = *urgent; + mc->last_hint = domain_hint_local(mc, b, b->last_move.coord); + if (!is_pass(mc->last_hint)) { mc->last_hint_value = mc->local_rate; - return; + return mc->last_hint; } } - mc->last_hint = pass; + return ((mc->last_hint = pass)); } diff --git a/montecarlo/hint.h b/montecarlo/hint.h index ea52772..edff34b 100644 --- a/montecarlo/hint.h +++ b/montecarlo/hint.h @@ -7,6 +7,6 @@ struct montecarlo; struct board; -void domain_hint(struct montecarlo *mc, struct board *b, coord_t *urgent, enum stone our_real_color); +coord_t domain_hint(struct montecarlo *mc, struct board *b, enum stone our_real_color); #endif diff --git a/montecarlo/montecarlo.c b/montecarlo/montecarlo.c index 3e5cd89..f89d7fd 100644 --- a/montecarlo/montecarlo.c +++ b/montecarlo/montecarlo.c @@ -103,7 +103,7 @@ montecarlo_genmove(struct engine *e, struct board *b, enum stone color) int losses = 0; int i, superko = 0, good_games = 0; for (i = 0; i < mc->games; i++) { - int result = play_random_game(b, &m, mc->gamelen); + int result = play_random_game(b, &m, mc->gamelen, domain_hint, mc); if (MCDEBUGL(3)) fprintf(stderr, "\tresult %d\n", result); diff --git a/playout.c b/playout.c index bd82170..b656532 100644 --- a/playout.c +++ b/playout.c @@ -9,7 +9,8 @@ #include "playout.h" int -play_random_game(struct board *b, struct move *m, int gamelen) +play_random_game(struct board *b, struct move *m, int gamelen, + playout_policeman policeman, void *policy) { if (b->superko_violation) { if (DEBUGL(0)) { @@ -50,14 +51,12 @@ play_random_game(struct board *b, struct move *m, int gamelen) /* This check is ultra-important BTW. Without it domain checking does * not bring that much of an advantage. It might even warrant it to by * default do only this domain check. */ - urgent = pass; - /* domain_hint(mc, b, &urgent, m->color); */ + urgent = policeman(policy, b, m->color); if (!is_pass(urgent)) goto play_urgent; while (gamelen-- && passes < 2) { - urgent = pass; - /* domain_hint(mc, &b2, &urgent, m->color); */ + urgent = policeman(policy, &b2, m->color); coord_t coord; diff --git a/playout.h b/playout.h index d8af0e6..574c09a 100644 --- a/playout.h +++ b/playout.h @@ -3,11 +3,16 @@ struct board; struct move; +enum stone; + + +typedef coord_t (*playout_policeman)(void *playout_policy, struct board *b, enum stone my_color); + /* 1: m->color wins, 0: m->color loses * -1 superko at the root * -2 superko inside the game tree (NOT at root, that's simply invalid move) * -3 first move is multi-stone suicide */ -int play_random_game(struct board *b, struct move *m, int gamelen); +int play_random_game(struct board *b, struct move *m, int gamelen, playout_policeman policeman, void *policy); #endif -- 2.11.4.GIT