diff options
| author | tslil clingman <tslil@posteo.de> | 2021-01-26 22:39:28 -0500 |
|---|---|---|
| committer | tslil <tslil@posteo.de> | 2026-08-28 19:37:41 +0100 |
| commit | 6b48baaf6b67cc7364d5945eb6d9b25ea9683bd9 (patch) | |
| tree | b4b5a65c687a20f5f4075b2be100a1fffab06e59 | |
| parent | d39e9f242d7e71a517adbe003e9b3a25b676a052 (diff) | |
Somehting along these lines, i'm tired
| -rw-r--r-- | include/actions.c | 25 | ||||
| -rw-r--r-- | include/actions.h | 11 | ||||
| -rw-r--r-- | include/zobrist.c | 104 | ||||
| -rw-r--r-- | include/zobrist.h | 15 |
4 files changed, 138 insertions, 17 deletions
diff --git a/include/actions.c b/include/actions.c index 9b3534b..96264d0 100644 --- a/include/actions.c +++ b/include/actions.c @@ -8,15 +8,6 @@ #define CLR_STONE NUM_MASK -#define TYPE_SHIFT 24 -#define LOC_SHIFT 16 -#define DATA0_SHIFT 8 - -#define GET_TYPE(a) (enum A_TYPE)((a)>>TYPE_SHIFT) -#define GET_LOC(a) (int8_t)(((a)>>LOC_SHIFT) & 0xFF) -#define GET_DATA0(a) (uint8_t)(((a)>>DATA0_SHIFT) & 0xFF) -#define GET_DATA1(a) (uint8_t)((a) & 0xFF) - static inline void list_append(action_list_t *list, const enum A_TYPE type, const int8_t loc, const uint8_t data0, @@ -65,13 +56,13 @@ void action_list_free(action_list_t *list) { } // Keep track of move offsets -static int8_t deltas[4]; +int8_t move_deltas[4]; void action_list_init(void) { - deltas[0] = +board_size; - deltas[1] = -board_size; - deltas[2] = -1; - deltas[3] = +1; + move_deltas[0] = +board_size; + move_deltas[1] = -board_size; + move_deltas[2] = -1; + move_deltas[3] = +1; } action_list_t *action_list_generate(void) { @@ -117,7 +108,7 @@ action_list_t *action_list_generate(void) { // Now we check for caps and walls const uint8_t cap_top = STONE_AT(loc) == STONE_CAPSTONE; for (int d = 0; d < 4; d++){ - const int delta = deltas[d]; + const int delta = move_deltas[d]; const int stop = end_stops[d]; end_stops[d] = 0; for (int k = 1; k <= stop; k++) { @@ -229,7 +220,7 @@ void action_take(const action_t action) { const uint8_t gaps = GET_DATA0(action) & 0x7F, num = GET_DATA1(action) & 0x0F, // unpack dir = GET_DATA1(action) >> 4; - int8_t delta = deltas[dir]; + int8_t delta = move_deltas[dir]; // Use the Kernighan method to count the set bits int8_t steps = 1; @@ -293,7 +284,7 @@ void action_undo(const action_t action) { crush = GET_DATA0(action) & 0x80, num = GET_DATA1(action) & 0x0F, dir = GET_DATA1(action) >> 4; - const int8_t delta = deltas[dir]; + const int8_t delta = move_deltas[dir]; int8_t steps = 1; uint8_t gap_bit = 1, total = 1; diff --git a/include/actions.h b/include/actions.h index 661f11e..d331284 100644 --- a/include/actions.h +++ b/include/actions.h @@ -10,6 +10,15 @@ enum A_TYPE { A_PLACE, A_MOVE }; typedef uint32_t action_t; +#define TYPE_SHIFT 24 +#define LOC_SHIFT 16 +#define DATA0_SHIFT 8 + +#define GET_TYPE(a) (enum A_TYPE)((a)>>TYPE_SHIFT) +#define GET_LOC(a) (int8_t)(((a)>>LOC_SHIFT) & 0xFF) +#define GET_DATA0(a) (uint8_t)(((a)>>DATA0_SHIFT) & 0xFF) +#define GET_DATA1(a) (uint8_t)((a) & 0xFF) + typedef struct action_node_s { struct action_node_s *next; action_t action; @@ -20,6 +29,8 @@ typedef struct action_list_s { uint32_t length; } action_list_t; +extern int8_t move_deltas[4]; + void action_list_init(void); void action_list_free(action_list_t *list); action_list_t *action_list_generate(void); diff --git a/include/zobrist.c b/include/zobrist.c new file mode 100644 index 0000000..8eeb758 --- /dev/null +++ b/include/zobrist.c @@ -0,0 +1,104 @@ +#include "zobrist.h" + +// =================================================================== +// Globals +// =================================================================== + +static uint64_t *zobrist[15]; + +// =================================================================== +// Helpers +// =================================================================== + + +// =================================================================== +// Exported method implementations +// =================================================================== + +int +zobrist_init(void) { + for (int k=0; k<15; k++) { + if (zobrist[k] != NULL) return EXIT_FAILURE; + } + + for (int j=0; j<15; j++) { + zobrist[j] = malloc(sizeof(uint64_t)*board_size*board_size*(2*3+1)); + for (int k=0; k<board_size*board_size*(2*3+1); k++) { + XORSHIFT64; + zobrist[j][k] = RANDOM64; + } + } + + return EXIT_SUCCESS; +} + +void +zobrist_free(void) { + for (int k=0; k<15; k++) { + if (zobrist[k] != NULL) { + free(zobrist[k]); + zobrist[k] = NULL; + } + } +} + +uint64_t +zobrist_compute(void) { + uint64_t hash = 0; + for (uint8_t l=0; l<board_size*board_size; l++) { + colour_stack_t c = colours[l]; + const uint8_t count = COUNT_AT(l); + enum STONE_VARIANT s = STONE_AT(l); + for (uint8_t h=0; h<count; h++, c >>= 1) + hash ^= zobrist[h][l*(2*3+1)+(c&1)*3+s]; + } + return hash; +} + +uint64_t +zobrist_apply(const action_t action, uint64_t hash) { + const enum A_TYPE type = GET_TYPE(action); + const int8_t loc = GET_LOC(action); + if (type == A_PLACE) { + hash ^= zobrist[0][loc*(2*3+1) + +current_colour*3 + +GET_DATA0(action)]; + } else { + const uint8_t gaps = GET_DATA0(action) & 0x7F, + crush = GET_DATA0(action) & 0x80, + num = GET_DATA1(action) & 0x0F, + dir = GET_DATA1(action) >> 4; + const int8_t delta = move_deltas[dir]; + + // TODO: adapt this + int8_t steps = 1; + uint8_t gap_bit = 1, total = 1; + for (int8_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); + colours[loc+steps*delta] >>= total; + celldat[loc] += total*NUM_INC; + celldat[loc+steps*delta] -= total*NUM_INC; + total = 0; + steps++; + } + } + colours[loc] <<= total; + colours[loc] |= colours[loc+steps*delta] & ((1 << total) - 1); + colours[loc+steps*delta] >>= total; + + celldat[loc] += total*NUM_INC; + // celldat[loc] &= CLR_STONE; is not necessary, as STONE_FLAT == 0 + celldat[loc] |= STONE_AT(loc+steps*delta); + celldat[loc+steps*delta] -= total*NUM_INC; + celldat[loc+steps*delta] &= CLR_STONE; + if (crush) { + celldat[loc+steps*delta] |= STONE_STANDING; + } else { + celldat[loc+steps*delta] |= STONE_FLAT; // should be optimised out + } + + } + return hash; +} diff --git a/include/zobrist.h b/include/zobrist.h new file mode 100644 index 0000000..4e760ca --- /dev/null +++ b/include/zobrist.h @@ -0,0 +1,15 @@ +#include <xorshift64.h> +#include <tak.h> +#include <actions.h> + +void +zobrist_free(void); + +int +zobrist_init(void); + +uint64_t +zobrist_compute(void); + +uint64_t +zobrist_apply(const action_t action, uint64_t hash); |
