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 /include/zobrist.c | |
| parent | d39e9f242d7e71a517adbe003e9b3a25b676a052 (diff) | |
Somehting along these lines, i'm tired
Diffstat (limited to 'include/zobrist.c')
| -rw-r--r-- | include/zobrist.c | 104 |
1 files changed, 104 insertions, 0 deletions
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; +} |
