diff options
| author | tslil clingman <tslil@posteo.de> | 2021-01-25 17:22:48 -0500 |
|---|---|---|
| committer | tslil <tslil@posteo.de> | 2026-08-28 19:37:41 +0100 |
| commit | 8418ddf3187ec0f526ef5d8dbb0689fc786fac92 (patch) | |
| tree | aeb5b1ad5b0df50b0ce5c484d732ffd6534223e0 /include/action_list.c | |
| parent | 034b4035f584f83669f7c4332d8befc3237e160c (diff) | |
Still some bugs, standing stone becomes flat at depth4 self-play??
Diffstat (limited to 'include/action_list.c')
| -rw-r--r-- | include/action_list.c | 75 |
1 files changed, 35 insertions, 40 deletions
diff --git a/include/action_list.c b/include/action_list.c index 10bbdcf..b338627 100644 --- a/include/action_list.c +++ b/include/action_list.c @@ -6,7 +6,7 @@ #define CLR_STONE NUM_MASK -static inline action_list_t * +static inline void action_list_prepend(action_list_t *list, const enum A_TYPE type, const int8_t loc, const uint8_t data0, const uint8_t data1); @@ -16,11 +16,14 @@ action_list_prepend(action_list_t *list, const enum A_TYPE type, // =================================================================== void action_list_free(action_list_t *list) { - action_list_t *n = NULL; - while (list) { - n = list->next; + if (list) { + action_node_t *n = list->head, *nn; + while (n) { + nn = n->next; + free(n); + n = nn; + } free(list); - list = n; } } @@ -35,7 +38,10 @@ void action_list_init(void) { } action_list_t *action_list_generate(void) { - action_list_t *result = NULL; + action_list_t *result = malloc(sizeof(struct action_list_s)); + // TODO: trap errno + result->length = 0; + result->head = NULL; const uint8_t black = (ply < 2) ? (ply==1) : (ply & 1), material = (black) ? black_count : white_count, @@ -43,9 +49,9 @@ action_list_t *action_list_generate(void) { cap = (ply >= 2 && (material & 128)), standing = (ply >= 2 && (material & 127)); - // Step across the board - for (int8_t row = board_size - 1; row > 0; row--) { - for (int8_t col = board_size - 1; col > 0; col--) { + // Step across the board, reversed because we prepend to the list + for (int8_t row = board_size - 1; row >= 0; row--) { + for (int8_t col = board_size - 1; col >= 0; col--) { // We'll need these at various points: the location of this // square and the maximum number of stones we could pick up const int8_t loc = THE_COORDS(col, row); @@ -106,7 +112,7 @@ action_list_t *action_list_generate(void) { const uint8_t last_drop_check = (num > 1) ? (gaps & 1<<(num - 2)) : 1; if (end_stops[dir][1] || last_drop_check) - result = action_list_prepend(result, A_MOVE, loc, gaps, (dir<<4) | num); + action_list_prepend(result, A_MOVE, loc, gaps, (dir<<4) | num); /* * With thanks to * https://graphics.stanford.edu/~seander/bithacks.html#NextBitPermutation @@ -122,31 +128,22 @@ action_list_t *action_list_generate(void) { } else if (count == 0 && material) { // Empty square, generate placements if (flat) { - result = action_list_prepend(result, - A_PLACE, - loc, - STONE_FLAT, - 0); + action_list_prepend(result, A_PLACE, loc, + STONE_FLAT, 0); if (standing) - result = action_list_prepend(result, - A_PLACE, - loc, - STONE_STANDING, - 0); + action_list_prepend(result, A_PLACE, loc, + STONE_STANDING, 0); } if (cap) - result = action_list_prepend(result, - A_PLACE, - loc, - STONE_CAPSTONE, - 0); + action_list_prepend(result, A_PLACE, loc, + STONE_CAPSTONE, 0); } } } return result; } -void action_take(action_list_t *action) { +void action_take(action_node_t *action) { const int8_t loc = action->loc; if (action->type == A_PLACE) { const uint8_t black = (current_colour == C_BLACK); @@ -181,7 +178,7 @@ void action_take(action_list_t *action) { // Use the Kernighan method to count the set bits int8_t steps = 1; - for (uint8_t _gaps = gaps; _gaps > 0; steps++) _gaps &= _gaps - 1; + for (uint8_t _gaps = gaps; _gaps; steps++) _gaps &= _gaps - 1; // Move top stone type to destination celldat[loc+steps*delta] &= CLR_STONE; // necessary for crushing @@ -189,14 +186,13 @@ void action_take(action_list_t *action) { celldat[loc] &= CLR_STONE; celldat[loc] |= STONE_FLAT; // should be optimised out - uint8_t gap_bit = 0, total = 0; + uint8_t gap_bit = 0, total = 1; // num == 1 is a special case if (num > 1) { gap_bit = 1 << (num - 2); - total = 1; } // move stuff starting at destination - for (uint8_t d = 0; d + 1 < num; d++, total++, gap_bit >>= 1) { + for (uint8_t d = 1; d < num; d++, total++, gap_bit >>= 1) { // We took a step, move everything over so far if (gaps & gap_bit) { colours[loc+steps*delta] <<= total; @@ -209,7 +205,6 @@ void action_take(action_list_t *action) { steps--; } } - total++; // Move what remains (steps == 1 here always, so we simplify) colours[loc+delta] <<= total; colours[loc+delta] |= colours[loc] & ((1 << total) - 1); @@ -227,7 +222,7 @@ void action_take(action_list_t *action) { } } -void action_undo(action_list_t *action) { +void action_undo(action_node_t *action) { // Previous ply if (ply>0) ply--; if (ply == 1) { @@ -256,8 +251,8 @@ void action_undo(action_list_t *action) { const int8_t delta = deltas[dir]; int8_t steps = 1; - uint8_t gap_bit = 1, total = (num > 1) ? 1 : 0; - for (uint8_t d = 0; d + 1 < num; d++, total++, gap_bit <<= 1) { + uint8_t gap_bit = 1, total = 1; + for (uint8_t d = 1; d < num; d++, total++, gap_bit <<= 1) { if (gaps & gap_bit) { colours[loc] <<= total; colours[loc] |= colours[loc+steps*delta] & ((1 << total) - 1); @@ -268,7 +263,6 @@ void action_undo(action_list_t *action) { steps++; } } - total++; colours[loc] <<= total; colours[loc] |= colours[loc+steps*delta] & ((1 << total) - 1); colours[loc+steps*delta] >>= total; @@ -282,7 +276,7 @@ void action_undo(action_list_t *action) { } } -void action_to_ptn(action_list_t* action, char* out_ptn) { +void action_to_ptn(action_node_t* action, char* out_ptn) { const int8_t loc = action->loc; if (action->type == A_PLACE) { generate_place(loc, action->data0, out_ptn); @@ -314,16 +308,17 @@ void action_to_ptn(action_list_t* action, char* out_ptn) { // Helper method implementations // =================================================================== -static inline action_list_t * +static inline void action_list_prepend(action_list_t *list, const enum A_TYPE type, const int8_t loc, const uint8_t data0, const uint8_t data1) { - action_list_t *new = malloc(sizeof(action_list_t)); + action_node_t *new = malloc(sizeof(action_list_t)); // TODO: trap errno + list->length++; new->loc = loc; new->type = type; - new->next = list; new->data0 = data0; new->data1 = data1; - return new; + new->next = list->head; + list->head = new; } |
