From cbdb6a8c6afd96ab822ea9863bfebb32c903932f Mon Sep 17 00:00:00 2001 From: lemonsqueeze Date: Fri, 10 Jun 2016 08:04:38 +0200 Subject: [PATCH] can_countercapture(): foolproof api --- playout/moggy.c | 3 +- t-unit/test.c | 2 +- tactics/1lib.c | 105 +++++++++++++++------------------------------------- tactics/1lib.h | 13 +++---- tactics/ladder.c | 4 +- tactics/selfatari.c | 2 +- 6 files changed, 39 insertions(+), 90 deletions(-) diff --git a/playout/moggy.c b/playout/moggy.c index 3cf77e3..8666eb8 100644 --- a/playout/moggy.c +++ b/playout/moggy.c @@ -192,8 +192,7 @@ test_pattern3_here(struct playout_policy *p, struct board *b, struct move *m, bo /* Ladder moves are stupid. */ group_t atari_neighbor = board_get_atari_neighbor(b, m->coord, m->color); if (atari_neighbor && is_ladder(b, m->coord, atari_neighbor, middle_ladder) - && !can_countercapture(b, board_at(b, group_base(atari_neighbor)), - atari_neighbor, m->color, NULL, 0)) + && !can_countercapture(b, atari_neighbor, NULL, 0)) return false; //fprintf(stderr, "%s: %d (%.3f)\n", coord2sstr(m->coord, b), (int) pi, pp->pat3_gammas[(int) pi]); if (gamma) diff --git a/t-unit/test.c b/t-unit/test.c index 3b2c3c1..d866f12 100644 --- a/t-unit/test.c +++ b/t-unit/test.c @@ -175,7 +175,7 @@ test_can_countercapture(struct board *b, char *arg) enum stone color = board_at(b, c); group_t g = group_at(b, c); assert(color == S_BLACK || color == S_WHITE); - int rres = can_countercapture(b, color, g, color, NULL, 0); + int rres = can_countercapture(b, g, NULL, 0); if (rres == eres) { if (DEBUGL(1)) diff --git a/tactics/1lib.c b/tactics/1lib.c index 8ffc2be..6c8459c 100644 --- a/tactics/1lib.c +++ b/tactics/1lib.c @@ -78,36 +78,27 @@ can_play_on_lib(struct board *b, group_t g, enum stone to_play) return false; } -/* Check snapbacks */ -static inline __attribute__((always_inline)) bool -capturable_group(struct board *b, enum stone capturer, coord_t c, - enum stone to_play) -{ - group_t g = group_at(b, c); - if (likely(board_at(b, c) != stone_other(capturer) - || board_group_info(b, g).libs > 1)) - return false; - - return can_capture(b, g, to_play); -} - +/* Checks snapbacks */ bool -can_countercapture(struct board *b, enum stone owner, group_t g, - enum stone to_play, struct move_queue *q, int tag) +can_countercapture(struct board *b, group_t group, struct move_queue *q, int tag) { - //if (!b->clen) - // return false; - + enum stone color = board_at(b, group); + enum stone other = stone_other(color); + assert(color == S_BLACK || color == S_WHITE); + // Not checking b->clen, not maintained by board_quick_play() + unsigned int qmoves_prev = q ? q->moves : 0; - foreach_in_group(b, g) { + foreach_in_group(b, group) { foreach_neighbor(b, c, { - if (!capturable_group(b, owner, c, to_play)) + group_t g = group_at(b, c); + if (likely(board_at(b, c) != other + || board_group_info(b, g).libs > 1) || + !can_capture(b, g, color)) continue; - if (!q) { + if (!q) return true; - } mq_add(q, board_group_info(b, group_at(b, c)).lib[0], tag); mq_nodup(q); }); @@ -117,36 +108,28 @@ can_countercapture(struct board *b, enum stone owner, group_t g, return can; } -static inline __attribute__((always_inline)) bool -capturable_group_fast(struct board *b, enum stone capturer, coord_t c, - enum stone to_play) -{ - group_t g = group_at(b, c); - if (likely(board_at(b, c) != stone_other(capturer) - || board_group_info(b, g).libs > 1)) - return false; - - coord_t lib = board_group_info(b, g).lib[0]; - return board_is_valid_play(b, to_play, lib); -} - bool -can_countercapture_any(struct board *b, enum stone owner, group_t g, - enum stone to_play, struct move_queue *q, int tag) +can_countercapture_any(struct board *b, group_t group, struct move_queue *q, int tag) { - //if (b->clen < 2) - // return false; - + enum stone color = board_at(b, group); + enum stone other = stone_other(color); + assert(color == S_BLACK || color == S_WHITE); + // Not checking b->clen, not maintained by board_quick_play() + unsigned int qmoves_prev = q ? q->moves : 0; - foreach_in_group(b, g) { + foreach_in_group(b, group) { foreach_neighbor(b, c, { - if (!capturable_group_fast(b, owner, c, to_play)) + group_t g = group_at(b, c); + if (likely(board_at(b, c) != other + || board_group_info(b, g).libs > 1)) + continue; + coord_t lib = board_group_info(b, g).lib[0]; + if (!board_is_valid_play(b, color, lib)) continue; - if (!q) { + if (!q) return true; - } mq_add(q, board_group_info(b, group_at(b, c)).lib[0], tag); mq_nodup(q); }); @@ -156,36 +139,6 @@ can_countercapture_any(struct board *b, enum stone owner, group_t g, return can; } -#if 0 -bool -can_countercapture_(struct board *b, enum stone owner, group_t g, - enum stone to_play, struct move_queue *q, int tag) -{ - if (!g || - board_at(b, g) != owner || - owner != to_play) { - board_print(b, stderr); - fprintf(stderr, "can_countercap(%s %s %s): \n", - stone2str(owner), coord2sstr(g, b), stone2str(to_play)); - } - /* Sanity checks */ - assert(g); - assert(board_at(b, g) == owner); - assert(owner == to_play); - -#if 0 - bool r1 = my_can_countercapture(b, owner, g, to_play, NULL, 0); - bool r2 = orig_can_countercapture(b, owner, g, to_play, NULL, 0); - if (r1 != r2) { - fprintf(stderr, "---------------------------------------------------------------\n"); - board_print(b, stderr); - fprintf(stderr, "can_countercap(%s %s %s) diff ! my:%i org:%i\n", - stone2str(owner), coord2sstr(g, b), stone2str(to_play), r1, r2); - } -#endif - return orig_can_countercapture(b, owner, g, to_play, q, tag); -} -#endif #ifdef NO_DOOMED_GROUPS static bool @@ -196,7 +149,7 @@ can_be_rescued(struct board *b, group_t group, enum stone color, int tag) return true; /* Then, maybe we can capture one of our neighbors? */ - return can_countercapture(b, color, group, color, NULL, tag); + return can_countercapture(b, group, NULL, tag); } #endif @@ -233,7 +186,7 @@ group_atari_check(unsigned int alwaysccaprate, struct board *b, group_t group, e * Could be because of a bug / under the stones situations * (maybe not so uncommon in moggy ?) / it upsets moggy's balance somehow * (there's always a chance opponent doesn't capture after taking snapback) */ - bool ccap = can_countercapture_any(b, color, group, to_play, q, tag); + bool ccap = can_countercapture_any(b, group, q, tag); if (ccap && !ladder && alwaysccaprate > fast_random(100)) return; diff --git a/tactics/1lib.h b/tactics/1lib.h index 37e55d8..d380732 100644 --- a/tactics/1lib.h +++ b/tactics/1lib.h @@ -9,14 +9,11 @@ struct move_queue; -/* For given atari group @group owned by @owner, decide if @to_play - * can save it / keep it in danger by dealing with one of the - * neighboring groups. */ -bool can_countercapture(struct board *b, enum stone owner, group_t g, - enum stone to_play, struct move_queue *q, int tag); - -bool can_countercapture_any(struct board *b, enum stone owner, group_t g, - enum stone to_play, struct move_queue *q, int tag); +/* Can group @group usefully capture a neighbor ? + * (usefully: not a snapback) */ +bool can_countercapture(struct board *b, group_t group, struct move_queue *q, int tag); +/* Can group @group capture *any* neighbor ? */ +bool can_countercapture_any(struct board *b, group_t group, struct move_queue *q, int tag); /* Examine given group in atari, suggesting suitable moves for player * @to_play to deal with it (rescuing or capturing it). */ diff --git a/tactics/ladder.c b/tactics/ladder.c index e8aa7c8..8a12a8e 100644 --- a/tactics/ladder.c +++ b/tactics/ladder.c @@ -15,7 +15,7 @@ bool is_border_ladder(struct board *b, coord_t coord, group_t laddered, enum stone lcolor) { - if (can_countercapture(b, lcolor, laddered, lcolor, NULL, 0)) + if (can_countercapture(b, laddered, NULL, 0)) return false; int x = coord_x(coord, b), y = coord_y(coord, b); @@ -183,7 +183,7 @@ is_middle_ladder(struct board *b, coord_t coord, group_t laddered, enum stone lc * board and start selective 2-liberty search. */ struct move_queue ccq = { .moves = 0 }; - if (can_countercapture(b, lcolor, laddered, lcolor, &ccq, 0)) { + if (can_countercapture(b, laddered, &ccq, 0)) { /* We could escape by countercapturing a group. * Investigate. */ assert(ccq.moves > 0); diff --git a/tactics/selfatari.c b/tactics/selfatari.c index 2a2bb3a..71339b1 100644 --- a/tactics/selfatari.c +++ b/tactics/selfatari.c @@ -739,7 +739,7 @@ found:; /* Can we get liberties by capturing a neighbor? */ struct move_queue ccq; ccq.moves = 0; if (board_at(b, group) == color && - can_countercapture(b, color, group, color, &ccq, 0)) { + can_countercapture(b, group, &ccq, 0)) { lib2 = mq_pick(&ccq); } else { -- 2.11.4.GIT