From 0e5cb34a8dce29af00414c5956c764761c201232 Mon Sep 17 00:00:00 2001 From: Petr Baudis Date: Wed, 23 Sep 2009 04:30:13 +0200 Subject: [PATCH] Permission policy for random plays is available now board_play_random() can call back a boolean function, board_play_random_game() can proxy that to playout policy. --- board.c | 11 ++++++----- board.h | 6 ++++-- montecarlo/montecarlo.c | 2 +- playout.c | 3 ++- playout.h | 5 ++++- random/random.c | 2 +- 6 files changed, 18 insertions(+), 11 deletions(-) diff --git a/board.c b/board.c index a13b601..cedf8ad 100644 --- a/board.c +++ b/board.c @@ -832,7 +832,7 @@ board_play(struct board *board, struct move *m) static inline bool -board_try_random_move(struct board *b, enum stone color, coord_t *coord, int f) +board_try_random_move(struct board *b, enum stone color, coord_t *coord, int f, ppr_permit permit, void *permit_data) { coord_raw(*coord) = b->f[f]; if (unlikely(is_pass(*coord))) @@ -841,23 +841,24 @@ board_try_random_move(struct board *b, enum stone color, coord_t *coord, int f) if (DEBUGL(6)) fprintf(stderr, "trying random move %d: %d,%d\n", f, coord_x(*coord, b), coord_y(*coord, b)); return (likely(!board_is_one_point_eye(b, coord, color)) /* bad idea to play into one, usually */ + && (!permit || permit(permit_data, b, &m)) && likely(board_play_f(b, &m, f) >= 0)); } void -board_play_random(struct board *b, enum stone color, coord_t *coord) +board_play_random(struct board *b, enum stone color, coord_t *coord, ppr_permit permit, void *permit_data) { int base = fast_random(b->flen); coord_pos(*coord, base, b); - if (likely(board_try_random_move(b, color, coord, base))) + if (likely(board_try_random_move(b, color, coord, base, permit, permit_data))) return; int f; for (f = base + 1; f < b->flen; f++) - if (board_try_random_move(b, color, coord, f)) + if (board_try_random_move(b, color, coord, f, permit, permit_data)) return; for (f = 0; f < base; f++) - if (board_try_random_move(b, color, coord, f)) + if (board_try_random_move(b, color, coord, f, permit, permit_data)) return; *coord = pass; diff --git a/board.h b/board.h index 6a20f1f..d70a79c 100644 --- a/board.h +++ b/board.h @@ -187,8 +187,10 @@ void board_handicap(struct board *board, int stones, FILE *f); int board_play(struct board *board, struct move *m); /* Like above, but plays random move; the move coordinate is recorded * to *coord. This method will never fill your own eye. pass is played - * when no move can be played. */ -void board_play_random(struct board *b, enum stone color, coord_t *coord); + * when no move can be played. You can impose extra restrictions if you + * supply your own permit function. */ +typedef bool (*ppr_permit)(void *data, struct board *b, struct move *m); +void board_play_random(struct board *b, enum stone color, coord_t *coord, ppr_permit permit, void *permit_data); /* Adjust symmetry information as if given coordinate has been played. */ void board_symmetry_update(struct board *b, struct board_symmetry *symmetry, coord_t c); diff --git a/montecarlo/montecarlo.c b/montecarlo/montecarlo.c index 23e8777..67fd644 100644 --- a/montecarlo/montecarlo.c +++ b/montecarlo/montecarlo.c @@ -95,7 +95,7 @@ montecarlo_genmove(struct engine *e, struct board *b, enum stone color) board_copy(&b2, b); coord_t coord; - board_play_random(&b2, color, &coord); + board_play_random(&b2, color, &coord, NULL, NULL); if (!is_pass(coord) && !group_at(&b2, coord)) { /* Multi-stone suicide. We play chinese rules, * so we can't consider this. (Note that we diff --git a/playout.c b/playout.c index b643df9..80d9d1f 100644 --- a/playout.c +++ b/playout.c @@ -8,6 +8,7 @@ #include "move.h" #include "playout.h" + int play_random_game(struct board *b, enum stone starting_color, int gamelen, struct playout_amafmap *amafmap, @@ -40,7 +41,7 @@ play_random_game(struct board *b, enum stone starting_color, int gamelen, coord = urgent; } else { play_random: - board_play_random(b, color, &coord); + board_play_random(b, color, &coord, (ppr_permit) policy->permit, policy); } #if 0 diff --git a/playout.h b/playout.h index 0efc6ec..0e487a9 100644 --- a/playout.h +++ b/playout.h @@ -10,13 +10,16 @@ struct playout_policy; typedef coord_t (*playoutp_choose)(struct playout_policy *playout_policy, struct board *b, enum stone to_play); /* 0.0 - 1.0; can return NAN is policy has no opinion */ typedef float (*playoutp_assess)(struct playout_policy *playout_policy, struct board *b, struct move *m); +typedef bool (*playoutp_permit)(struct playout_policy *playout_policy, struct board *b, struct move *m); struct playout_policy { int debug_level; /* We call choose when we ask policy about next move. - * We call assess when we ask policy about how good given move is. */ + * We call assess when we ask policy about how good given move is. + * We call permit when we ask policy if we can make a randomly chosen move. */ playoutp_choose choose; playoutp_assess assess; + playoutp_permit permit; void *data; }; diff --git a/random/random.c b/random/random.c index 555461b..1637f6e 100644 --- a/random/random.c +++ b/random/random.c @@ -10,7 +10,7 @@ static coord_t * random_genmove(struct engine *e, struct board *b, enum stone color) { coord_t coord; - board_play_random(b, color, &coord); + board_play_random(b, color, &coord, NULL, NULL); if (!group_at(b, coord)) { /* This was suicide. Just pass. */ /* XXX: We should check for non-suicide alternatives. */ -- 2.11.4.GIT