aboutsummaryrefslogtreecommitdiff
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
parentd39e9f242d7e71a517adbe003e9b3a25b676a052 (diff)
Somehting along these lines, i'm tired
-rw-r--r--include/actions.c25
-rw-r--r--include/actions.h11
-rw-r--r--include/zobrist.c104
-rw-r--r--include/zobrist.h15
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);