aboutsummaryrefslogtreecommitdiff
path: root/include/zobrist.c
diff options
context:
space:
mode:
authortslil clingman <tslil@posteo.de>2021-01-26 22:39:28 -0500
committertslil <tslil@posteo.de>2026-08-28 19:37:41 +0100
commit6b48baaf6b67cc7364d5945eb6d9b25ea9683bd9 (patch)
treeb4b5a65c687a20f5f4075b2be100a1fffab06e59 /include/zobrist.c
parentd39e9f242d7e71a517adbe003e9b3a25b676a052 (diff)
Somehting along these lines, i'm tired
Diffstat (limited to 'include/zobrist.c')
-rw-r--r--include/zobrist.c104
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;
+}