aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/actions.c500
-rw-r--r--include/actions.h29
-rw-r--r--include/lcdlib.c53
-rw-r--r--include/lcdlib.h7
-rw-r--r--include/negamax.c190
-rw-r--r--include/negamax.h10
-rw-r--r--include/nn1986.c26
-rw-r--r--include/nn1986.h2
-rw-r--r--include/tak.c664
-rw-r--r--include/tak.h53
-rw-r--r--include/tps.c351
-rw-r--r--include/tps.h8
-rw-r--r--include/tt_llcht.c27
-rw-r--r--include/tt_llcht.h9
-rw-r--r--include/weights.c10
-rw-r--r--include/weights.h3
-rw-r--r--include/xorshift64.h11
-rw-r--r--include/zobrist.c23
-rw-r--r--include/zobrist.h8
19 files changed, 1080 insertions, 904 deletions
diff --git a/include/actions.c b/include/actions.c
index 795c135..6303822 100644
--- a/include/actions.c
+++ b/include/actions.c
@@ -16,37 +16,42 @@
*/
#include "actions.h"
+#include "tak.h"
+
+#include <stdio.h>
+
+static uint8_t al_board_size;
// ===================================================================
// Helper method declarations
// ===================================================================
-#define DANGER_MIN(a,b) (((a)<(b))?(a):(b))
+#define DANGER_MIN(a, b) (((a) < (b)) ? (a) : (b))
#define CLR_STONE NUM_MASK
-static inline void
-list_append(action_list_t *list, const enum A_TYPE type,
- const int8_t loc, const uint8_t data0,
- const uint8_t data1);
+static inline void list_append(action_list_t *list, const enum A_TYPE type,
+ const int8_t loc, const uint8_t data0,
+ const uint8_t data1);
+
+static inline void list_prepend(action_list_t *list, const enum A_TYPE type,
+ const int8_t loc, const uint8_t data0,
+ const uint8_t data1);
-static inline void
-list_prepend(action_list_t *list, const enum A_TYPE type,
- const int8_t loc, const uint8_t data0,
- const uint8_t data1);
+static inline void inline_next_ply(tak_state_p state);
-static inline void
-inline_next_ply(void);
+static inline void inline_prev_ply(tak_state_p state);
-static inline void
-inline_prev_ply(void);
+static inline uint8_t check_no_overflow(tak_state_p state, const uint8_t loc,
+ const int8_t delta, const uint8_t num,
+ const uint8_t steps,
+ const uint8_t gaps);
// ===================================================================
// Exported method implementations
// ===================================================================
-int action_move_to_front(const action_t action,
- action_list_t *list) {
+int action_move_to_front(const action_t action, action_list_t *list) {
action_node_t *n = list->head;
// TODO: what if it's not in the list?
@@ -64,7 +69,6 @@ int action_move_to_front(const action_t action,
return EXIT_FAILURE;
}
-
void action_list_free(action_list_t *list) {
if (list) {
action_node_t *n = list->head, *nn;
@@ -80,7 +84,8 @@ void action_list_free(action_list_t *list) {
// Keep track of move offsets
int8_t move_deltas[4];
-void action_list_init(void) {
+void action_list_init(const uint8_t board_size) {
+ al_board_size = board_size;
move_deltas[0] = +board_size;
move_deltas[1] = -board_size;
move_deltas[2] = -1;
@@ -89,7 +94,7 @@ void action_list_init(void) {
// We bias place over move by prepending place actions and appending
// move actions to the generated list
-action_list_t *action_list_generate(void) {
+action_list_t *action_list_generate(tak_state_p state) {
action_list_t *list = malloc(sizeof(struct action_list_s));
// TODO: trap errno
@@ -103,278 +108,297 @@ action_list_t *action_list_generate(void) {
* well save on the conditional.
*/
- const uint8_t material = (ply & 1) ? black_count : white_count,
- flat = material & 0x7F,
- cap = ((ply >= 2) && (material & 0x80)),
- standing = ((ply >= 2) && flat);
+ const uint8_t material =
+ (state->ply & 1) ? state->black_count : state->white_count,
+ flat = material & 0x7F,
+ cap = ((state->ply >= 2) && (material & 0x80)),
+ standing = ((state->ply >= 2) && flat);
// Step across the board
- for (int row = 0; row < board_size; row++) {
- for (int col = 0; col < board_size; col++) {
+ for (int row = 0; row < state->board_size; row++) {
+ for (int col = 0; col < state->board_size; col++) {
// We'll need these at various points: the location of this
// square and the maximum number of stones we could pick up
- const int loc = THE_COORDS(col, row);
- const uint8_t count = DANGER_MIN(COUNT_AT(loc), board_size);
+ const int loc = THE_COORDS(al_board_size, col, row);
+ const uint8_t count = DANGER_MIN(COUNT_AT(state, loc), al_board_size);
// Only try moves after CPS and if the colour is correct
if (count) {
- if (ply >= 2 && ((colours[loc] & 1) == current_colour)) {
-
- // Pre-compute end-stops and crushes
- uint8_t end_stops[4], crushes[4] = {0, 0, 0, 0};
+ if (state->ply >= 2 &&
+ ((state->colours[loc] & 1) == state->current_colour)) {
- // These are upper bounds, not counting walls and such.
- // UP DOWN LEFT RIGHT
- end_stops[0] = DANGER_MIN(board_size - row - 1, count);
- end_stops[1] = DANGER_MIN(row, count);
- end_stops[2] = DANGER_MIN(col, count);
- end_stops[3] = DANGER_MIN(board_size - col - 1, count);
+ // Pre-compute end-stops and crushes
+ uint8_t end_stops[4], crushes[4] = {0, 0, 0, 0};
- // 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 = move_deltas[d];
- const int stop = end_stops[d];
- end_stops[d] = 0;
- for (int k = 1; k <= stop; k++) {
- const enum STONE_VARIANT stone = STONE_AT(loc+k*delta);
- if (stone == STONE_STANDING) {
- if (cap_top) {
- crushes[d] = 0xFF;
- end_stops[d]++;
- }
- break;
- } else if (stone == STONE_CAPSTONE) {
- break;
- }
- end_stops[d]++;
- }
- }
- /*
- * For each direction, generate all possible ordered integer
- * partitions of 1 ≤ num ≤ count whose number of summands is
- * exactly 1 ≤ summands ≤ min(end_stops[dir], num) -- we
- * write summands as steps.
- *
- * We exploit the `gaps' bijection here and elsewhere
- * between ordered {integer partitions of n with s summands}
- * and {binary strings of length n-1 with s-1 set bits}.
- */
- for (enum MOVE_DIRECTION dir=M_UP; dir<=M_RIGHT; dir++) {
- for (uint8_t num = 1; num <= count; num++) {
- for (uint8_t steps = 1;
- steps <= end_stops[dir] && steps <= num;
- steps++) {
- uint8_t gaps =
- ((1<<(board_size - 2)) - 1) >> (board_size-steps-1);
- // For 5x5 this givess 0b0000[0XXX] where steps-1 of
- // those X's are 1s (starting with LSB) because 4-1=3
- // and 5-1=4
- do {
- /*
- * We skip the partition if it calls for multiple
- * stones at the end with a crush.
- */
- const uint8_t last_drop_check =
- (num > 1) ? (gaps & (1 << (num - 2))) : 1;
- if (crushes[dir] == 0 || last_drop_check) {
- // We have to record a crush!
- const uint8_t crush =
- (steps == end_stops[dir]) && crushes[dir];
- // Store the move
+ // These are upper bounds, not counting walls and such.
+ // UP DOWN LEFT RIGHT
+ end_stops[0] = DANGER_MIN(al_board_size - row - 1, count);
+ end_stops[1] = DANGER_MIN(row, count);
+ end_stops[2] = DANGER_MIN(col, count);
+ end_stops[3] = DANGER_MIN(al_board_size - col - 1, count);
- list_append(list, A_MOVE, loc,
- (crush << 7) | gaps,
- (dir<<4) | num);
- }
- /*
- * With thanks to
- * https://graphics.stanford.edu/~seander/bithacks.html#NextBitPermutation
- * we have the following magic to generate the next
- * permutation of steps-many set bits
- */
- uint8_t t = (gaps | (gaps - 1));
- gaps = (t + 1)
- | (((~t & -~t) - 1) >> (__builtin_ctz(gaps) + 1));
- } while (gaps && (gaps + 1 <= (1 << (num - 1))));
- }
- }
- }
- }
+ // Now we check for caps and walls
+ const uint8_t cap_top = STONE_AT(state, loc) == STONE_CAPSTONE;
+ for (int d = 0; d < 4; d++) {
+ const int delta = move_deltas[d];
+ const int stop = end_stops[d];
+ end_stops[d] = 0;
+ for (int k = 1; k <= stop; k++) {
+ const enum STONE_VARIANT stone = STONE_AT(state, loc + k * delta);
+ if (stone == STONE_STANDING) {
+ if (cap_top) {
+ crushes[d] = k;
+ end_stops[d]++;
+ }
+ break;
+ } else if (stone == STONE_CAPSTONE) {
+ break;
+ }
+ end_stops[d]++;
+ }
+ }
+ /*
+ * For each direction, generate all possible ordered integer
+ * partitions of 1 ≤ num ≤ count whose number of summands is in the
+ * range 1 ≤ # summands ≤ min(end_stops[dir], num) -- we write
+ * summands as steps.
+ *
+ * We exploit the `gaps' bijection here and elsewhere between ordered
+ * {integer partitions of n with s summands} and {binary strings of
+ * length n-1 with s-1 set bits}.
+ */
+ for (enum MOVE_DIRECTION dir = M_UP; dir <= M_RIGHT; dir++) {
+ const int8_t delta = move_deltas[dir];
+ for (uint8_t num = 1; num <= count; num++) {
+ for (uint8_t steps = 1; steps <= end_stops[dir] && steps <= num;
+ steps++) {
+ uint8_t gaps = ((1 << (al_board_size - 2)) - 1) >>
+ (al_board_size - steps - 1);
+ // For 5x5 this gives 0b0000[0XXX] where steps-1 of those X's
+ // are 1s (starting with LSB) because 4-1=3 and 5-1=4
+ do {
+ /*
+ * We skip the partition if it calls for multiple stones at
+ * the end with a crush, or if it would cause any stack to
+ * grow beyond height 15.
+ */
+ const uint8_t no_overflow =
+ check_no_overflow(state, loc, delta, num, steps, gaps);
+ const uint8_t last_drop_check =
+ (num > 1) ? (gaps & (1 << (num - 2))) : 1;
+ const uint8_t can_and_must_crush =
+ crushes[dir] == steps && last_drop_check;
+ const uint8_t crush_check =
+ can_and_must_crush || crushes[dir] != steps;
+ if (no_overflow && crush_check) {
+ // Store the move
+ list_append(list, A_MOVE, loc,
+ (can_and_must_crush << 7) | gaps,
+ (dir << 4) | num);
+ }
+ /*
+ * With thanks to
+ * https://graphics.stanford.edu/~seander/bithacks.html#NextBitPermutation
+ * we have the following magic to generate the next
+ * permutation of steps-many set bits
+ */
+ uint8_t t = (gaps | (gaps - 1));
+ gaps =
+ (t + 1) | (((~t & -~t) - 1) >> (__builtin_ctz(gaps) + 1));
+ } while (gaps && (gaps + 1 <= (1 << (num - 1))));
+ }
+ }
+ }
+ }
} // end of if (count) { ... }
else if (material) {
- // Empty square, generate placements
- if (flat) {
- list_prepend(list, A_PLACE, loc, STONE_FLAT, 0);
- if (standing)
- list_prepend(list, A_PLACE, loc, STONE_STANDING,0);
- }
- if (cap)
- list_prepend(list, A_PLACE, loc, STONE_CAPSTONE, 0);
+ // Empty square, generate placements
+ if (flat) {
+ list_prepend(list, A_PLACE, loc, STONE_FLAT, 0);
+ if (standing)
+ list_prepend(list, A_PLACE, loc, STONE_STANDING, 0);
+ }
+ if (cap)
+ list_prepend(list, A_PLACE, loc, STONE_CAPSTONE, 0);
}
}
}
return list;
}
-void action_take(const action_t action) {
+void action_take(tak_state_p state, const action_t action) {
const int8_t loc = A_GET_LOC(action);
if (A_GET_TYPE(action) == A_PLACE) {
- const uint8_t black = (current_colour == C_BLACK);
+ const uint8_t black = (state->current_colour == C_BLACK);
switch (A_GET_DATA0(action)) {
- case STONE_FLAT: {
- if (black) black_count--;
- else white_count--;
- colours[loc] = current_colour;
- celldat[loc] = NUM_INC | STONE_FLAT;
- break;
- }
- case STONE_STANDING: {
- if (black) black_count--;
- else white_count--;
- colours[loc] = current_colour;
- celldat[loc] = NUM_INC | STONE_STANDING;
- break;
- }
- default: {
- if (black) black_count &= 0x7F;
- else white_count &= 0x7F;
- colours[loc] = current_colour;
- celldat[loc] = NUM_INC | STONE_CAPSTONE;
- break;
- }
+ case STONE_FLAT: {
+ if (black)
+ state->black_count--;
+ else
+ state->white_count--;
+ state->colours[loc] = state->current_colour;
+ state->celldat[loc] = NUM_INC | STONE_FLAT;
+ break;
+ }
+ case STONE_STANDING: {
+ if (black)
+ state->black_count--;
+ else
+ state->white_count--;
+ state->colours[loc] = state->current_colour;
+ state->celldat[loc] = NUM_INC | STONE_STANDING;
+ break;
+ }
+ default: {
+ if (black)
+ state->black_count &= 0x7F;
+ else
+ state->white_count &= 0x7F;
+ state->colours[loc] = state->current_colour;
+ state->celldat[loc] = NUM_INC | STONE_CAPSTONE;
+ break;
+ }
}
} else {
/*
- * See the discussion around line 135 for an explanation of the
- * encoding. Here we are not interested in whether we crushed, it
- * will work out by anyway because we overwrite the top stone
- * type. See (*) later for when we do need to know.
+ * See the discussion around line 160 for an explanation of the encoding.
+ * Here we are not interested in whether we crushed, it will work out by
+ * anyway because we overwrite the top stone type. See (*) later for when we
+ * do need to know.
*/
const uint8_t gaps = A_GET_DATA0(action) & 0x7F,
- num = A_GET_DATA1(action) & 0x0F, // unpack
- dir = A_GET_DATA1(action) >> 4;
+ num = A_GET_DATA1(action) & 0x0F, // unpack
+ dir = A_GET_DATA1(action) >> 4;
int8_t delta = move_deltas[dir];
// Use the Kernighan method to count the set bits
int8_t steps = 1;
- for (uint8_t _gaps = gaps; _gaps; 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
- celldat[loc+steps*delta] |= STONE_AT(loc);
- celldat[loc] &= CLR_STONE;
- celldat[loc] |= STONE_FLAT; // should be optimised out
+ state->celldat[loc + steps * delta] &= CLR_STONE; // necessary for crushing
+ state->celldat[loc + steps * delta] |= STONE_AT(state, loc);
+ state->celldat[loc] &= CLR_STONE;
+ state->celldat[loc] |= STONE_FLAT; // should be optimised out
+
+ uint8_t total = 1, gap_bit = 1 << (num - 2); // it's not important what
+ // negative shifts do here, we
+ // don't use gap_bit if num < 2
- uint8_t total = 1, gap_bit = 1 << (num - 2); // it's not important
- // what negative
- // shifts do here, we
- // don't use gap_bit
- // if num < 2
// move stuff starting at destination
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;
- colours[loc+steps*delta] |= colours[loc] & ((1 << total) - 1);
- colours[loc] >>= total;
- celldat[loc+steps*delta] += total*NUM_INC;
- celldat[loc] -= total*NUM_INC;
- // Reset for next step
- total = 0;
- steps--;
+ state->colours[loc + steps * delta] <<= total;
+ state->colours[loc + steps * delta] |=
+ state->colours[loc] & ((1 << total) - 1);
+ state->colours[loc] >>= total;
+ state->celldat[loc + steps * delta] += total * NUM_INC;
+ state->celldat[loc] -= total * NUM_INC;
+ // Reset for next step
+ total = 0;
+ steps--;
}
}
// Move what remains (steps == 1 here always, so we simplify)
- colours[loc+delta] <<= total;
- colours[loc+delta] |= colours[loc] & ((1 << total) - 1);
- colours[loc] >>= total;
- celldat[loc+delta] += total*NUM_INC;
- celldat[loc] -= total*NUM_INC;
+ state->colours[loc + delta] <<= total;
+ state->colours[loc + delta] |= state->colours[loc] & ((1 << total) - 1);
+ state->colours[loc] >>= total;
+ state->celldat[loc + delta] += total * NUM_INC;
+ state->celldat[loc] -= total * NUM_INC;
}
// Next ply
- inline_next_ply();
+ inline_next_ply(state);
}
-void action_undo(const action_t action) {
+void action_undo(tak_state_p state, const action_t action) {
// Previous ply
- inline_prev_ply();
+ inline_prev_ply(state);
const int8_t loc = A_GET_LOC(action);
if (A_GET_TYPE(action) == A_PLACE) {
- const uint8_t black = (current_colour == C_BLACK);
- celldat[loc] = 0;
+ const uint8_t black = (state->current_colour == C_BLACK);
+ state->celldat[loc] = 0;
if (A_GET_DATA0(action) == STONE_CAPSTONE) {
- if (black) black_count |= 0x80;
- else white_count |= 0x80;
+ if (black)
+ state->black_count |= 0x80;
+ else
+ state->white_count |= 0x80;
} else {
- if (black) black_count++;
- else white_count++;
+ if (black)
+ state->black_count++;
+ else
+ state->white_count++;
}
} else {
// See action_take for comments, this is the time reversal, but
// there is one caveat -- undoing a crush! (*)
const uint8_t gaps = A_GET_DATA0(action) & 0x7F,
- crush = A_GET_DATA0(action) & 0x80,
- num = A_GET_DATA1(action) & 0x0F,
- dir = A_GET_DATA1(action) >> 4;
+ crush = A_GET_DATA0(action) & 0x80,
+ num = A_GET_DATA1(action) & 0x0F,
+ dir = A_GET_DATA1(action) >> 4;
const int8_t delta = move_deltas[dir];
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++;
+ state->colours[loc] <<= total;
+ state->colours[loc] |=
+ state->colours[loc + steps * delta] & ((1 << total) - 1);
+ state->colours[loc + steps * delta] >>= total;
+ state->celldat[loc] += total * NUM_INC;
+ state->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;
+ state->colours[loc] <<= total;
+ state->colours[loc] |=
+ state->colours[loc + steps * delta] & ((1 << total) - 1);
+ state->colours[loc + steps * delta] >>= total;
- celldat[loc] += total*NUM_INC;
+ state->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;
+ state->celldat[loc] |= STONE_AT(state, loc + steps * delta);
+ state->celldat[loc + steps * delta] -= total * NUM_INC;
+ state->celldat[loc + steps * delta] &= CLR_STONE;
if (crush) {
- celldat[loc+steps*delta] |= STONE_STANDING;
+ state->celldat[loc + steps * delta] |= STONE_STANDING;
} else {
- celldat[loc+steps*delta] |= STONE_FLAT; // should be optimised out
+ state->celldat[loc + steps * delta] |=
+ STONE_FLAT; // should be optimised out
}
}
}
-void action_to_ptn(const action_t action, char* out_ptn) {
+void action_to_ptn(const action_t action, char *out_ptn) {
const int8_t loc = A_GET_LOC(action);
if (A_GET_TYPE(action) == A_PLACE) {
- generate_place(loc, A_GET_DATA0(action), out_ptn);
+ generate_place(al_board_size, loc, A_GET_DATA0(action), out_ptn);
} else {
const uint8_t gaps = A_GET_DATA0(action) & 0x7F,
- num = A_GET_DATA1(action) & 0x0F, // unpack
- dir = A_GET_DATA1(action) >> 4;
+ num = A_GET_DATA1(action) & 0x0F, // unpack
+ dir = A_GET_DATA1(action) >> 4;
- uint8_t drops[board_size]; // we only ever need board_size-1 in
- // drops actually, the last spot is to
- // skip a bounds check at (**)
+ uint8_t drops[al_board_size]; // we only ever need al_board_size-1 in drops
+ // actually, the last spot is to skip a bounds
+ // check at (**)
uint8_t mask = 1, steps = 0;
// Translate to a drop sequence
- drops[0] = 1; mask = 1;
+ drops[0] = 1;
+ mask = 1;
for (uint8_t d = 1; d < num; d++) {
if (gaps & mask) {
- steps++;
- drops[steps] = 1; // (**) no bounds check
+ steps++;
+ drops[steps] = 1; // (**) no bounds check
} else {
- drops[steps] += 1;
+ drops[steps] += 1;
}
mask <<= 1;
}
- generate_move(loc, dir, steps+1, drops, out_ptn);
+ generate_move(al_board_size, loc, dir, steps + 1, drops, out_ptn);
}
}
@@ -382,10 +406,9 @@ void action_to_ptn(const action_t action, char* out_ptn) {
// Helper method implementations
// ===================================================================
-static inline void
-list_append(action_list_t *list, const enum A_TYPE type,
- const int8_t loc, const uint8_t data0,
- const uint8_t data1) {
+static inline void list_append(action_list_t *list, const enum A_TYPE type,
+ const int8_t loc, const uint8_t data0,
+ const uint8_t data1) {
action_node_t *new = malloc(sizeof(action_node_t));
// TODO: trap errno
@@ -403,10 +426,9 @@ list_append(action_list_t *list, const enum A_TYPE type,
list->length++;
}
-static inline void
-list_prepend(action_list_t *list, const enum A_TYPE type,
- const int8_t loc, const uint8_t data0,
- const uint8_t data1) {
+static inline void list_prepend(action_list_t *list, const enum A_TYPE type,
+ const int8_t loc, const uint8_t data0,
+ const uint8_t data1) {
action_node_t *new = malloc(sizeof(action_list_t));
// TODO: trap errno
@@ -421,24 +443,46 @@ list_prepend(action_list_t *list, const enum A_TYPE type,
list->length++;
}
-static inline void
-inline_next_ply(void) {
- ply++;
- if (ply == 2) {
- current_colour = C_WHITE;
+static inline void inline_next_ply(tak_state_p state) {
+ state->ply++;
+ if (state->ply == 2) {
+ state->current_colour = C_WHITE;
} else {
- if (current_colour == C_BLACK) current_colour = C_WHITE;
- else current_colour = C_BLACK;
+ if (state->current_colour == C_BLACK)
+ state->current_colour = C_WHITE;
+ else
+ state->current_colour = C_BLACK;
}
}
-static inline void
-inline_prev_ply(void) {
- if (ply>0) ply--;
- if (ply == 1) {
- current_colour = C_WHITE;
+static inline void inline_prev_ply(tak_state_p state) {
+ if (state->ply > 0)
+ state->ply--;
+ if (state->ply == 1) {
+ state->current_colour = C_WHITE;
} else {
- if (current_colour == C_BLACK) current_colour = C_WHITE;
- else current_colour = C_BLACK;
+ if (state->current_colour == C_BLACK)
+ state->current_colour = C_WHITE;
+ else
+ state->current_colour = C_BLACK;
+ }
+}
+
+static inline uint8_t check_no_overflow(tak_state_p state, const uint8_t loc,
+ const int8_t delta, const uint8_t num,
+ const uint8_t steps,
+ const uint8_t gaps) {
+ uint8_t total = 1, gap_bit = 1 << (num - 2), step = steps;
+ for (uint8_t d = 1; d < num; d++, total++, gap_bit >>= 1) {
+ if (gaps & gap_bit) {
+ if (COUNT_AT(state, loc + step * delta) + total > 15)
+ return 0;
+ step--;
+ total = 0;
+ }
}
+ if (COUNT_AT(state, loc + delta) + total > 15)
+ return 0;
+
+ return 1;
}
diff --git a/include/actions.h b/include/actions.h
index 8df9392..1550cce 100644
--- a/include/actions.h
+++ b/include/actions.h
@@ -18,8 +18,8 @@
#ifndef ACTIONS_H
#define ACTIONS_H
-#include <stdlib.h>
#include <stdint.h>
+#include <stdlib.h>
#include <tak.h>
@@ -33,16 +33,15 @@ typedef uint32_t action_t;
#define A_DATA1_SHIFT 24
#define A_DATA0_SHIFT 16
-#define A_LOC_SHIFT 8
+#define A_LOC_SHIFT 8
-#define A_GET_DATA1(a) (enum A_TYPE)((a)>>A_DATA1_SHIFT)
-#define A_GET_DATA0(a) (int8_t)(((a)>>A_DATA0_SHIFT) & 0xFF)
-#define A_GET_LOC(a) (uint8_t)(((a)>>A_LOC_SHIFT) & 0xFF)
-#define A_GET_TYPE(a) (uint8_t)((a) & 0xFF)
-#define A_BUILD(type,loc,data0,data1) ((type) \
- | (loc) << A_LOC_SHIFT \
- | (data0) << A_DATA0_SHIFT \
- | (data1) << A_DATA1_SHIFT)
+#define A_GET_DATA1(a) (enum A_TYPE)((a) >> A_DATA1_SHIFT)
+#define A_GET_DATA0(a) (int8_t)(((a) >> A_DATA0_SHIFT) & 0xFF)
+#define A_GET_LOC(a) (uint8_t)(((a) >> A_LOC_SHIFT) & 0xFF)
+#define A_GET_TYPE(a) (uint8_t)((a)&0xFF)
+#define A_BUILD(type, loc, data0, data1) \
+ ((type) | (loc) << A_LOC_SHIFT | (data0) << A_DATA0_SHIFT | \
+ (data1) << A_DATA1_SHIFT)
typedef struct action_node_s {
struct action_node_s *next;
@@ -64,15 +63,15 @@ extern int8_t move_deltas[4];
// Methods
// ===================================================================
-void action_list_init(void);
+void action_list_init(const uint8_t board_size);
void action_list_free(action_list_t *list);
-action_list_t *action_list_generate(void);
+action_list_t *action_list_generate(tak_state_p state);
int action_move_to_front(const action_t action, action_list_t *list);
-void action_take(const action_t action);
-void action_undo(const action_t action);
+void action_take(tak_state_p state, const action_t action);
+void action_undo(tak_state_p state, const action_t action);
-void action_to_ptn(const action_t action, char* out_ptn);
+void action_to_ptn(const action_t action, char *out_ptn);
#endif
diff --git a/include/lcdlib.c b/include/lcdlib.c
index 69d6df0..beced28 100644
--- a/include/lcdlib.c
+++ b/include/lcdlib.c
@@ -17,38 +17,32 @@
#include "lcdlib.h"
-static char previous_lines[LCD_HEIGHT][LCD_WIDTH+1];
-static const char* esc = "\x1B[L";
+static char previous_lines[LCD_HEIGHT][LCD_WIDTH + 1];
+static const char *esc = "\x1B[L";
static FILE *lcd = NULL;
static int line_idx;
-int
-lcd_begin(void) {
+int lcd_begin(void) {
lcd = fopen("/dev/lcd", "w");
- if (lcd == NULL) return EXIT_FAILURE;
+ if (lcd == NULL)
+ return EXIT_FAILURE;
lcd_clear();
return EXIT_SUCCESS;
}
-void
-lcd_end(void) {
- fclose(lcd);
-}
+void lcd_end(void) { fclose(lcd); }
-void
-lcd_set_blink(void) {
+void lcd_set_blink(void) {
fprintf(lcd, "%sB", esc);
fflush(lcd);
}
-void
-lcd_stop_blink(void) {
+void lcd_stop_blink(void) {
fprintf(lcd, "%sb", esc);
fflush(lcd);
}
-void
-lcd_clear(void) {
+void lcd_clear(void) {
line_idx = 0;
for (int y = 0; y + 1 < LCD_HEIGHT; y++) {
fprintf(lcd, "%sy%dx0;%sk", esc, y, esc);
@@ -57,18 +51,17 @@ lcd_clear(void) {
fflush(lcd);
}
-void
-lcd_put_line(const enum LCD_WRITE_MODE mode, const char *line) {
+void lcd_put_line(const enum LCD_WRITE_MODE mode, const char *line) {
char last_line = 0;
if (line_idx == LCD_HEIGHT) {
if (mode == L_SCROLL) {
// If we're at the bottom, ``shift'' everything up
for (int y = 1; y < LCD_HEIGHT; y++) {
- // Go to the start of row y, clear the line, and print the
- // previous string there
- fprintf(lcd, "%sy%dx0;%sk%s", esc, y-1, esc, previous_lines[y]);
- // Overwrite the stored previous line with the next
- strncpy(previous_lines[y-1], previous_lines[y], LCD_WIDTH+1);
+ // Go to the start of row y, clear the line, and print the
+ // previous string there
+ fprintf(lcd, "%sy%dx0;%sk%s", esc, y - 1, esc, previous_lines[y]);
+ // Overwrite the stored previous line with the next
+ strncpy(previous_lines[y - 1], previous_lines[y], LCD_WIDTH + 1);
}
}
last_line = 1;
@@ -77,20 +70,20 @@ lcd_put_line(const enum LCD_WRITE_MODE mode, const char *line) {
fprintf(lcd, "%sy%dx0;%sk%s", esc, line_idx, esc, line);
fflush(lcd);
// Store this line, null-terminate!
- if (last_line) line_idx--;
- strncpy(previous_lines[line_idx], line, LCD_WIDTH+1);
+ if (last_line)
+ line_idx--;
+ strncpy(previous_lines[line_idx], line, LCD_WIDTH + 1);
previous_lines[line_idx][LCD_WIDTH] = 0;
- if (mode == L_SCROLL && line_idx < LCD_HEIGHT) line_idx++;
+ if (mode == L_SCROLL && line_idx < LCD_HEIGHT)
+ line_idx++;
}
-void
-lcd_printf_line(const enum LCD_WRITE_MODE mode,
- const char *format, ...) {
- char buf[LCD_WIDTH+1];
+void lcd_printf_line(const enum LCD_WRITE_MODE mode, const char *format, ...) {
+ char buf[LCD_WIDTH + 1];
va_list(args);
va_start(args, format);
- vsnprintf(buf, LCD_WIDTH+1, format, args);
+ vsnprintf(buf, LCD_WIDTH + 1, format, args);
va_end(args);
lcd_put_line(mode, buf);
diff --git a/include/lcdlib.h b/include/lcdlib.h
index c514ba0..d8225c2 100644
--- a/include/lcdlib.h
+++ b/include/lcdlib.h
@@ -15,16 +15,16 @@
along with ct. If not, see <https://www.gnu.org/licenses/>.
*/
-#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
// ===================================================================
// Types
// ===================================================================
-#define LCD_WIDTH 16
+#define LCD_WIDTH 16
#define LCD_HEIGHT 2
enum LCD_WRITE_MODE { L_OVERWRITE, L_SCROLL };
@@ -42,5 +42,4 @@ void lcd_stop_blink(void);
void lcd_put_line(const enum LCD_WRITE_MODE mode, const char *line);
-void lcd_printf_line(const enum LCD_WRITE_MODE mode,
- const char *format, ...);
+void lcd_printf_line(const enum LCD_WRITE_MODE mode, const char *format, ...);
diff --git a/include/negamax.c b/include/negamax.c
index e85aba9..0f2c450 100644
--- a/include/negamax.c
+++ b/include/negamax.c
@@ -16,6 +16,7 @@
*/
#include "negamax.h"
+#include "actions.h"
// ===================================================================
// Variables
@@ -30,43 +31,40 @@ static uint64_t negamax_best_action;
// Helper declarations
// ===================================================================
-static float negamax(const uint8_t cur_depth, const uint8_t init_depth,
- float alpha, float beta,
- const float colour, const uint64_t hash);
+static float negamax(tak_state_p state, const uint8_t cur_depth,
+ const uint8_t init_depth, float alpha, float beta,
+ const float colour, const uint64_t hash);
// ===================================================================
// Exported functions
// ===================================================================
void negamax_init(const uint8_t new_board_size) {
- board_size = new_board_size;
- action_list_init();
- zobrist_init();
- tt_init();
+ action_list_init(new_board_size);
+ zobrist_init(new_board_size);
+ tt_init();
}
-void negamax_free(void) {
- zobrist_free();
-}
+void negamax_free(void) { zobrist_free(); }
-float negamax_generate(void) {
- // We need to start with something outside of [-∞,∞] because those
- // values are wins
- const float safe_infty = infty + 1;
- float result = -infty;
+float negamax_generate(tak_state_p state) {
+ // We need to start with something outside of [-∞,∞] because those
+ // values are wins
+ const float safe_infty = infty + 1;
+ float result = -infty;
- negamax_best_action = -1;
+ negamax_best_action = -1;
- tt_init();
- for (int d = 1; d <= negamax_search_depth; d++) {
- result = negamax(d, d, -safe_infty, safe_infty,
- (ply & 1) ? +1.0 : -1.0, zobrist_compute());
- }
- tt_free();
+ tt_init();
+ for (int d = 1; d <= negamax_search_depth; d++) {
+ result = negamax(state, d, d, -safe_infty, safe_infty,
+ (state->ply & 1) ? +1.0 : -1.0, zobrist_compute(state));
+ }
+ tt_free();
- action_to_ptn(negamax_best_action, negamax_ptn);
+ action_to_ptn(negamax_best_action, negamax_ptn);
- return result;
+ return result;
}
// ===================================================================
@@ -78,89 +76,95 @@ float negamax_generate(void) {
static enum TT_FLAG flag;
static enum WIN_TYPE w;
-static float negamax(const uint8_t cur_depth, const uint8_t init_depth,
- float alpha, float beta,
- const float colour, const uint64_t hash) {
+static float negamax(tak_state_p state, const uint8_t cur_depth,
+ const uint8_t init_depth, float alpha, float beta,
+ const float colour, const uint64_t hash) {
- tt_entry_t *entry = tt_seek(hash);
+ tt_entry_t *entry = tt_seek(hash);
- // CAUTION: ≥ breaks search stability (vs =) on shallow depths
- if (entry != NULL && entry->depth >= cur_depth) {
- if (entry->flag == TT_EXACT) {
- return entry->value;
- } else if (entry->flag == TT_LOWERBOUND && entry->value > alpha) {
- alpha = entry->value;
- } else if (entry->flag == TT_UPPERBOUND && entry->value < beta) {
- beta = entry->value;
- }
- if (alpha >= beta) return entry->value;
+ // CAUTION: ≥ breaks search stability (vs =) on shallow depths
+ if (entry != NULL && entry->depth >= cur_depth) {
+ if (entry->flag == TT_EXACT) {
+ return entry->value;
+ } else if (entry->flag == TT_LOWERBOUND && entry->value > alpha) {
+ alpha = entry->value;
+ } else if (entry->flag == TT_UPPERBOUND && entry->value < beta) {
+ beta = entry->value;
}
+ if (alpha >= beta)
+ return entry->value;
+ }
- action_list_t *list;
- if ((list = action_list_generate()) == NULL)
- return alpha; // should never happen!
+ action_list_t *list;
+ if ((list = action_list_generate(state)) == NULL)
+ return alpha; // should never happen!
- if (entry != NULL) {
- action_move_to_front(entry->action, list);
- }
-
- if (init_depth > 1 && cur_depth == init_depth) {
- action_move_to_front(negamax_best_action, list);
- }
+ if (entry != NULL) {
+ action_move_to_front(entry->action, list);
+ }
- // TODO: what to do if this is never written to?
- action_t best_action = list->head->action;
- float best_value = -infty;
+ if (init_depth > 1 && cur_depth == init_depth) {
+ action_move_to_front(negamax_best_action, list);
+ }
- for (action_node_t *node=list->head; node!=NULL; node=node->next) {
- negamax_display_progress(cur_depth, init_depth, list->length);
+ // TODO: what to do if this is never written to?
+ action_t best_action = list->head->action;
+ float best_value = -infty;
- action_take(node->action);
+ for (action_node_t *node = list->head; node != NULL; node = node->next) {
+ negamax_display_progress(cur_depth, init_depth, list->length);
- // Compute the value of the node
- float node_value;
- if (ply >= 2*board_size - 2 && (w = check_win()) < 0xFF) {
- node_value = -colour*infty;
- // Check win if far enough into the game
- if (w == WIN_ROAD_BLACK || w == WIN_FLAT_BLACK) {
- node_value = colour*infty;
- } else if (w == WIN_DRAW) {
- node_value = 0;
- }
- } else if (cur_depth > 1) {
- // If nobody won, or too early and not leaf, recurse
- node_value = -negamax(cur_depth - 1, init_depth,
- -beta, -alpha,
- -colour, zobrist_compute());
- } else {
- node_value = colour * nn1986_evaluate_black_win();
- }
- action_undo(node->action);
+ action_take(state, node->action);
- if (node_value > best_value) {
- best_value = node_value;
- best_action = node->action;
- }
+ // Compute the value of the node
+ float node_value;
+ if (state->ply >= 2 * state->board_size - 2 &&
+ (w = check_win(state)) < 0xFF) {
+ node_value = -colour * infty;
+ // Check win if far enough into the game
+ if (w == WIN_ROAD_BLACK || w == WIN_FLAT_BLACK) {
+ node_value = colour * infty;
+ } else if (w == WIN_DRAW) {
+ node_value = 0;
+ }
+ } else if (cur_depth > 1) {
+ // If nobody won, or too early and not leaf, recurse
+ node_value = -negamax(state, cur_depth - 1, init_depth, -beta, -alpha,
+ -colour, zobrist_compute(state));
+ } else {
+ node_value = colour * nn1986_evaluate_black_win(state);
+ }
+ action_undo(state, node->action);
- if (best_value > alpha) alpha = best_value;
- if (alpha >= beta) break;
+ if (node_value > best_value) {
+ best_value = node_value;
+ best_action = node->action;
}
- action_list_free(list);
- if (cur_depth == init_depth) negamax_best_action = best_action;
+ if (best_value > alpha)
+ alpha = best_value;
+ if (alpha >= beta)
+ break;
+ }
- flag = TT_EXACT;
- if (best_value >= beta) flag = TT_LOWERBOUND;
- else if (best_value <= alpha) flag = TT_UPPERBOUND;
+ action_list_free(list);
+ if (cur_depth == init_depth)
+ negamax_best_action = best_action;
- if (entry == NULL) {
- tt_insert(hash, flag, cur_depth, best_value, best_action);
- } else {
- entry->flag = flag;
- entry->value = best_value;
- entry->depth = cur_depth;
- entry->action = best_action;
- }
+ flag = TT_EXACT;
+ if (best_value >= beta)
+ flag = TT_LOWERBOUND;
+ else if (best_value <= alpha)
+ flag = TT_UPPERBOUND;
+
+ if (entry == NULL) {
+ tt_insert(hash, flag, cur_depth, best_value, best_action);
+ } else {
+ entry->flag = flag;
+ entry->value = best_value;
+ entry->depth = cur_depth;
+ entry->action = best_action;
+ }
- return best_value;
+ return best_value;
}
diff --git a/include/negamax.h b/include/negamax.h
index e491baa..eedb7dd 100644
--- a/include/negamax.h
+++ b/include/negamax.h
@@ -15,12 +15,12 @@
along with ct. If not, see <https://www.gnu.org/licenses/>.
*/
-#include <stdint.h>
#include <math.h>
+#include <stdint.h>
-#include <tak.h>
#include <actions.h>
#include <nn1986.h>
+#include <tak.h>
#include <tt_llcht.h>
#include <zobrist.h>
@@ -33,8 +33,8 @@ extern char negamax_ptn[9];
extern uint8_t negamax_search_depth;
extern void negamax_display_progress(const uint8_t cur_depth,
- const uint8_t init_depth,
- const uint32_t length);
+ const uint8_t init_depth,
+ const uint32_t length);
// ===================================================================
// Methods
@@ -50,4 +50,4 @@ void negamax_free(void);
* `negamax_ptn', and return its value. The `negamax_display_progress'
* function is called on every new square at the top level.
*/
-float negamax_generate(void);
+float negamax_generate(tak_state_p state);
diff --git a/include/nn1986.c b/include/nn1986.c
index b9c551c..117a034 100644
--- a/include/nn1986.c
+++ b/include/nn1986.c
@@ -28,22 +28,22 @@ static float dense1[DENSE_NUM];
static float output[2];
#define RELU(x) ((x) = ((x) < 0) ? 0 : (x))
-float nn1986_evaluate_black_win(void) {
+float nn1986_evaluate_black_win(tak_state_p state) {
/* --------------- *
* Populate input *
* --------------- */
- for (unsigned int y = 0; y < board_size; y++) {
- for (unsigned int x = 0; x < board_size; x++) {
- const unsigned int loc = x + y * board_size;
- const unsigned int count = COUNT_AT(loc);
+ for (unsigned int y = 0; y < state->board_size; y++) {
+ for (unsigned int x = 0; x < state->board_size; x++) {
+ const unsigned int loc = x + y * state->board_size;
+ const unsigned int count = COUNT_AT(state, loc);
float lookup = 0;
if (count > 0) {
- if (STONE_AT(loc) == STONE_STANDING) {
- lookup = (colours[loc] & 1) ? +0.25 : -0.25;
- } else if (STONE_AT(loc) == STONE_CAPSTONE) {
- lookup = (colours[loc] & 1) ? +1.00 : -1.00;
+ if (STONE_AT(state, loc) == STONE_STANDING) {
+ lookup = (state->colours[loc] & 1) ? +0.25 : -0.25;
+ } else if (STONE_AT(state, loc) == STONE_CAPSTONE) {
+ lookup = (state->colours[loc] & 1) ? +1.00 : -1.00;
} else {
- lookup = (colours[loc] & 1) ? +0.50 : -0.50;
+ lookup = (state->colours[loc] & 1) ? +0.50 : -0.50;
}
}
cur_board[3 + loc] = lookup;
@@ -53,9 +53,9 @@ float nn1986_evaluate_black_win(void) {
* Convolution layer *
* ------------------ */
// Add input of flat counts and ply parity
- cur_board[0] = (ply & 1) ? 1 : -1;
- cur_board[1] = (float)(white_count & 127) / 21.0;
- cur_board[2] = (float)(black_count & 127) / 21.0;
+ cur_board[0] = (state->ply & 1) ? 1 : -1;
+ cur_board[1] = (float)(state->white_count & 127) / 21.0;
+ cur_board[2] = (float)(state->black_count & 127) / 21.0;
/* ------------------ *
* First dense layer *
* ------------------ */
diff --git a/include/nn1986.h b/include/nn1986.h
index 4e99ac2..02dca0e 100644
--- a/include/nn1986.h
+++ b/include/nn1986.h
@@ -17,4 +17,4 @@
#include <tak.h>
-float nn1986_evaluate_black_win(void);
+float nn1986_evaluate_black_win(tak_state_p state);
diff --git a/include/tak.c b/include/tak.c
index 5fd8e9a..a5f2f44 100644
--- a/include/tak.c
+++ b/include/tak.c
@@ -16,57 +16,55 @@
*/
#include "tak.h"
+#include <stdlib.h>
// ===================================================================
-// Globals
+// Helpers
// ===================================================================
-enum WIN_TYPE won;
-uint8_t board_size;
-data_t celldat[36];
-colour_stack_t colours[36];
-enum COLOUR current_colour;
-uint8_t white_count, black_count, ply;
+#define NUM_SQUARES(board_size) (board_size * board_size)
-// ===================================================================
-// Helpers
-// ===================================================================
+tak_state_p new_tak_state(const uint8_t board_size) {
+ tak_state_p state = malloc(sizeof(struct tak_state_s));
+ reset_state(state, board_size);
+ return state;
+}
-#define NUM_SQUARES (board_size * board_size)
+void free_tak_state(tak_state_p state) { free(state); }
// ===================================================================
// General state stuff
// ===================================================================
-void
-reset_state(const uint8_t new_board_size) {
+void reset_state(tak_state_p state, const uint8_t new_board_size) {
if (new_board_size == 6) {
- board_size = 6;
- white_count = 128 | 30;
- black_count = 128 | 30;
+ state->board_size = 6;
+ state->white_count = 128 | 30;
+ state->black_count = 128 | 30;
} else {
- board_size = 5;
- white_count = 128 | 21;
- black_count = 128 | 21;
+ state->board_size = 5;
+ state->white_count = 128 | 21;
+ state->black_count = 128 | 21;
}
- ply = 0;
- won = 0xFF; // i may live to regret this hack
- current_colour = C_BLACK;
+ state->ply = 0;
+ state->won = 0xFF; // i may live to regret this hack
+ state->current_colour = C_BLACK;
- for (uint8_t k = 0; k < NUM_SQUARES; k++ ) {
- celldat[k] = 0;
+ for (uint8_t k = 0; k < NUM_SQUARES(new_board_size); k++) {
+ state->celldat[k] = 0;
}
}
-void
-next_ply(void) {
- ply++;
- if (ply == 2) {
- current_colour = C_WHITE;
+void next_ply(tak_state_p state) {
+ state->ply++;
+ if (state->ply == 2) {
+ state->current_colour = C_WHITE;
} else {
- if (current_colour == C_BLACK) current_colour = C_WHITE;
- else current_colour = C_BLACK;
+ if (state->current_colour == C_BLACK)
+ state->current_colour = C_WHITE;
+ else
+ state->current_colour = C_BLACK;
}
}
@@ -74,47 +72,57 @@ next_ply(void) {
// Placing stones
// ===================================================================
-enum ACT_RESULT
-try_place(const int8_t location, const enum COLOUR colour,
- const enum STONE_VARIANT stone)
-{
+enum ACT_RESULT try_place(tak_state_p state, const int8_t location,
+ const enum COLOUR colour,
+ const enum STONE_VARIANT stone) {
// Game is over?
- if (won < 0xFF) return GAME_END;
+ if (state->won < 0xFF)
+ return GAME_END;
// Can't place on an occupied square
- if (COUNT_AT(location)) {
+ if (COUNT_AT(state, location)) {
return ACT_ILLEGAL;
} else {
switch (stone) {
- case STONE_STANDING:
- if (ply < 2) return ACT_ILLEGAL;
- // behold the magic GCC comment which defeates
- // -Wimplicit-fallthrough:
- // fall through
- case STONE_FLAT: {
- if (colour == C_BLACK) {
- if (black_count & 127) black_count--;
- else return ACT_ILLEGAL;
- } else {
- if (white_count & 127) white_count--;
- else return ACT_ILLEGAL;
- }
- break;
+ case STONE_STANDING:
+ if (state->ply < 2)
+ return ACT_ILLEGAL;
+ // behold the magic GCC comment which defeates
+ // -Wimplicit-fallthrough:
+ // fall through
+ case STONE_FLAT: {
+ if (colour == C_BLACK) {
+ if (state->black_count & 127)
+ state->black_count--;
+ else
+ return ACT_ILLEGAL;
+ } else {
+ if (state->white_count & 127)
+ state->white_count--;
+ else
+ return ACT_ILLEGAL;
}
- case STONE_CAPSTONE: {
- if (ply < 2) return ACT_ILLEGAL;
- if (colour == C_BLACK) {
- if (black_count & 128) black_count &= 127;
- else return ACT_ILLEGAL;
- } else {
- if (white_count & 128) white_count &= 127;
- else return ACT_ILLEGAL;
- }
- break;
+ break;
+ }
+ case STONE_CAPSTONE: {
+ if (state->ply < 2)
+ return ACT_ILLEGAL;
+ if (colour == C_BLACK) {
+ if (state->black_count & 128)
+ state->black_count &= 127;
+ else
+ return ACT_ILLEGAL;
+ } else {
+ if (state->white_count & 128)
+ state->white_count &= 127;
+ else
+ return ACT_ILLEGAL;
}
+ break;
+ }
}
- colours[location] = colour;
- celldat[location] = NUM_INC | stone;
+ state->colours[location] = colour;
+ state->celldat[location] = NUM_INC | stone;
return ACT_OK;
}
}
@@ -123,59 +131,63 @@ try_place(const int8_t location, const enum COLOUR colour,
// Moving stacks
// ===================================================================
-static inline void
-push_stones(const int8_t location, const uint8_t count,
- const uint8_t new_colours,
- const enum STONE_VARIANT top_stone) {
- colours[location] = (colours[location] << count) | new_colours;
- celldat[location] = top_stone
- | ((celldat[location] + ((count << NUM_SHIFT))) & NUM_MASK);
+static inline void push_stones(tak_state_p state, const int8_t location,
+ const uint8_t count, const uint8_t new_colours,
+ const enum STONE_VARIANT top_stone) {
+ state->colours[location] = (state->colours[location] << count) | new_colours;
+ state->celldat[location] =
+ top_stone |
+ ((state->celldat[location] + ((count << NUM_SHIFT))) & NUM_MASK);
}
-enum ACT_RESULT
-try_move(const int8_t location, const enum MOVE_DIRECTION direction,
- const uint8_t steps, const uint8_t drops[5]) {
+enum ACT_RESULT try_move(tak_state_p state, const int8_t location,
+ const enum MOVE_DIRECTION direction,
+ const uint8_t steps, const uint8_t drops[5]) {
// Game is over?
- if (won < 0xFF) return GAME_END;
+ if (state->won < 0xFF)
+ return GAME_END;
// Can't do this
- if (steps == 0 || steps > board_size) return ACT_ILLEGAL;
+ if (steps == 0 || steps > state->board_size)
+ return ACT_ILLEGAL;
// Check for stones at all
- const uint8_t avail = COUNT_AT(location);
- if (avail == 0) return ACT_ILLEGAL;
+ const uint8_t avail = COUNT_AT(state, location);
+ if (avail == 0)
+ return ACT_ILLEGAL;
// Does the current player own the pile?
- if ((colours[location] & 1) != current_colour) return ACT_ILLEGAL;
+ if ((state->colours[location] & 1) != state->current_colour)
+ return ACT_ILLEGAL;
// Is the desired direction and count on the board?
int8_t delta = 0;
switch (direction) {
- case M_UP: {
- delta = +board_size;
- if (location + delta * steps > NUM_SQUARES)
- return ACT_ILLEGAL;
- break;
- };
- case M_DOWN: {
- delta = -board_size;
- if (location + delta * steps < 0)
- return ACT_ILLEGAL;
- break;
- };
- case M_RIGHT: {
- delta = +1;
- if ((location + steps * delta) / board_size
- > location / board_size)
- return ACT_ILLEGAL;
- break;
- };
- case M_LEFT: {
- delta = -1;
- // We need the extra check for zero here because, irritatingly,
- // -1 / board_size == 1 / board_size
- if ((location + steps * delta < 0) ||
- ((location + steps * delta) / board_size
- < location / board_size))
- return ACT_ILLEGAL;
- break;
- };
+ case M_UP: {
+ delta = +state->board_size;
+ if (location + delta * steps > NUM_SQUARES(state->board_size))
+ return ACT_ILLEGAL;
+ break;
+ };
+ case M_DOWN: {
+ delta = -state->board_size;
+ if (location + delta * steps < 0)
+ return ACT_ILLEGAL;
+ break;
+ };
+ case M_RIGHT: {
+ delta = +1;
+ if ((location + steps * delta) / state->board_size >
+ location / state->board_size)
+ return ACT_ILLEGAL;
+ break;
+ };
+ case M_LEFT: {
+ delta = -1;
+ // We need the extra check for zero here because, irritatingly,
+ // -1 / board_size == 1 / board_size
+ if ((location + steps * delta < 0) ||
+ ((location + steps * delta) / state->board_size <
+ location / state->board_size))
+ return ACT_ILLEGAL;
+ break;
+ };
};
// For every square in the direction
@@ -185,27 +197,25 @@ try_move(const int8_t location, const enum MOVE_DIRECTION direction,
if (drops[k] == 0)
return ACT_ILLEGAL;
// Can't drop more than BOARD_SIZE stones in a square
- if (drops[k] > board_size)
+ if (drops[k] > state->board_size)
return ACT_ILLEGAL;
// Check for overflows
- if (COUNT_AT(location+(k+1)*delta) + drops[k] > 0x0F)
+ if (COUNT_AT(state, location + (k + 1) * delta) + drops[k] > 0x0F)
return ACT_OVERFLOW;
// Check for capstone
- if (STONE_AT(location+(k+1)*delta) == STONE_CAPSTONE)
+ if (STONE_AT(state, location + (k + 1) * delta) == STONE_CAPSTONE)
return ACT_ILLEGAL;
// Check for wall
- if ( (STONE_AT(location+(k+1)*delta) == STONE_STANDING)
- // If not last drop, or not dropping just one, or not a cap
- && ( (k+1 < steps)
- || (drops[k] != 1)
- || (STONE_AT(location) != STONE_CAPSTONE) )
- )
+ if ((STONE_AT(state, location + (k + 1) * delta) == STONE_STANDING)
+ // If not last drop, or not dropping just one, or not a cap
+ && ((k + 1 < steps) || (drops[k] != 1) ||
+ (STONE_AT(state, location) != STONE_CAPSTONE)))
return ACT_ILLEGAL;
total += drops[k];
}
// Can't ask to move 0, more than board_size, or stones available
- if ( (total == 0) || (total > board_size) || (total > avail) )
+ if ((total == 0) || (total > state->board_size) || (total > avail))
return ACT_ILLEGAL;
// Nothing illegal, do it. First we add the stones to the
@@ -213,15 +223,14 @@ try_move(const int8_t location, const enum MOVE_DIRECTION direction,
uint8_t j = total;
for (uint8_t k = 0; k < steps; k++) {
j -= drops[k];
- push_stones(location+(k+1)*delta,
- drops[k],
- (colours[location] >> j) & (0xFFFF >> (0x10 - drops[k])),
- (k == steps - 1) ? STONE_AT(location) : STONE_FLAT);
+ push_stones(state, location + (k + 1) * delta, drops[k],
+ (state->colours[location] >> j) & (0xFFFF >> (0x10 - drops[k])),
+ (k == steps - 1) ? STONE_AT(state, location) : STONE_FLAT);
}
// Then we drop them from the source
- colours[location] >>= total;
- const uint8_t dec_count = celldat[location] - (total << NUM_SHIFT);
- celldat[location] = dec_count & NUM_MASK;
+ state->colours[location] >>= total;
+ const uint8_t dec_count = state->celldat[location] - (total << NUM_SHIFT);
+ state->celldat[location] = dec_count & NUM_MASK;
return ACT_OK;
}
@@ -231,9 +240,10 @@ try_move(const int8_t location, const enum MOVE_DIRECTION direction,
// ===================================================================
// Check for the presence of a road connecting opposite sides
-static enum WIN_TYPE
-check_road_colour(const enum COLOUR colour) {
- int component[NUM_SQUARES], touching[NUM_SQUARES];
+static enum WIN_TYPE check_road_colour(tak_state_p state,
+ const enum COLOUR colour) {
+ int component[NUM_SQUARES(state->board_size)],
+ touching[NUM_SQUARES(state->board_size)];
/*
We're doing a poor version of a disjoint set data structure to
@@ -249,10 +259,10 @@ check_road_colour(const enum COLOUR colour) {
the same reason we also don't do path flattening/halving or
anything.
*/
- for (int k=0; k<NUM_SQUARES; k++) {
+ for (int k = 0; k < NUM_SQUARES(state->board_size); k++) {
component[k] = k; // every square is in its own connected
// component initially
- touching[k] = 0; // and not connected to any sides
+ touching[k] = 0; // and not connected to any sides
}
// touching is the bit mask for connectivity,
@@ -260,90 +270,95 @@ check_road_colour(const enum COLOUR colour) {
// 1 2 4 8
int touch = 5;
- for (int row = 0; row < board_size; row++) {
- for (int col = 0; col < board_size; col++) {
- const int cur = THE_COORDS(col, row);
- if (COUNT_AT(cur)
- && (colours[cur] & 1) == colour
- && STONE_AT(cur) != STONE_STANDING) {
+ for (int row = 0; row < state->board_size; row++) {
+ for (int col = 0; col < state->board_size; col++) {
+ const int cur = THE_COORDS(state->board_size, col, row);
+ if (COUNT_AT(state, cur) && (state->colours[cur] & 1) == colour &&
+ STONE_AT(state, cur) != STONE_STANDING) {
- // do we have any neighbours to the left and below?
- const int left_neighbour = ((cur % board_size > 0)
- && (COUNT_AT(cur - 1)) // wont ever be out of bounds
- && ((colours[cur - 1] & 1) == colour)
- && (STONE_AT(cur - 1) != STONE_STANDING));
+ // do we have any neighbours to the left and below?
+ const int left_neighbour =
+ ((cur % state->board_size > 0) &&
+ (COUNT_AT(state, cur - 1)) // wont ever be out of bounds
+ && ((state->colours[cur - 1] & 1) == colour) &&
+ (STONE_AT(state, cur - 1) != STONE_STANDING));
- const int lowr_neighbour = ((cur >= board_size)
- && (COUNT_AT(cur - board_size))
- && ((colours[cur - board_size] & 1) == colour)
- && (STONE_AT(cur - board_size) != STONE_STANDING));
+ const int lowr_neighbour =
+ ((cur >= state->board_size) &&
+ (COUNT_AT(state, cur - state->board_size)) &&
+ ((state->colours[cur - state->board_size] & 1) == colour) &&
+ (STONE_AT(state, cur - state->board_size) != STONE_STANDING));
- // always take the component of the lower neighbour if
- // possible, failing that take the left neighbour, otherwise
- // we're not yet connected, so update our own component.
- if (lowr_neighbour) {
- // look up the root of the lower neighbour
- int root = cur - board_size;
- while (root != component[root])
- root = component[root];
- // join the set
- component[cur] = root;
- if (touch) {
- // something new
- touching[root] |= touch;
- // are we done?
- if ( (touching[root] & 0x3) == 0x3 || (touching[root] & 0xC) == 0xC)
- return (colour == C_BLACK) ? WIN_ROAD_BLACK : WIN_ROAD_WHITE;
- }
- // if we also have a left neighbour then we should `merge'
- // sets, and here we assume that the left neighbour set is
- // always smaller (may not be) for the direction of merge
- if (left_neighbour) {
- int left_root = cur - 1;
- while (left_root != component[left_root])
- left_root = component[left_root];
- // merge
- const int left_touch = touching[left_root];
- if (left_touch) {
- touching[root] |= left_touch;
- if ( (touching[root] & 0x3) == 0x3 || (touching[root] & 0xC) == 0xC)
- return (colour == C_BLACK) ? WIN_ROAD_BLACK : WIN_ROAD_WHITE;
- }
- component[left_root] = root;
- }
- } else if (left_neighbour) {
- int root = cur - 1;
- while (root != component[root])
- root = component[root];
- component[cur] = root;
- if (touch) {
- touching[root] |= touch;
- if ( (touching[root] & 0x3) == 0x3 || (touching[root] & 0xC) == 0xC)
- return (colour == C_BLACK) ? WIN_ROAD_BLACK : WIN_ROAD_WHITE;
- }
- } else if (touch) {
- // we had no left or lower neighbour, so we're on our own
- touching[cur] = touch;
- }
+ // always take the component of the lower neighbour if
+ // possible, failing that take the left neighbour, otherwise
+ // we're not yet connected, so update our own component.
+ if (lowr_neighbour) {
+ // look up the root of the lower neighbour
+ int root = cur - state->board_size;
+ while (root != component[root])
+ root = component[root];
+ // join the set
+ component[cur] = root;
+ if (touch) {
+ // something new
+ touching[root] |= touch;
+ // are we done?
+ if ((touching[root] & 0x3) == 0x3 || (touching[root] & 0xC) == 0xC)
+ return (colour == C_BLACK) ? WIN_ROAD_BLACK : WIN_ROAD_WHITE;
+ }
+ // if we also have a left neighbour then we should `merge'
+ // sets, and here we assume that the left neighbour set is
+ // always smaller (may not be) for the direction of merge
+ if (left_neighbour) {
+ int left_root = cur - 1;
+ while (left_root != component[left_root])
+ left_root = component[left_root];
+ // merge
+ const int left_touch = touching[left_root];
+ if (left_touch) {
+ touching[root] |= left_touch;
+ if ((touching[root] & 0x3) == 0x3 ||
+ (touching[root] & 0xC) == 0xC)
+ return (colour == C_BLACK) ? WIN_ROAD_BLACK : WIN_ROAD_WHITE;
+ }
+ component[left_root] = root;
+ }
+ } else if (left_neighbour) {
+ int root = cur - 1;
+ while (root != component[root])
+ root = component[root];
+ component[cur] = root;
+ if (touch) {
+ touching[root] |= touch;
+ if ((touching[root] & 0x3) == 0x3 || (touching[root] & 0xC) == 0xC)
+ return (colour == C_BLACK) ? WIN_ROAD_BLACK : WIN_ROAD_WHITE;
+ }
+ } else if (touch) {
+ // we had no left or lower neighbour, so we're on our own
+ touching[cur] = touch;
+ }
}
- if (col + 2 == board_size) touch |= 8;
- else touch &= 0x3;
+ if (col + 2 == state->board_size)
+ touch |= 8;
+ else
+ touch &= 0x3;
}
- if (row + 2 == board_size) touch = 6;
- else touch = 4;
+ if (row + 2 == state->board_size)
+ touch = 6;
+ else
+ touch = 4;
}
return 0xFF;
}
-enum WIN_TYPE
-check_win(void) {
+enum WIN_TYPE check_win(tak_state_p state) {
// Road?
enum WIN_TYPE rb, rw;
- rb = check_road_colour(C_BLACK);
- rw = check_road_colour(C_WHITE);
+ rb = check_road_colour(state, C_BLACK);
+ rw = check_road_colour(state, C_WHITE);
if (rb == WIN_ROAD_BLACK && rw == WIN_ROAD_WHITE) {
- return (ply & 1) ? rb : rw; // Dragons
+ return (state->ply & 1) ? rb : rw; // Dragons
} else if (rw == WIN_ROAD_WHITE) {
return rw;
} else if (rb == WIN_ROAD_BLACK) {
@@ -352,18 +367,21 @@ check_win(void) {
// Do we do a flat count?
int8_t total = 0, board_full = 1;
- for (uint8_t k = 0; k < NUM_SQUARES; k++) {
- if (COUNT_AT(k) == 0) {
+ for (uint8_t k = 0; k < NUM_SQUARES(state->board_size); k++) {
+ if (COUNT_AT(state, k) == 0) {
board_full = 0;
- } else if (STONE_AT(k) == STONE_FLAT) {
- total += ((colours[k] & 1) == C_BLACK) ? +1 : -1 ;
+ } else if (STONE_AT(state, k) == STONE_FLAT) {
+ total += ((state->colours[k] & 1) == C_BLACK) ? +1 : -1;
}
}
- if (black_count == 0 || white_count == 0 || board_full) {
+ if (state->black_count == 0 || state->white_count == 0 || board_full) {
// Decide based on count
- if (total > 0) return WIN_FLAT_BLACK;
- else if (total < 0) return WIN_FLAT_WHITE;
- else return WIN_DRAW;
+ if (total > 0)
+ return WIN_FLAT_BLACK;
+ else if (total < 0)
+ return WIN_FLAT_WHITE;
+ else
+ return WIN_DRAW;
}
return 0xFF;
@@ -372,38 +390,57 @@ check_win(void) {
// PTN place parser
// ===================================================================
-#define NULL 0
-
-#define ASSERT_NONEMPTY { \
- if (ptn == NULL || *ptn == 0) return PTN_INVALID; \
+#define ASSERT_NONEMPTY \
+ { \
+ if (ptn == NULL || *ptn == 0) \
+ return PTN_INVALID; \
}
-#define ASSERT_MORE { if (*ptn == 0) return PTN_INVALID; }
+#define ASSERT_MORE \
+ { \
+ if (*ptn == 0) \
+ return PTN_INVALID; \
+ }
-enum PTN_RESULT
-parse_place(char *ptn, uint8_t *out_location,
- enum STONE_VARIANT *out_stone) {
+enum PTN_RESULT parse_place(const uint8_t board_size, char *ptn,
+ uint8_t *out_location,
+ enum STONE_VARIANT *out_stone) {
ASSERT_NONEMPTY;
*out_stone = STONE_FLAT;
switch (*ptn) {
- case 'C' : { ptn++; *out_stone = STONE_CAPSTONE; break; };
- case 'S' : { ptn++; *out_stone = STONE_STANDING; break; };
- case 'F' : { ptn++; break; };
+ case 'C': {
+ ptn++;
+ *out_stone = STONE_CAPSTONE;
+ break;
+ };
+ case 'S': {
+ ptn++;
+ *out_stone = STONE_STANDING;
+ break;
+ };
+ case 'F': {
+ ptn++;
+ break;
+ };
}
ASSERT_MORE;
- if ( (*ptn < 'a') || (*ptn > '`' + board_size) ) return PTN_INVALID;
+ if ((*ptn < 'a') || (*ptn > '`' + board_size))
+ return PTN_INVALID;
*out_location = *ptn - 'a';
- ptn++; ASSERT_MORE;
+ ptn++;
+ ASSERT_MORE;
- if ( (*ptn < '1') || (*ptn > board_size + '0') ) return PTN_INVALID;
+ if ((*ptn < '1') || (*ptn > board_size + '0'))
+ return PTN_INVALID;
*out_location += board_size * (*ptn - '1');
- if (*(++ptn) > 0) return PTN_INVALID;
+ if (*(++ptn) > 0)
+ return PTN_INVALID;
return PTN_OK;
}
@@ -412,40 +449,58 @@ parse_place(char *ptn, uint8_t *out_location,
// PTN move parser
// ===================================================================
-enum PTN_RESULT
-parse_move(char *ptn, uint8_t *out_location,
- enum MOVE_DIRECTION *out_direction,
- uint8_t *out_steps, uint8_t out_drops[5]) {
+enum PTN_RESULT parse_move(const uint8_t board_size, char *ptn,
+ uint8_t *out_location,
+ enum MOVE_DIRECTION *out_direction,
+ uint8_t *out_steps, uint8_t out_drops[5]) {
ASSERT_NONEMPTY;
uint8_t picked_up = 1;
// Optionally indicate how many stones picked up
- if ( (*ptn >= '1') && (*ptn <= '0' + board_size)) {
+ if ((*ptn >= '1') && (*ptn <= '0' + board_size)) {
picked_up = *ptn - '0';
- ptn++; ASSERT_MORE;
+ ptn++;
+ ASSERT_MORE;
}
// column must be on the board
- if ( (*ptn < 'a') || (*ptn > '`' + board_size) ) return PTN_INVALID;
+ if ((*ptn < 'a') || (*ptn > '`' + board_size))
+ return PTN_INVALID;
*out_location = *ptn - 'a';
- ptn++; ASSERT_MORE;
+ ptn++;
+ ASSERT_MORE;
// row must be on the board
- if ( (*ptn < '1') || (*ptn > board_size + '0') ) return PTN_INVALID;
+ if ((*ptn < '1') || (*ptn > board_size + '0'))
+ return PTN_INVALID;
*out_location += board_size * (*ptn - '1');
- ptn++; ASSERT_MORE;
+ ptn++;
+ ASSERT_MORE;
// valid direction
switch (*ptn) {
- case '+': { *out_direction = M_UP; break; }
- case '-': { *out_direction = M_DOWN; break; }
- case '<': { *out_direction = M_LEFT; break; }
- case '>': { *out_direction = M_RIGHT; break; }
- default: return PTN_INVALID;
+ case '+': {
+ *out_direction = M_UP;
+ break;
+ }
+ case '-': {
+ *out_direction = M_DOWN;
+ break;
+ }
+ case '<': {
+ *out_direction = M_LEFT;
+ break;
+ }
+ case '>': {
+ *out_direction = M_RIGHT;
+ break;
+ }
+ default:
+ return PTN_INVALID;
}
// Handle the case 'n<column><row><direction>' as
@@ -463,11 +518,11 @@ parse_move(char *ptn, uint8_t *out_location,
uint8_t total = 0;
while (*ptn) {
// can't drop more than the carry limit, or less than 1
- if ( (*ptn < '1') || (*ptn > '0' + board_size) )
+ if ((*ptn < '1') || (*ptn > '0' + board_size))
return PTN_INVALID;
// can't move more than the size of the board in any direction
- if ( (*out_steps + 1 >= board_size) && *ptn)
+ if ((*out_steps + 1 >= board_size) && *ptn)
return PTN_INVALID;
out_drops[*out_steps] = *ptn - '0';
@@ -477,7 +532,8 @@ parse_move(char *ptn, uint8_t *out_location,
}
// Mismatch between number of stones picked up and total dropped
- if ( total != picked_up ) return PTN_INVALID;
+ if (total != picked_up)
+ return PTN_INVALID;
return PTN_OK;
}
@@ -486,16 +542,27 @@ parse_move(char *ptn, uint8_t *out_location,
// Generate PTN for place
// ===================================================================
-void
-generate_place(const uint8_t in_location,
- const enum STONE_VARIANT in_stone, char out_ptn[4]) {
+void generate_place(const uint8_t board_size, const uint8_t in_location,
+ const enum STONE_VARIANT in_stone, char out_ptn[4]) {
switch (in_stone) {
- case STONE_FLAT: { break; }
- case STONE_STANDING: { *out_ptn = 'S'; out_ptn++; break; }
- case STONE_CAPSTONE: { *out_ptn = 'C'; out_ptn++; break; }
+ case STONE_FLAT: {
+ break;
+ }
+ case STONE_STANDING: {
+ *out_ptn = 'S';
+ out_ptn++;
+ break;
+ }
+ case STONE_CAPSTONE: {
+ *out_ptn = 'C';
+ out_ptn++;
+ break;
}
- *out_ptn = 'a' + (in_location % board_size); out_ptn++;
- *out_ptn = '1' + (in_location / board_size); out_ptn++;
+ }
+ *out_ptn = 'a' + (in_location % board_size);
+ out_ptn++;
+ *out_ptn = '1' + (in_location / board_size);
+ out_ptn++;
*out_ptn = 0;
}
@@ -503,29 +570,46 @@ generate_place(const uint8_t in_location,
// Generate PTN for move
// ===================================================================
-void
-generate_move(const uint8_t in_location,
- const enum MOVE_DIRECTION in_direction,
- const uint8_t in_steps, const uint8_t in_drops[5],
- char out_ptn[10]) {
+void generate_move(const uint8_t board_size, const uint8_t in_location,
+ const enum MOVE_DIRECTION in_direction,
+ const uint8_t in_steps, const uint8_t in_drops[5],
+ char out_ptn[10]) {
uint8_t total = 0;
- for (uint8_t k = 0; k<in_steps; k++) total+=in_drops[k];
+ for (uint8_t k = 0; k < in_steps; k++)
+ total += in_drops[k];
if (total > 1) {
- *out_ptn = '0' + total; out_ptn++;
+ *out_ptn = '0' + total;
+ out_ptn++;
}
- *out_ptn = 'a' + (in_location % board_size); out_ptn++;
- *out_ptn = '1' + (in_location / board_size); out_ptn++;
+ *out_ptn = 'a' + (in_location % board_size);
+ out_ptn++;
+ *out_ptn = '1' + (in_location / board_size);
+ out_ptn++;
switch (in_direction) {
- case M_UP: { *out_ptn = '+'; break; }
- case M_DOWN: { *out_ptn = '-'; break; }
- case M_LEFT: { *out_ptn = '<'; break; }
- case M_RIGHT: { *out_ptn = '>'; break; }
- }; out_ptn++;
+ case M_UP: {
+ *out_ptn = '+';
+ break;
+ }
+ case M_DOWN: {
+ *out_ptn = '-';
+ break;
+ }
+ case M_LEFT: {
+ *out_ptn = '<';
+ break;
+ }
+ case M_RIGHT: {
+ *out_ptn = '>';
+ break;
+ }
+ };
+ out_ptn++;
for (uint8_t k = 0; (total > 1) && (k < in_steps); k++) {
- *out_ptn = '0' + in_drops[k]; out_ptn++;
+ *out_ptn = '0' + in_drops[k];
+ out_ptn++;
}
*out_ptn = 0;
@@ -535,24 +619,26 @@ generate_move(const uint8_t in_location,
// Driver
// ===================================================================
-static uint8_t
-is_not_placement(char *ptn) {
- if (ptn == 0) return 0;
- for (;;ptn++) {
+static uint8_t is_not_placement(char *ptn) {
+ if (ptn == 0)
+ return 0;
+ for (;; ptn++) {
switch (*ptn) {
- case '+':
- case '-':
- case '>':
- case '<': return 1;
- case 0: return 0;
+ case '+':
+ case '-':
+ case '>':
+ case '<':
+ return 1;
+ case 0:
+ return 0;
}
}
}
-enum ACT_RESULT
-do_ptn(char *ptn) {
+enum ACT_RESULT do_ptn(tak_state_p state, char *ptn) {
// Game over?
- if (won < 0xFF) return GAME_END;
+ if (state->won < 0xFF)
+ return GAME_END;
enum PTN_RESULT ptn_res;
enum ACT_RESULT act_res;
@@ -563,11 +649,13 @@ do_ptn(char *ptn) {
uint8_t steps, drops[5];
enum MOVE_DIRECTION direction;
// Parse it as a move
- ptn_res = parse_move(ptn, &location, &direction, &steps, drops);
+ ptn_res = parse_move(state->board_size, ptn, &location, &direction, &steps,
+ drops);
// If valid PTN, try to do it
if (ptn_res == PTN_OK) {
- if (ply < 2) return ACT_ILLEGAL;
- act_res = try_move(location, direction, steps, drops);
+ if (state->ply < 2)
+ return ACT_ILLEGAL;
+ act_res = try_move(state, location, direction, steps, drops);
} else {
return ACT_INVALID_PTN;
}
@@ -575,10 +663,10 @@ do_ptn(char *ptn) {
// It was not a move
enum STONE_VARIANT stone;
// Was it a valid placement?
- ptn_res = parse_place(ptn, &location, &stone);
+ ptn_res = parse_place(state->board_size, ptn, &location, &stone);
// If so, try it
if (ptn_res == PTN_OK)
- act_res = try_place(location, current_colour, stone);
+ act_res = try_place(state, location, state->current_colour, stone);
else
return ACT_INVALID_PTN;
}
@@ -586,16 +674,16 @@ do_ptn(char *ptn) {
if (act_res == ACT_OK) {
// Don't bother checking that the game was won early on, could be
// more conservative here :)
- if (ply >= board_size) {
- won = check_win();
- if (won < 0xFF) {
- // Winning move, but no need to update current colour
- ply++;
- return GAME_END;
+ if (state->ply >= state->board_size) {
+ state->won = check_win(state);
+ if (state->won < 0xFF) {
+ // Winning move, but no need to update current colour
+ state->ply++;
+ return GAME_END;
}
}
// Only step if the game isn't over yet
- next_ply();
+ next_ply(state);
}
return act_res;
}
diff --git a/include/tak.h b/include/tak.h
index 26f4ae6..9f458f6 100644
--- a/include/tak.h
+++ b/include/tak.h
@@ -49,60 +49,61 @@ enum WIN_TYPE {
typedef uint8_t data_t;
typedef uint16_t colour_stack_t;
+typedef struct tak_state_s {
+ data_t celldat[36];
+ colour_stack_t colours[36];
+ enum WIN_TYPE won;
+ enum COLOUR current_colour;
+ uint8_t white_count, black_count, ply, board_size;
+} * tak_state_p;
+
#define NUM_SHIFT 4
#define NUM_MASK (0xF << NUM_SHIFT) // 0b11110000
#define NUM_INC (0x1 << NUM_SHIFT) // 0b00010000
#define STONE_MASK 3 // 0b00000011
-#define STONE_AT(l) (celldat[(l)] & STONE_MASK)
-#define COUNT_AT(l) (celldat[(l)] >> NUM_SHIFT)
-#define THE_COORDS(col, row) ((col) + (row)*board_size)
-
-// ===================================================================
-// Variables
-// ===================================================================
-
-// NOTE: We only support one capstone per player and 5s or 6s games.
-
-extern enum WIN_TYPE won;
-extern uint8_t board_size;
-extern data_t celldat[36];
-extern colour_stack_t colours[36];
-extern enum COLOUR current_colour;
-extern uint8_t white_count, black_count, ply;
+#define STONE_AT(state, l) (state->celldat[(l)] & STONE_MASK)
+#define COUNT_AT(state, l) (state->celldat[(l)] >> NUM_SHIFT)
+#define THE_COORDS(board_size, col, row) ((col) + (row)*board_size)
// ===================================================================
// Methods
// ===================================================================
+tak_state_p new_tak_state(const uint8_t board_size);
+void free_tak_state(tak_state_p state);
+
// -------------------------------------------------------------------
// Game state
-void reset_state(const uint8_t new_board_size);
-void next_ply(void);
+void reset_state(tak_state_p state, const uint8_t new_board_size);
+void next_ply(tak_state_p state);
-enum ACT_RESULT try_place(const int8_t location, const enum COLOUR colour,
+enum ACT_RESULT try_place(tak_state_p state, const int8_t location,
+ const enum COLOUR colour,
const enum STONE_VARIANT stone);
-enum ACT_RESULT try_move(const int8_t location,
+enum ACT_RESULT try_move(tak_state_p state, const int8_t location,
const enum MOVE_DIRECTION direction,
const uint8_t steps, const uint8_t drops[5]);
-enum WIN_TYPE check_win(void);
+enum WIN_TYPE check_win(tak_state_p state);
// -------------------------------------------------------------------
// PTN related
-enum PTN_RESULT parse_place(char *in_ptn, uint8_t *out_location,
+enum PTN_RESULT parse_place(const uint8_t board_size, char *in_ptn,
+ uint8_t *out_location,
enum STONE_VARIANT *out_stone);
-enum PTN_RESULT parse_move(char *in_ptn, uint8_t *out_location,
+enum PTN_RESULT parse_move(const uint8_t board_size, char *in_ptn,
+ uint8_t *out_location,
enum MOVE_DIRECTION *out_direction,
uint8_t *out_steps, uint8_t out_drops[5]);
-void generate_place(const uint8_t in_location,
+void generate_place(const uint8_t board_size, const uint8_t in_location,
const enum STONE_VARIANT in_stone, char out_ptn[4]);
-void generate_move(const uint8_t in_location,
+void generate_move(const uint8_t board_size, const uint8_t in_location,
const enum MOVE_DIRECTION in_direction,
const uint8_t in_steps, const uint8_t in_drops[5],
char out_ptn[10]);
@@ -110,5 +111,5 @@ void generate_move(const uint8_t in_location,
// -------------------------------------------------------------------
// Game driver
-enum ACT_RESULT do_ptn(char *ptn);
+enum ACT_RESULT do_ptn(tak_state_p state, char *ptn);
#endif
diff --git a/include/tps.c b/include/tps.c
index 7be0e8d..ad0fe21 100644
--- a/include/tps.c
+++ b/include/tps.c
@@ -4,134 +4,166 @@
// Load TPS string
// ===================================================================
-#define TPS_ASSERT_MORE { if (*tps == 0) return TPS_INVALID; }
+#define TPS_ASSERT_MORE \
+ { \
+ if (*tps == 0) \
+ return TPS_INVALID; \
+ }
-enum TPS_RESULT
-load_tps(char* tps) {
+enum TPS_RESULT load_tps(tak_state_p state, char *tps) {
// TODO: Ensure NULL termination?
- if (tps == NULL) return TPS_INVALID;
+ if (tps == NULL)
+ return TPS_INVALID;
uint8_t prefix = 0;
// Check if we're likely of the form [TPS "blah"]
if (!strncmp(tps, "[TPS \"", 6)) {
- prefix=1;
+ prefix = 1;
// Now we can worry about just the TPS part
tps += 6;
}
// Reset everything
- reset_state(board_size);
+ reset_state(state, state->board_size);
// Parse squares, NOTE: We assume that board_size matches TPS size.
- int col = 0, row = board_size-1, skip, parsing = 1;
+ int col = 0, row = state->board_size - 1, skip, parsing = 1;
while (parsing) {
switch (*tps) {
- case ' ': {
- // we're done
- parsing = 0;
- tps++; TPS_ASSERT_MORE;
- break;
- }
- case 'x': {
- // empty squares
- tps++; TPS_ASSERT_MORE;
- skip = 0;
- if (*tps >= '2' && *tps <= '0'+board_size) {
- skip = *tps - '1';
- tps++; TPS_ASSERT_MORE;
- } else if (*tps != ',' && *tps != '/' && *tps != ' ') {
- return TPS_INVALID;
- }
- col += skip;
- if (col >= board_size + 1) return TPS_INVALID;
- break;
- }
- case '/': {
- // next row
- if (col + 1 != board_size) return TPS_INVALID;
- row--; col = 0;
- if (row < 0) return TPS_INVALID;
- tps++; TPS_ASSERT_MORE;
- break;
- }
- case ',': {
- // next column
- col++;
- if (col >= board_size) return TPS_INVALID;
- tps++; TPS_ASSERT_MORE;
- break;
+ case ' ': {
+ // we're done
+ parsing = 0;
+ tps++;
+ TPS_ASSERT_MORE;
+ break;
+ }
+ case 'x': {
+ // empty squares
+ tps++;
+ TPS_ASSERT_MORE;
+ skip = 0;
+ if (*tps >= '2' && *tps <= '0' + state->board_size) {
+ skip = *tps - '1';
+ tps++;
+ TPS_ASSERT_MORE;
+ } else if (*tps != ',' && *tps != '/' && *tps != ' ') {
+ return TPS_INVALID;
}
- default: {
- const int l = THE_COORDS(col, row);
- uint8_t num_read = 0, reading = 1;
- // Read in a stack of colours, optionally terminated by an S
- // or C to change the top stone type
- while (reading) {
- switch (*tps) {
- // Reading a stone colour
- case '2': {
- // check next letter to make sure we have the material
- tps++; TPS_ASSERT_MORE;
- if (*tps == 'C') {
- if (black_count & 128) black_count &= 127;
- else return TPS_INVALID;
- } else if (black_count & 127) {
- black_count--;
- } else return TPS_INVALID;
- colours[l] <<= 1;
- celldat[l] += NUM_INC;
- colours[l] |= 1;
- num_read++;
- break;
- }
- case '1': {
- tps++; TPS_ASSERT_MORE;
- if (*tps == 'C') {
- if (white_count & 128) white_count &= 127;
- else return TPS_INVALID;
- } else if (white_count & 127) {
- white_count--;
- } else return TPS_INVALID;
- colours[l] <<= 1;
- celldat[l] += NUM_INC;
- num_read++;
- break;
- }
- case 'S': {
- // Have we already read a stone type?
- if (STONE_AT(l) != STONE_FLAT) return TPS_INVALID;
- celldat[l] |= STONE_STANDING;
- tps++; TPS_ASSERT_MORE;
- break;
- }
- case 'C': {
- if (STONE_AT(l) != STONE_FLAT) return TPS_INVALID;
- celldat[l] |= STONE_CAPSTONE;
- tps++; TPS_ASSERT_MORE;
- break;
- }
- case ',': // fall-through
- case '/': {
- // done here
- reading=0;
- break;
- }
- default: return TPS_INVALID;
- }
- if (num_read > 0xF) return TPS_INVALID;
- }
+ col += skip;
+ if (col >= state->board_size + 1)
+ return TPS_INVALID;
+ break;
+ }
+ case '/': {
+ // next row
+ if (col + 1 != state->board_size)
+ return TPS_INVALID;
+ row--;
+ col = 0;
+ if (row < 0)
+ return TPS_INVALID;
+ tps++;
+ TPS_ASSERT_MORE;
+ break;
+ }
+ case ',': {
+ // next column
+ col++;
+ if (col >= state->board_size)
+ return TPS_INVALID;
+ tps++;
+ TPS_ASSERT_MORE;
+ break;
+ }
+ default: {
+ const int l = THE_COORDS(state->board_size, col, row);
+ uint8_t num_read = 0, reading = 1;
+ // Read in a stack of colours, optionally terminated by an S
+ // or C to change the top stone type
+ while (reading) {
+ switch (*tps) {
+ // Reading a stone colour
+ case '2': {
+ // check next letter to make sure we have the material
+ tps++;
+ TPS_ASSERT_MORE;
+ if (*tps == 'C') {
+ if (state->black_count & 128)
+ state->black_count &= 127;
+ else
+ return TPS_INVALID;
+ } else if (state->black_count & 127) {
+ state->black_count--;
+ } else
+ return TPS_INVALID;
+ state->colours[l] <<= 1;
+ state->celldat[l] += NUM_INC;
+ state->colours[l] |= 1;
+ num_read++;
+ break;
+ }
+ case '1': {
+ tps++;
+ TPS_ASSERT_MORE;
+ if (*tps == 'C') {
+ if (state->white_count & 128)
+ state->white_count &= 127;
+ else
+ return TPS_INVALID;
+ } else if (state->white_count & 127) {
+ state->white_count--;
+ } else
+ return TPS_INVALID;
+ state->colours[l] <<= 1;
+ state->celldat[l] += NUM_INC;
+ num_read++;
+ break;
+ }
+ case 'S': {
+ // Have we already read a stone type?
+ if (STONE_AT(state, l) != STONE_FLAT)
+ return TPS_INVALID;
+ state->celldat[l] |= STONE_STANDING;
+ tps++;
+ TPS_ASSERT_MORE;
+ break;
+ }
+ case 'C': {
+ if (STONE_AT(state, l) != STONE_FLAT)
+ return TPS_INVALID;
+ state->celldat[l] |= STONE_CAPSTONE;
+ tps++;
+ TPS_ASSERT_MORE;
+ break;
+ }
+ case ',': // fall-through
+ case '/': {
+ // done here
+ reading = 0;
+ break;
+ }
+ default:
+ return TPS_INVALID;
+ }
+ if (num_read > 0xF)
+ return TPS_INVALID;
}
}
+ }
}
// Now it's time to parse the ply number. First, the active player
- if (*tps != '1' && *tps != '2') return TPS_INVALID;
- ply += *tps - '1';
- tps++; TPS_ASSERT_MORE;
+ if (*tps != '1' && *tps != '2')
+ return TPS_INVALID;
+ state->ply += *tps - '1';
+ tps++;
+ TPS_ASSERT_MORE;
// Space
- if (*tps != ' ') return TPS_INVALID;
- tps++; TPS_ASSERT_MORE;
+ if (*tps != ' ')
+ return TPS_INVALID;
+ tps++;
+ TPS_ASSERT_MORE;
// Turn number, atoi doesn't detect errors so let's do it ourselves
uint8_t p = 0;
@@ -139,21 +171,27 @@ load_tps(char* tps) {
p *= 10;
if (*tps >= '0' && *tps <= '9') {
p += *tps - '0';
- } else return TPS_INVALID;
+ } else
+ return TPS_INVALID;
tps++;
- } while ( (prefix && *tps && *tps != '"') || (!prefix && *tps) );
- if (p == 0) return TPS_INVALID;
- ply += 2*(p - 1);
+ } while ((prefix && *tps && *tps != '"') || (!prefix && *tps));
+ if (p == 0)
+ return TPS_INVALID;
+ state->ply += 2 * (p - 1);
- current_colour = (ply & 1) ? C_BLACK : C_WHITE;
- if (ply < 2) current_colour = C_BLACK - current_colour;
+ state->current_colour = (state->ply & 1) ? C_BLACK : C_WHITE;
+ if (state->ply < 2)
+ state->current_colour = C_BLACK - state->current_colour;
if (prefix) {
- tps++; TPS_ASSERT_MORE;
- if (*tps != ']' ) return TPS_INVALID;
+ tps++;
+ TPS_ASSERT_MORE;
+ if (*tps != ']')
+ return TPS_INVALID;
tps++;
- if (*tps != 0) return TPS_INVALID;
+ if (*tps != 0)
+ return TPS_INVALID;
}
return TPS_OK;
@@ -163,55 +201,68 @@ load_tps(char* tps) {
// Generate TPS string
// ===================================================================
-void
-generate_tps(char *out_tps) {
+void generate_tps(tak_state_p state, char *out_tps) {
strcpy(out_tps, "[TPS \"");
out_tps += 6;
- for (int8_t row = board_size - 1; row >= 0; row--) {
- for (int8_t col = 0; col < board_size; col++) {
- const int8_t l = THE_COORDS(col, row);
- const uint8_t count = COUNT_AT(l);
+ for (int8_t row = state->board_size - 1; row >= 0; row--) {
+ for (int8_t col = 0; col < state->board_size; col++) {
+ const int8_t l = THE_COORDS(state->board_size, col, row);
+ const uint8_t count = COUNT_AT(state, l);
if (count) {
- colour_stack_t c = colours[l], s = 1<<(count - 1);
- for (int k=0; k<count; k++, s >>=1, out_tps++) {
- if (c & s) *out_tps = '2';
- else *out_tps = '1';
- }
- switch (STONE_AT(l)) {
- case STONE_CAPSTONE: {
- *out_tps = 'C'; out_tps++; break;
- }
- case STONE_STANDING: {
- *out_tps = 'S'; out_tps++; break;
- }
- default: break;
- }
+ colour_stack_t c = state->colours[l], s = 1 << (count - 1);
+ for (int k = 0; k < count; k++, s >>= 1, out_tps++) {
+ if (c & s)
+ *out_tps = '2';
+ else
+ *out_tps = '1';
+ }
+ switch (STONE_AT(state, l)) {
+ case STONE_CAPSTONE: {
+ *out_tps = 'C';
+ out_tps++;
+ break;
+ }
+ case STONE_STANDING: {
+ *out_tps = 'S';
+ out_tps++;
+ break;
+ }
+ default:
+ break;
+ }
} else {
- int8_t skip = 1;
- while (col < board_size && COUNT_AT(l+skip) == 0) {
- skip++;
- col++;
- }
- *out_tps = 'x'; out_tps++;
- if (skip > 1) {
- *out_tps = '0'+skip; out_tps++;
- }
+ int8_t skip = 1;
+ while (col < state->board_size && COUNT_AT(state, l + skip) == 0) {
+ skip++;
+ col++;
+ }
+ *out_tps = 'x';
+ out_tps++;
+ if (skip > 1) {
+ *out_tps = '0' + skip;
+ out_tps++;
+ }
}
- if (col + 1 < board_size) {
- *out_tps = ','; out_tps++;
+ if (col + 1 < state->board_size) {
+ *out_tps = ',';
+ out_tps++;
}
}
if (row > 0) {
- *out_tps = '/'; out_tps++;
+ *out_tps = '/';
+ out_tps++;
}
}
- *out_tps = ' '; out_tps++;
- *out_tps = '1' + (ply & 1); out_tps++;
- *out_tps = ' '; out_tps++;
+ *out_tps = ' ';
+ out_tps++;
+ *out_tps = '1' + (state->ply & 1);
+ out_tps++;
+ *out_tps = ' ';
+ out_tps++;
- out_tps += sprintf(out_tps, "%d", ply/2 + 1);
+ out_tps += sprintf(out_tps, "%d", state->ply / 2 + 1);
strcpy(out_tps, "\"]");
}
diff --git a/include/tps.h b/include/tps.h
index 70cf1de..075b3f8 100644
--- a/include/tps.h
+++ b/include/tps.h
@@ -1,11 +1,9 @@
#include <tak.h>
-#include <string.h> // for strnlen, strncmp, and strcpy
#include <stdio.h> // for sprintf (in a single place! grrr)
+#include <string.h> // for strnlen, strncmp, and strcpy
// NOTE: We assume that board_size matches TPS size.
-enum TPS_RESULT
-load_tps(char* in_tps);
+enum TPS_RESULT load_tps(tak_state_p state, char *in_tps);
-void
-generate_tps(char *out_tps);
+void generate_tps(tak_state_p state, char *out_tps);
diff --git a/include/tt_llcht.c b/include/tt_llcht.c
index b80da39..7b2269b 100644
--- a/include/tt_llcht.c
+++ b/include/tt_llcht.c
@@ -21,30 +21,29 @@
// Variables
// ===================================================================
-static tt_entry_t *table[TT_LLCHT_SIZE+1];
+static tt_entry_t *table[TT_LLCHT_SIZE + 1];
// ===================================================================
// Helper declarations
// ===================================================================
-tt_entry_t * new_ll_node(const uint64_t key, const enum TT_FLAG flag,
- const uint8_t depth, const float value,
- const action_t action);
-
+tt_entry_t *new_ll_node(const uint64_t key, const enum TT_FLAG flag,
+ const uint8_t depth, const float value,
+ const action_t action);
// ===================================================================
// Exported functions
// ===================================================================
int tt_init(void) {
- for (uint32_t k=0; k<=TT_LLCHT_SIZE; k++)
+ for (uint32_t k = 0; k <= TT_LLCHT_SIZE; k++)
table[k] = NULL;
return EXIT_SUCCESS;
}
void tt_free(void) {
tt_entry_t *n, *nn;
- for (uint32_t k=0; k<=TT_LLCHT_SIZE; k++) {
+ for (uint32_t k = 0; k <= TT_LLCHT_SIZE; k++) {
n = table[k];
while (n) {
nn = n->next;
@@ -61,15 +60,15 @@ tt_entry_t *tt_seek(const uint64_t key) {
return lookup;
}
-int tt_insert(const uint64_t key, const enum TT_FLAG flag,
- const uint8_t depth, const float value,
- const action_t action) {
+int tt_insert(const uint64_t key, const enum TT_FLAG flag, const uint8_t depth,
+ const float value, const action_t action) {
tt_entry_t *new = new_ll_node(key, flag, depth, value, action), *n;
// TODO: trap
const uint32_t idx = key & TT_LLCHT_SIZE;
if ((n = table[idx]) != NULL) {
- for (; n->next != NULL; n = n->next);
+ for (; n->next != NULL; n = n->next)
+ ;
n->next = new;
} else {
table[idx] = new;
@@ -82,9 +81,9 @@ int tt_insert(const uint64_t key, const enum TT_FLAG flag,
// Helper function implementations
// ===================================================================
-tt_entry_t * new_ll_node(const uint64_t key, const enum TT_FLAG flag,
- const uint8_t depth, const float value,
- const action_t action) {
+tt_entry_t *new_ll_node(const uint64_t key, const enum TT_FLAG flag,
+ const uint8_t depth, const float value,
+ const action_t action) {
tt_entry_t *new = malloc(sizeof(struct tt_node_s));
// TODO: trap errno
new->key = key;
diff --git a/include/tt_llcht.h b/include/tt_llcht.h
index 40d8bdb..dc73d26 100644
--- a/include/tt_llcht.h
+++ b/include/tt_llcht.h
@@ -18,8 +18,8 @@
#ifndef TT_LLCHT_H
#define TT_LLCHT_H
-#include <stdlib.h>
#include <stdint.h>
+#include <stdlib.h>
#include <actions.h>
@@ -42,7 +42,7 @@ typedef struct tt_node_s {
// Variables
// ===================================================================
-#define TT_LLCHT_SIZE ((uint32_t)((1<<19) - 1))
+#define TT_LLCHT_SIZE ((uint32_t)((1 << 19) - 1))
// ===================================================================
// Methods
@@ -53,8 +53,7 @@ void tt_free(void);
tt_entry_t *tt_seek(const uint64_t key);
-int tt_insert(const uint64_t key, const enum TT_FLAG flag,
- const uint8_t depth, const float value,
- const action_t action);
+int tt_insert(const uint64_t key, const enum TT_FLAG flag, const uint8_t depth,
+ const float value, const action_t action);
#endif
diff --git a/include/weights.c b/include/weights.c
index 82b55f9..1fa864e 100644
--- a/include/weights.c
+++ b/include/weights.c
@@ -14,20 +14,20 @@
* Trainable params: 1,986
* Non-trainable params: 0
* _________________________________________________________________
- * ([0.4593624770641327, 0.8171698451042175], [0.44635653495788574, 0.819940984249115])
+ * ([0.5177317261695862, 0.755382776260376], [0.5241230130195618, 0.7530876398086548])
*/
#include "weights.h"
const float dense1_weights[DENSE_NUM][INP_NUM] =
-{{0.09708841890096664, -0.14983339607715607, 0.9531096816062927, 0.14991514384746552, -0.63932865858078, 0.09746148437261581, -0.1670435070991516, 0.25754305720329285, -0.1731426864862442, -0.1653723269701004, -0.3116675615310669, 0.4331771433353424, 0.07788953930139542, -0.3911878764629364, -0.5864945650100708, -0.5138149261474609, -0.10366032272577286, 0.09420160204172134, 0.3116736114025116, -0.8269373774528503, -0.6619208455085754, -1.0483648777008057, -0.05252189561724663, 0.12044219672679901, 0.677895724773407, 0.9947460293769836, -1.109876036643982, -0.20052704215049744}, {0.04853341355919838, -0.44796833395957947, 1.0772864818572998, 0.12211384624242783, 0.43898314237594604, 0.19653372466564178, -0.010857676155865192, -0.34688177704811096, -1.917777180671692, -1.0062774419784546, -0.772797167301178, -0.6764053106307983, -0.15675123035907745, 0.20477063953876495, 0.0170141514390707, 0.0373976044356823, -0.3958517014980316, -0.17130737006664276, 0.10296492278575897, -0.10372677445411682, -0.07705003023147583, -0.21586216986179352, -0.06457874923944473, 0.18130557239055634, -0.19682471454143524, -0.10427158325910568, -0.6213868260383606, 0.2646593451499939}, {0.05100073665380478, -1.490741491317749, 0.5347241759300232, 0.5138917565345764, 0.7368579506874084, -0.3916100859642029, 0.10224276781082153, -0.8944575190544128, 0.9391179084777832, 0.8531733155250549, -0.7068527936935425, -0.1843581348657608, 0.10034217685461044, 0.7256124019622803, -0.5566624402999878, -0.630030632019043, 0.1081201434135437, 0.06458459794521332, -0.06652732193470001, -0.7848819494247437, 0.06676337122917175, 0.19047099351882935, 0.3317343592643738, -1.125041127204895, -0.15809980034828186, 0.7293155193328857, 0.7303928732872009, 0.24778194725513458}, {-0.10748109966516495, 1.3822530508041382, 0.2629156708717346, 0.6968264579772949, 0.17485041916370392, -0.20862552523612976, -0.12484818696975708, -0.23138242959976196, 0.8940210342407227, 0.7281381487846375, 0.2892467975616455, 0.07963291555643082, -0.07487558573484421, -0.1968744993209839, 0.8000355362892151, 0.6640182733535767, 0.22926642000675201, 0.2277926504611969, -0.37833377718925476, -0.2742082476615906, 0.8170139193534851, 0.4202984571456909, 0.27552902698516846, -0.46328070759773254, -0.3581807315349579, 0.10414467751979828, 0.7333625555038452, 0.35470449924468994}, {-0.1888720840215683, 0.9495699405670166, -0.6001124978065491, 0.2289646714925766, 0.1645985096693039, 0.010710741393268108, -0.07195031642913818, -0.3604000210762024, 0.40493911504745483, 0.06439553201198578, -0.1027727797627449, -0.18764203786849976, -0.020061621442437172, 0.41247984766960144, 0.0985364243388176, 0.03292955830693245, 0.13963104784488678, -0.1577671319246292, 0.8160413503646851, 0.3458573818206787, 0.15316851437091827, 0.09699071943759918, -0.15548554062843323, 0.06560410559177399, 0.5002033710479736, 0.6853768825531006, 0.913468599319458, 1.762925148010254}, {-0.05926303192973137, 2.1326680183410645, 0.20786024630069733, 0.20509517192840576, 0.3232854902744293, 0.4138268232345581, 0.23191986978054047, 0.1483074426651001, 0.30143123865127563, 0.36913859844207764, 0.2858075201511383, 0.27123841643333435, 0.21376250684261322, 0.2404519021511078, 0.4652462899684906, 0.23301848769187927, 0.3275870382785797, 0.3245834708213806, 0.35785531997680664, 0.21870960295200348, 0.28119996190071106, 0.385022908449173, 0.2985413074493408, 0.015570216812193394, 0.2387431263923645, 0.3773896098136902, 0.3013421595096588, 0.09287303686141968}, {-0.13003307580947876, 1.7538926601409912, -0.6812999844551086, -0.4881831109523773, -0.4694475829601288, 0.75823974609375, 0.2842443883419037, 0.31535980105400085, -0.4027916193008423, 0.6403568387031555, 0.7254506945610046, 0.31957608461380005, 0.6868956089019775, 0.6129562854766846, 0.6620163917541504, -0.19040672481060028, 0.2591014504432678, 0.17981182038784027, 0.3206057548522949, 0.26464489102363586, 0.12509778141975403, -0.1723550260066986, 0.5769479274749756, 0.27363383769989014, 0.40419286489486694, 0.4196736216545105, 0.474353551864624, 0.3851746618747711}, {0.004320172592997551, -0.06554269790649414, 1.0545583963394165, 0.03816256299614906, -0.3641563057899475, -0.04311445355415344, -1.0777692794799805, 0.3634617328643799, -0.2762683629989624, 0.2931346595287323, 0.12660370767116547, -0.8033497333526611, -0.08709059655666351, 0.2099713832139969, 0.38327884674072266, 0.11443039029836655, -0.8581308722496033, -0.6271834969520569, 0.01899813674390316, -0.36976635456085205, -0.9609361290931702, -1.242712140083313, -0.20354503393173218, -0.892693042755127, -1.3654234409332275, -0.1457122266292572, 0.4198227822780609, 0.47160959243774414}, {-0.1309877187013626, 1.7283211946487427, -0.34542015194892883, 0.09756244719028473, 0.10365703701972961, 0.16427665948867798, 0.5429031848907471, 0.000730195315554738, 0.9568342566490173, 0.43416130542755127, 0.5171336531639099, -0.03411416709423065, 0.09991542249917984, 0.22394727170467377, 0.46084511280059814, 0.2941528856754303, 0.40269896388053894, 0.4282401502132416, -0.043696314096450806, 0.9397956728935242, 0.4523789584636688, 0.21760058403015137, 0.25844889879226685, -0.0975789725780487, 1.4064749479293823, -0.4462650716304779, -0.0176702868193388, -0.15949156880378723}, {-0.09322677552700043, 1.4953668117523193, -0.6572163701057434, 0.03580909222364426, 0.07035914063453674, 1.2231422662734985, 0.14995643496513367, -0.01055422704666853, -0.3619900643825531, 0.00962253101170063, 1.1480656862258911, 0.04119277000427246, -0.029596557840704918, -0.20450031757354736, -0.20949582755565643, 1.3544684648513794, -0.07676524668931961, -0.33410149812698364, 0.14368489384651184, 0.18317444622516632, 0.9521495699882507, 0.2047186642885208, -0.14690256118774414, -0.002987049985677004, 0.22252139449119568, 0.5207418203353882, 0.3862583041191101, 0.04728662222623825}, {0.12120318412780762, -0.32054218649864197, 0.2999326288700104, 0.914248526096344, -0.25369349122047424, 1.0056365728378296, 1.0900052785873413, -1.9740498065948486, -0.2208552062511444, 0.12854935228824615, 0.17538198828697205, -0.1234835833311081, -1.1125203371047974, -0.3354377746582031, -0.5196758508682251, -0.30077362060546875, -0.5856597423553467, -0.8402205109596252, -0.22239884734153748, -0.4105615019798279, -0.38801825046539307, -0.8613605499267578, -0.27762359380722046, 0.49667125940322876, 0.020931968465447426, -0.12382236868143082, -0.4301914572715759, -0.350443035364151}, {-0.07766333967447281, 0.6034705638885498, -4.554388523101807, 0.2126956582069397, 0.15929296612739563, 0.17145121097564697, 0.1601206660270691, 0.17433294653892517, 0.12817388772964478, 0.11653872579336166, 0.14781475067138672, 0.23677119612693787, 0.12034492939710617, 0.1955379694700241, 0.13016147911548615, 0.23828306794166565, 0.14038963615894318, 0.15755616128444672, 0.23868830502033234, 0.26690152287483215, 0.1843731850385666, 0.17341510951519012, 0.057188548147678375, 0.2539713680744171, 0.2696954309940338, 0.18604490160942078, 0.14197516441345215, 0.36821600794792175}, {0.15129533410072327, 0.09887662529945374, 1.2054975032806396, 0.24753500521183014, 0.4909513294696808, -1.6100319623947144, 0.07008431106805801, 0.1423417031764984, -0.09243771433830261, -0.34568139910697937, -1.0303078889846802, 0.18709783256053925, 0.6571977138519287, -0.11068439483642578, -0.14676885306835175, -0.6726709008216858, -0.6291938424110413, 0.6409110426902771, -0.4643811285495758, -0.06342993676662445, -0.3956544101238251, -0.7433932423591614, -1.4594924449920654, -0.2231053113937378, -0.31123557686805725, 0.03604980930685997, -0.01676316000521183, -0.010373279452323914}, {0.08248379826545715, -0.33374691009521484, 0.4519060552120209, -0.3651171028614044, -1.0735950469970703, 0.005808517802506685, 1.2023851871490479, 0.7546958327293396, -0.19511595368385315, -0.5970048904418945, -1.1051145792007446, -0.513593316078186, 1.0888173580169678, 0.2880654036998749, 0.14094868302345276, -0.5696795582771301, -1.0076549053192139, 0.19139567017555237, 0.336557537317276, 0.3891679644584656, 0.09406869858503342, -0.8800191283226013, -0.5774187445640564, 0.18142414093017578, 0.17849640548229218, -0.11618805676698685, -0.6260532736778259, -0.39390552043914795}, {-0.07623733580112457, 1.0555744171142578, -0.17468947172164917, 0.18221747875213623, 0.06131114810705185, -0.014457565732300282, 0.1536666601896286, 0.6676269769668579, 0.17481842637062073, -0.14446255564689636, 0.04878826066851616, 0.27363839745521545, 0.5058372020721436, 0.16395719349384308, 0.19522777199745178, 0.31879734992980957, 0.8337258696556091, 0.612602710723877, 0.18271851539611816, 0.12550194561481476, 0.7062245011329651, 0.2406325489282608, -0.5638207793235779, 0.44285738468170166, 0.49697133898735046, 0.655937135219574, -0.5988529324531555, -0.6180514693260193}, {-0.08515164256095886, 1.8156886100769043, -0.3055272698402405, -0.00542338564991951, 0.28451383113861084, 0.3305817246437073, 0.44789642095565796, 0.007520807906985283, 0.6411338448524475, 0.6627947688102722, 0.3936305642127991, 0.543207585811615, 0.31023091077804565, 0.5907645225524902, -0.5054730772972107, 0.5622344613075256, 0.46472644805908203, 0.7537768483161926, 0.5771557092666626, 0.6231046915054321, 0.5562911629676819, 0.05025006830692291, 0.4974210858345032, -0.021163247525691986, 0.428413450717926, 0.2096228450536728, 0.1297932267189026, 0.15994444489479065}, {0.059478625655174255, -1.2593594789505005, 0.8060709238052368, -0.5756357312202454, -0.5642467141151428, -1.1023842096328735, -1.0840095281600952, -1.7373161315917969, 0.051716454327106476, -0.18114325404167175, 0.03431779146194458, 0.07772735506296158, 0.30920106172561646, 0.06860094517469406, 0.053684305399656296, 0.050935737788677216, 1.5831908967811614e-05, 0.06146225333213806, 0.14663179218769073, 0.01896907575428486, -0.017615582793951035, 0.049037203192710876, 0.3536975681781769, 0.5997693538665771, 0.06265199184417725, 0.018393227830529213, -0.03553879261016846, 0.15440478920936584}, {-0.06590350717306137, 0.6541862487792969, -0.9594393968582153, 1.5689195394515991, 0.995005190372467, 0.7445554733276367, 0.92704838514328, 0.4702519476413727, -0.3339536786079407, -0.18121398985385895, 0.12824110686779022, 0.32404643297195435, 0.08692658692598343, 0.06525395065546036, -0.07403562217950821, -0.08786602318286896, 0.30545052886009216, 0.1610720455646515, 0.025930603966116905, -0.006452936679124832, 0.04217161983251572, -0.00885680504143238, 0.01933605782687664, -0.5424081683158875, 0.03653205558657646, -0.09611544758081436, 0.07054111361503601, -0.33712488412857056}, {-0.033981095999479294, 0.7148251533508301, -0.9412906169891357, -0.14343379437923431, -0.10766273736953735, -0.11414168775081635, -0.13219089806079865, 1.2587040662765503, 0.008397090248763561, -0.10059479624032974, 0.13039082288742065, 0.12154032289981842, 1.238200306892395, -0.19973790645599365, -0.05784938111901283, 0.017947781831026077, -0.04616774618625641, 1.1192306280136108, 0.07938524335622787, -0.005415983498096466, 0.09550166130065918, 0.09772814065217972, 1.2091776132583618, -0.30785369873046875, -0.05821114033460617, -0.06727229803800583, -0.04389581456780434, 1.2299752235412598}, {0.1273789405822754, -0.341524600982666, 1.151167392730713, -0.04134071618318558, -0.07647605985403061, 0.36836978793144226, -1.3937312364578247, -0.16971394419670105, -0.1672888547182083, 0.05098025128245354, 0.4777861535549164, -1.6180260181427002, -0.14700591564178467, -0.42429643869400024, -0.571417510509491, -0.3194080591201782, -1.2477779388427734, 0.7285082340240479, -0.5621447563171387, -0.067803755402565, -0.33690130710601807, -1.2182284593582153, -0.026820745319128036, 0.24996322393417358, -0.04271029680967331, -0.25508779287338257, -0.18486416339874268, -0.2532777190208435}, {0.11533160507678986, 0.3406147062778473, 1.8792569637298584, 0.018996711820364, -0.2056526243686676, -0.33621448278427124, -0.20685425400733948, -0.24743612110614777, -0.17051126062870026, -0.584708034992218, -0.40372198820114136, -0.37256744503974915, -0.34893912076950073, -0.3406921923160553, -0.5737095475196838, 0.9329007267951965, -0.5134408473968506, -0.3319478929042816, -0.1288238763809204, -0.5994487404823303, -0.5022518038749695, -0.49213001132011414, -0.13361960649490356, -0.02503959834575653, -0.33584609627723694, -0.30276021361351013, -0.16746489703655243, 0.13810385763645172}, {-0.09611523896455765, 1.238119125366211, -0.4888734817504883, 0.20628002285957336, 0.37660905718803406, 0.22086504101753235, 1.418500542640686, -0.3454299569129944, 0.2719173729419708, 0.19811256229877472, 0.3238287568092346, 1.0737624168395996, -0.12214085459709167, 0.3549494743347168, 0.2717260420322418, -0.009705607779324055, 0.853428304195404, 0.24796196818351746, 0.33442437648773193, -0.13321736454963684, 0.13895970582962036, 0.3937171995639801, 0.6743841767311096, -0.2558365762233734, 0.33873921632766724, -0.2011198103427887, -0.24151191115379333, 1.0191739797592163}, {0.028014613315463066, -0.4389137625694275, 1.2217202186584473, 0.5615558624267578, 0.05263078957796097, 0.05092257261276245, -0.0025020919274538755, -0.10499066114425659, 0.22626706957817078, -0.18914547562599182, 0.04754278063774109, 0.03034340962767601, -0.22401578724384308, -1.2998645305633545, -0.9751662015914917, -0.7423930764198303, -0.3970774710178375, -0.061214447021484375, -0.08540238440036774, 0.45488816499710083, -0.14393432438373566, -0.23829105496406555, -0.26323971152305603, 0.2596847116947174, 0.37555330991744995, 0.11025014519691467, -0.4083321690559387, 0.15121963620185852}, {-0.21241767704486847, 1.6689105033874512, -0.226408913731575, 0.03731200098991394, 0.26310592889785767, 1.2660009860992432, -0.47913163900375366, -0.4116690158843994, 0.39553773403167725, 0.0419420562684536, 1.0190608501434326, 0.3955974280834198, -0.2669771909713745, 0.22511376440525055, 0.19040349125862122, 0.3689280152320862, 0.5754274725914001, 0.791631281375885, 0.17811143398284912, 0.364437997341156, 0.13787342607975006, 0.1953200399875641, 0.35008370876312256, 0.40746477246284485, 0.021115917712450027, 0.19234441220760345, 0.34583356976509094, 0.221570685505867}, {-0.056629478931427, 1.3422456979751587, -0.48497992753982544, -0.1941925585269928, 0.165594220161438, 0.287276953458786, 0.15132613480091095, 0.38584816455841064, 0.2143339067697525, 0.13520006835460663, 0.2816779315471649, 0.36108213663101196, 0.5532099604606628, 0.2023126780986786, 0.26956668496131897, 0.06489624828100204, 0.8025456070899963, 0.01022995077073574, 0.20568951964378357, 0.3348022401332855, 0.235650435090065, 1.00911283493042, -0.1623430848121643, -0.029755957424640656, 0.16051626205444336, -0.30153003334999084, 1.820574402809143, -0.18349412083625793}, {0.08210670948028564, -0.10644663870334625, 2.0925099849700928, -0.24863389134407043, -0.2665429711341858, -0.40262511372566223, -0.45371878147125244, -0.1377442479133606, -0.39157360792160034, -0.22115609049797058, -0.4804888963699341, -0.2904321551322937, -0.18321593105793, -0.33899354934692383, -0.3302883207798004, -0.2938438951969147, -0.18833966553211212, -0.30292198061943054, -0.35079896450042725, -0.2308332324028015, -0.343620240688324, -0.29516926407814026, -0.2986883819103241, -0.16443338990211487, -0.44009503722190857, -0.27044206857681274, -0.4302333891391754, -0.036748480051755905}, {-0.020061643794178963, 1.2271647453308105, -0.7192057967185974, 0.22154885530471802, -0.2719059884548187, 0.45283734798431396, 0.23891234397888184, 0.06230388209223747, -0.3005612790584564, 0.38583460450172424, 0.09369464963674545, 0.25240558385849, 0.22129446268081665, -0.14313091337680817, -0.03104626201093197, 0.07079270482063293, 0.4938150942325592, 0.4324195086956024, 1.1018677949905396, 1.2313228845596313, 0.8778300881385803, 1.1587250232696533, 0.23411384224891663, -0.05438053980469704, -0.20136210322380066, -0.25242170691490173, 0.27750808000564575, 0.13955263793468475}, {0.21351471543312073, 0.13765887916088104, 2.0183377265930176, -0.007917194627225399, -0.3589908182621002, -0.5994181036949158, -0.11847121268510818, 0.021346328780055046, -0.4103794991970062, -0.41012945771217346, 0.18445296585559845, -0.6636074185371399, -0.24117298424243927, -0.3390832841396332, -0.40450406074523926, -0.3359193205833435, -0.39004817605018616, -0.2984693646430969, -0.22267311811447144, -0.3200683295726776, -0.17157769203186035, -0.15781398117542267, -0.20106711983680725, -0.3199653625488281, -0.28912240266799927, -0.5469598174095154, -0.598488450050354, -0.20015941560268402}, {0.13156303763389587, -0.04746222496032715, 1.4406293630599976, 0.04010009765625, -0.19504183530807495, -0.3422450125217438, -0.30269885063171387, 0.03397633880376816, -0.34146347641944885, -0.2657840847969055, -0.5875772833824158, -0.3439021110534668, -0.24916069209575653, -0.06749272346496582, -0.6978026032447815, -0.5449330806732178, -0.6765002608299255, -0.374035120010376, -0.0997399315237999, -0.7321766018867493, 0.932058572769165, -0.7302301526069641, -0.10420955717563629, 0.09721499681472778, -0.7511874437332153, -0.5356468558311462, -0.7049369215965271, 0.10399650782346725}, {-0.026832129806280136, 0.9518526792526245, 0.027437914162874222, 0.03834706172347069, 0.19063116610050201, 0.06822194904088974, 0.025699865072965622, -0.0034538416657596827, 0.5062559247016907, 0.48999106884002686, 0.839417040348053, 1.0514994859695435, -0.33073392510414124, 0.4111200273036957, -0.09617988020181656, -0.6156681776046753, 0.7947877049446106, 0.5059559345245361, 0.3703654408454895, -0.01992918737232685, 0.010815472342073917, 0.7090519666671753, 0.33787572383880615, 0.3802514672279358, 0.27450019121170044, 0.7134937047958374, 0.47950777411460876, 0.07987868040800095}, {-0.12225848436355591, 1.7318753004074097, -0.2236385941505432, 0.164175882935524, 0.6606665253639221, -0.09252867102622986, -0.09040944278240204, -0.01922728307545185, 0.2076280564069748, 0.5997986793518066, 0.8389816284179688, 1.0328935384750366, 1.4117224216461182, 0.2752927839756012, 0.3150433599948883, 0.3206954002380371, 0.3793025016784668, -0.2018655240535736, 0.1428735852241516, 0.4109397232532501, 0.2945535182952881, 0.2752903401851654, 0.1045895516872406, -0.013057844713330269, 0.33169877529144287, 0.5139592885971069, 0.06500981748104095, -0.03201531246304512}, {0.037458743900060654, -0.0013948864070698619, 1.5822151899337769, 0.2050805389881134, -0.1646299958229065, -0.19420349597930908, -0.09858932346105576, 0.03837038576602936, -0.14196360111236572, -0.5955793857574463, -0.6105048656463623, -0.19990204274654388, -0.14786484837532043, -0.4259253144264221, 1.1276053190231323, -0.5819753408432007, -0.5576790571212769, -0.37708580493927, -0.4070882201194763, -0.5314394235610962, -0.6408591866493225, -0.3505810797214508, 0.024513090029358864, 0.16252656280994415, -0.3316267132759094, -0.22024187445640564, -0.29375335574150085, -0.08565379679203033}, {-0.0819413959980011, 1.0591763257980347, -0.7337607741355896, -0.17952848970890045, 0.8200972676277161, 0.8254687190055847, 0.8399497866630554, 1.0778814554214478, 0.32117852568626404, 0.6869990229606628, 0.4733969271183014, 0.19321654736995697, -0.2765744924545288, 0.39945876598358154, 0.6774672269821167, 0.09932424128055573, -0.20062103867530823, -0.2712205648422241, 0.7035691142082214, 0.20941823720932007, -0.1504993587732315, 0.1819196194410324, 0.0758715346455574, 0.9624840021133423, -0.10010877996683121, 0.047227196395397186, 0.07651358097791672, -0.15292885899543762}, {-0.03150544688105583, -0.02839292772114277, -0.5884301662445068, 0.039681024849414825, 0.08184020221233368, 0.10623382031917572, 0.009769861586391926, -0.07766010612249374, -0.021818384528160095, 0.2412724792957306, 0.11478745937347412, 0.05257875472307205, 0.07520901411771774, 0.05953354015946388, 0.22793656587600708, 0.12766006588935852, 0.15545566380023956, 0.09512616693973541, 0.1359385848045349, 0.2246624231338501, 0.1218600645661354, 0.13645589351654053, 0.022114301100373268, -0.0938657894730568, 0.053409822285175323, 0.04353907331824303, 0.05621011555194855, 0.024152453988790512}, {-0.10731056332588196, 1.9101223945617676, -0.14491631090641022, -0.31954917311668396, -0.13067302107810974, -0.38983073830604553, 1.2752583026885986, 0.10712035745382309, -0.02182578109204769, -0.27314284443855286, 0.5775480270385742, 0.8474040031433105, 0.3230977952480316, -0.09060269594192505, 0.5151476263999939, 0.8193845152854919, 0.4053916931152344, 0.2335839718580246, 1.1781198978424072, 0.8876485228538513, 0.494328111410141, 0.10951576381921768, 0.35883137583732605, 0.031916506588459015, 0.24021664261817932, 0.4334607720375061, 0.32361146807670593, 0.12500637769699097}, {-0.048089589923620224, 0.2517174184322357, -0.6230883598327637, 0.03189172223210335, 0.028296470642089844, 0.05605744197964668, 0.08526457846164703, 0.05624855309724808, 0.04614025354385376, 0.0461905337870121, 0.07688868790864944, 0.1092841625213623, 0.06774014234542847, -0.03262807056307793, 0.08905143290758133, 0.0877608135342598, 0.06686928868293762, 0.07233935594558716, 0.057617634534835815, 0.016904741525650024, 0.04663266986608505, 0.07950703799724579, 0.00545073114335537, 0.07434149831533432, 0.03768325597047806, 0.10711461305618286, 0.06703071296215057, 0.10979264229536057}, {-0.08404885232448578, -0.7368913888931274, 0.4573487937450409, 0.13284821808338165, 0.3613227605819702, 0.14185453951358795, 0.6336719393730164, -1.4996527433395386, 0.14475664496421814, 0.29121872782707214, 0.4278671443462372, 0.1410083919763565, -0.8940686583518982, 0.2855665683746338, 0.42577508091926575, 0.32199257612228394, -0.29421567916870117, -0.47793734073638916, 0.3777045011520386, 0.19965225458145142, -0.2553655505180359, -0.7715121507644653, -0.7749602794647217, -0.9258174300193787, -0.47367092967033386, -0.7522175312042236, -0.6750305891036987, -0.22101743519306183}, {0.14481350779533386, -0.008970635011792183, 1.508664608001709, 0.15015840530395508, -0.14811588823795319, 0.588955819606781, -1.0150330066680908, -0.053266044706106186, 0.07046253234148026, -1.5722743272781372, -1.0555866956710815, -1.0166481733322144, -0.24272829294204712, -0.41724616289138794, -0.8357856273651123, -0.03276902064681053, -0.04676911234855652, -0.26494157314300537, -0.4370666444301605, -0.7593159079551697, -0.053759537637233734, 0.3186907172203064, -0.5872452855110168, 0.03758898749947548, -0.4328208863735199, -0.21179579198360443, -0.40803515911102295, 0.0951615571975708}, {0.00908249244093895, -0.07688987255096436, 0.782505452632904, 0.06486380100250244, -0.2471565157175064, 0.021011406555771828, 0.022204816341400146, 0.1792861968278885, -0.13489873707294464, -0.036091145128011703, -0.43057775497436523, -0.031296003609895706, -0.2873421311378479, 0.22351358830928802, -0.026948416605591774, -0.8745213150978088, 0.11529920995235443, 0.24653159081935883, 0.5388697981834412, 0.47889870405197144, -1.1142454147338867, 0.3187515139579773, 0.38350510597229004, 0.02950381115078926, 0.29876217246055603, -2.0111100673675537, 0.5463553071022034, 0.14435721933841705}, {0.14901532232761383, -1.5044587850570679, 0.8972142338752747, 0.2778427302837372, -0.05853148549795151, 0.1994359791278839, -0.30804818868637085, -0.2415803223848343, -0.22669333219528198, -0.09136048704385757, -0.09575177729129791, -0.5684528946876526, -0.5545351505279541, 0.11623877286911011, -0.16263911128044128, -0.040955785661935806, -0.049217116087675095, -0.8552798628807068, -0.048276450484991074, 0.10525430738925934, 0.33164283633232117, 0.24776573479175568, -0.9200206398963928, 0.14236557483673096, -0.1810273379087448, 0.08166225254535675, 0.7190329432487488, -2.1177501678466797}, {-0.19271403551101685, 1.728354811668396, -0.49745607376098633, 0.13163147866725922, 0.4125182628631592, 0.3173934519290924, 0.3347082734107971, 0.1567714363336563, 0.44411492347717285, 0.5317234992980957, -0.5201308727264404, 0.5674026012420654, 0.41059064865112305, 0.49735933542251587, 0.624692440032959, 0.854070246219635, 0.6220293045043945, 0.3193413019180298, 0.22398653626441956, 0.40847501158714294, 0.5839058756828308, 0.1582852154970169, 0.33516645431518555, 0.03460458666086197, 0.4448821544647217, 0.8498842120170593, 0.3459503650665283, 0.11562537401914597}, {-0.047379519790410995, 1.703660488128662, -0.5990813374519348, -0.5269250273704529, 1.5372254848480225, -0.2775944471359253, 0.001394903170876205, -0.19458095729351044, -0.27556341886520386, 0.9208241105079651, 0.21152672171592712, 0.06251904368400574, 0.2743033468723297, 0.06462933868169785, 0.7903530597686768, 0.39518019556999207, 0.31461477279663086, 0.7033582925796509, 1.100284457206726, 0.583648681640625, 0.5865142941474915, -0.006218436639755964, 0.31119057536125183, 0.5512746572494507, 0.037552036345005035, -0.026546820998191833, 0.3478201627731323, 0.03815087676048279}, {0.028824783861637115, -0.32616135478019714, 1.2353787422180176, -0.4744008779525757, -1.8294140100479126, -0.17039445042610168, -0.16263258457183838, -0.27589941024780273, 0.02396584302186966, -0.6765327453613281, 0.026453670114278793, -0.20710843801498413, 0.12056914716959, -0.027168219909071922, -0.472407728433609, -0.06178409606218338, -0.02956007793545723, -0.03951815888285637, -0.16745562851428986, -0.19822148978710175, -0.06916672736406326, 0.018468298017978668, -0.5161017179489136, -0.3942733108997345, -0.036136265844106674, -0.22772735357284546, -0.1378902643918991, 0.15064162015914917}, {0.03982025757431984, -2.4930081367492676, 0.8281068801879883, -0.4357646107673645, 0.10274703055620193, -0.665107786655426, 0.5115349888801575, 0.32747960090637207, -0.09119489789009094, 0.2945898175239563, -0.1673634648323059, -0.6479430794715881, 0.1562136858701706, -1.237152338027954, -0.3490593731403351, 0.027165303006768227, -0.03953339904546738, -0.7550083994865417, 0.424204021692276, -0.8311765193939209, -0.3301525413990021, -0.052060894668102264, 0.24890226125717163, 0.5295188426971436, 0.2250201553106308, -0.709912896156311, 0.1652745008468628, 0.02529488131403923}, {0.030456073582172394, -0.5592262744903564, 1.432510256767273, -1.1988471746444702, -0.5064346194267273, -0.6237148642539978, 0.40195557475090027, 0.25146642327308655, 0.5024128556251526, -0.12030938267707825, -0.7599889039993286, -1.1147559881210327, -1.3214906454086304, 0.37952062487602234, 0.0130626754835248, -0.057461678981781006, -0.4395413398742676, -0.39032915234565735, -0.04154334217309952, 0.3974667191505432, -0.22250966727733612, -0.495175838470459, 0.04570012539625168, 0.31906959414482117, -0.14886492490768433, 0.3113555312156677, -0.6547025442123413, 0.08879609405994415}, {0.11950501054525375, -0.48032498359680176, 1.2850854396820068, 0.06694980710744858, -0.16385744512081146, -0.3026943802833557, -0.25026676058769226, 0.08888517320156097, 0.06509137898683548, -0.17576169967651367, -0.06554707139730453, -0.08778101950883865, -0.30888912081718445, 0.06313688308000565, -0.03595643863081932, -0.1171422153711319, -0.13362252712249756, -0.10691016912460327, -2.0260233879089355, -0.8719305992126465, -0.5115545392036438, -0.20826612412929535, 0.0837148055434227, -0.10446202009916306, 0.4123838543891907, -0.08748969435691833, -0.28654301166534424, -0.22568418085575104}, {-0.0004980643279850483, 1.6956111192703247, -0.9341049194335938, 0.3910086750984192, 0.9375659823417664, -0.599976658821106, -0.1314917951822281, -0.2129734605550766, 0.21699850261211395, 1.0505825281143188, 0.901665449142456, -0.0852508544921875, -0.17882975935935974, 0.2928134500980377, -0.2693397104740143, 0.8399291038513184, 0.6454485654830933, 0.3374834358692169, 0.04004263877868652, 0.24971531331539154, -0.05535968020558357, 0.7141254544258118, 0.5550016760826111, -0.20664328336715698, 0.16429021954536438, 0.6384597420692444, 0.4723033607006073, -0.08882896602153778}, {-0.14170923829078674, 1.3551650047302246, -0.9581169486045837, 0.9161777496337891, 0.030683813616633415, 0.2503061294555664, 0.07654116302728653, -0.013592132367193699, 0.4500807523727417, 0.961696445941925, 0.3948116898536682, 0.7503361105918884, 0.32386764883995056, -0.4451524317264557, 1.040030598640442, -0.16870202124118805, -0.37502360343933105, 0.5298779606819153, -0.11141359061002731, 1.0228924751281738, -0.31592369079589844, -0.04017551988363266, -0.15074723958969116, 0.0482744537293911, 1.1439263820648193, 0.4571666717529297, 0.12239103764295578, 0.4535315930843353}, {-0.032109931111335754, -0.12122310698032379, 0.8914746642112732, -0.27882638573646545, -0.11921525001525879, 0.32706254720687866, 0.2490244358778, 0.3580411672592163, -0.2604867219924927, -0.21825937926769257, -0.012418774887919426, 0.19902339577674866, 0.2708764672279358, 0.2748216688632965, -0.3405546247959137, -0.8040348291397095, -0.9789102077484131, -1.7298134565353394, -0.25523945689201355, -0.07197760790586472, -0.021183472126722336, 0.24487651884555817, 0.5359469652175903, -0.04558420553803444, -0.1392718106508255, 0.26097846031188965, 0.41951051354408264, 0.2396070510149002}, {-0.1434144526720047, 1.5024970769882202, -0.26019152998924255, -0.032202448695898056, 0.32650431990623474, 0.39354056119918823, 0.19199824333190918, 0.15139684081077576, 0.2088635414838791, 0.23116657137870789, 0.34120866656303406, 0.2512649595737457, 0.04610608145594597, 0.45557311177253723, 0.46523430943489075, 0.3187943994998932, 0.25996607542037964, -0.3529891073703766, 0.18252035975456238, 0.43683773279190063, 0.8012835383415222, 1.1804018020629883, 1.7978644371032715, 0.37052586674690247, 0.6495969295501709, 0.21544672548770905, -0.24423786997795105, -0.04839114099740982}, {0.08772090822458267, 0.036836814135313034, 0.4411259591579437, -0.2324865311384201, -0.4422452747821808, 0.3720940351486206, 0.0609813816845417, 0.4158213138580322, -0.6237788200378418, -1.4070799350738525, 1.0921244621276855, 0.4683806300163269, -0.1926126927137375, 0.5655200481414795, -1.2423927783966064, -0.6283270120620728, -0.5818661451339722, 0.1723531186580658, 0.5311585068702698, -0.6664415597915649, -0.42718756198883057, -0.5389712452888489, -0.5409123301506042, -0.19837777316570282, -0.42452719807624817, -0.42125552892684937, 0.2389526516199112, 0.04127349331974983}, {0.13081054389476776, -0.11356072872877121, 1.4752963781356812, -0.07947410643100739, -0.2676275968551636, -0.3330131471157074, -0.20006857812404633, -0.04646018147468567, -0.4903687834739685, -0.45940980315208435, -0.631168782711029, -0.4270765483379364, -0.3620588183403015, -0.27580520510673523, -0.44114959239959717, -0.7304320335388184, 0.9806434512138367, -0.47282716631889343, -0.19448859989643097, -0.6225467920303345, -1.0841974020004272, -0.738459587097168, -0.8378979563713074, -0.14952285587787628, -0.2907923758029938, -0.20345616340637207, -0.3887461721897125, 0.09503486752510071}, {-0.06538720428943634, 0.7628426551818848, -0.48973286151885986, -0.38497161865234375, 0.15466463565826416, 0.11393487453460693, 0.030808981508016586, -0.3597305119037628, 0.03768155723810196, 0.024493861943483353, 0.04951104521751404, 0.14642468094825745, 0.07216943800449371, -0.12633569538593292, 0.016758088022470474, 0.13920584321022034, 0.13626915216445923, 0.07511813938617706, -0.2962007224559784, -0.1386595219373703, 0.2720275819301605, 0.21500355005264282, 0.6123909950256348, 1.9834942817687988, 0.9948948621749878, 0.9978277683258057, 0.8778850436210632, 0.6260098218917847}, {-0.16871626675128937, 1.4061483144760132, -0.5023764371871948, 0.33703121542930603, 0.8559048771858215, 0.469501256942749, 0.7470555305480957, 0.30814874172210693, 0.564860999584198, 0.40895015001296997, 0.10864124447107315, 0.1458897590637207, 0.3857732117176056, 0.7911720871925354, 0.7119686603546143, -0.250042200088501, 0.17346656322479248, 0.3537016212940216, -0.41765081882476807, 1.0786654949188232, 0.8970625996589661, 0.5761362910270691, 0.5433169603347778, -0.6643967032432556, -0.48398444056510925, 1.2207279205322266, 0.514649510383606, 0.21612684428691864}, {-0.08570192009210587, 1.214324712753296, -0.13377290964126587, 0.34323278069496155, -0.14258965849876404, -0.18832489848136902, -0.08113601058721542, -0.029942357912659645, 0.0971248522400856, 0.11952006071805954, 0.09883774071931839, 0.2491564154624939, 0.07593998312950134, 1.131385087966919, 1.2205246686935425, 1.1922342777252197, 1.2262190580368042, 0.48976269364356995, 0.22512586414813995, 0.33211636543273926, -0.5047371983528137, 0.2883317172527313, 0.23470860719680786, 0.24038122594356537, -0.04741585999727249, -0.5512517094612122, -0.08958519995212555, 0.3993839919567108}, {-0.09156186878681183, 1.447799801826477, -0.8677529096603394, -0.2403821051120758, -0.24082186818122864, 0.09531288594007492, 1.1842302083969116, 0.7055855393409729, 1.238553762435913, 0.830436646938324, 0.7400990724563599, 0.5128685832023621, -0.1964624524116516, -0.3230336308479309, -0.12294219434261322, 0.24010124802589417, 0.3363843262195587, -0.19299542903900146, -0.1038021519780159, 0.10120601207017899, 0.30215927958488464, 0.0030945949256420135, 0.162748321890831, 0.048576682806015015, 0.3265083134174347, 0.43292054533958435, 0.1647973358631134, -0.14344830811023712}, {-0.14595773816108704, 2.036177635192871, -0.15678788721561432, -0.19012169539928436, 0.042336251586675644, 0.09402280300855637, 0.7207157611846924, 0.14010852575302124, 0.013773145154118538, 0.2021285742521286, 0.8130205273628235, 0.697592556476593, 0.19569545984268188, 1.3054842948913574, 0.7752094864845276, 0.8463451862335205, -0.43331101536750793, 0.39584746956825256, -0.026438673958182335, 0.35300928354263306, 0.6822341680526733, 0.5199337005615234, 0.4171527326107025, -0.19292718172073364, 0.30702468752861023, 0.2383618950843811, 0.49791133403778076, 0.2006896585226059}, {-0.016399526968598366, -0.8661689162254333, 0.627953827381134, 0.8040047883987427, 0.2690049409866333, -0.05720654875040054, 0.20661626756191254, 0.49369704723358154, 0.1373131424188614, -0.08826663345098495, -0.16605296730995178, 0.23632067441940308, -0.04646783322095871, 0.3226010203361511, -0.21266025304794312, 0.13406658172607422, 0.3166760206222534, 0.39453834295272827, 0.22649653255939484, -0.2949632406234741, -0.30884310603141785, 0.1574787050485611, 0.8918634653091431, -0.6566658616065979, -1.055477261543274, -0.9904500842094421, -1.3658781051635742, -1.9980671405792236}, {0.12702903151512146, -4.264755725860596, 0.1351483166217804, -0.20723043382167816, -0.2467646598815918, -0.13731075823307037, -0.2164659947156906, -0.14355270564556122, -0.14075502753257751, -0.25379636883735657, -0.17323608696460724, -0.1511029303073883, -0.17861734330654144, -0.15422824025154114, -0.07887014746665955, -0.16572877764701843, -0.1545283943414688, -0.18726830184459686, -0.1911981999874115, -0.22419621050357819, -0.14734145998954773, -0.1506907343864441, -0.26516038179397583, -0.17076921463012695, -0.20366378128528595, -0.2068306803703308, -0.2465706467628479, -0.07892344892024994}, {0.08080519735813141, 0.1585157960653305, 1.8969849348068237, -0.20419242978096008, -0.2912924289703369, -0.36874666810035706, -0.40501853823661804, -0.19646884500980377, -0.142297625541687, -0.22064056992530823, -0.3288157284259796, -0.32355132699012756, -0.5395388007164001, -0.5318061709403992, -0.3192610740661621, -0.27381959557533264, -0.34684738516807556, -0.5140829086303711, -0.373310923576355, -0.413587361574173, -0.2374996393918991, -0.21946990489959717, -0.3940057158470154, -0.18182581663131714, -0.3221309185028076, -0.45614495873451233, -0.12116502225399017, -0.17031502723693848}, {0.07794322818517685, -0.10273882746696472, 1.2109743356704712, 0.018595527857542038, 0.056782107800245285, -0.1575082391500473, -0.1836964339017868, 0.13944111764431, 0.026699164882302284, -0.12828998267650604, -0.10416686534881592, -0.855417013168335, -1.1240910291671753, -0.3680402934551239, -0.5175941586494446, -0.8113775849342346, -0.48369184136390686, 0.42436426877975464, -0.24796444177627563, -0.7017632126808167, -0.33427396416664124, 0.8904720544815063, 0.13182073831558228, 0.0840996578335762, -1.3255901336669922, 0.555604100227356, 0.44455230236053467, 0.6097607612609863}, {-0.034049827605485916, 0.5697606801986694, -0.9041339755058289, 1.4350972175598145, -0.1483038365840912, -0.06558208167552948, -0.2450496107339859, -0.5598021149635315, 1.3650588989257812, 0.09695714712142944, 0.20738567411899567, -0.04335039108991623, 0.010373556055128574, 0.9249184727668762, 0.25404757261276245, 0.1163429543375969, -0.04122623801231384, 0.07139857113361359, 1.4624335765838623, 0.3055124580860138, 0.008223910816013813, -0.06609079241752625, 0.09183429181575775, 1.1958849430084229, 0.025186588987708092, 0.029254700988531113, 0.07879947870969772, -0.4418580234050751}, {0.07264219224452972, -0.8118353486061096, 0.5850833058357239, -0.04886290058493614, -0.21201711893081665, -0.2038731724023819, -0.044785141944885254, 0.33473384380340576, -0.3806909918785095, -0.3222631812095642, -0.1784955859184265, -0.07884243875741959, -0.04943345859646797, -0.7509729266166687, -0.2586313784122467, -0.11834448575973511, -0.3176766037940979, 0.029591834172606468, -0.6633329391479492, 0.31418582797050476, 0.1703609675168991, -0.1421850472688675, -0.09780556708574295, -2.4741933345794678, -0.007773654069751501, -0.2453930675983429, -0.10803715884685516, -0.10720524936914444}, {0.04180590435862541, -0.47792956233024597, 0.5036258101463318, -2.0397746562957764, 0.2890857756137848, 0.31826984882354736, 0.06372813880443573, -0.09525591135025024, -0.5323511362075806, 0.10418450832366943, 0.19146449863910675, 0.11332566291093826, -0.07695935666561127, -0.4690433442592621, -0.19135060906410217, 0.01175900548696518, -0.009661716409027576, 0.09737563133239746, -0.14801274240016937, -0.26320526003837585, -0.08077298104763031, -0.05239444971084595, -9.216830221703276e-05, -0.06783001869916916, -0.2219526469707489, -0.1100030168890953, 0.06168339401483536, -0.01574299857020378}};
+{{0.0335812121629715, -0.21365489065647125, -0.653753936290741, -0.13572198152542114, 0.18898768723011017, 0.06430475413799286, 0.1521165519952774, -0.6386323571205139, 0.5113293528556824, 0.3224753439426422, 0.3006350100040436, 0.4426257014274597, -0.4259096086025238, 0.34491172432899475, 0.26074907183647156, 0.30206671357154846, 0.2114274799823761, -0.5099963545799255, 0.38777005672454834, 0.23917558789253235, 0.32478395104408264, 0.2528369724750519, -0.5045477747917175, 0.10504062473773956, 0.34629005193710327, 0.28095799684524536, 0.31814444065093994, -0.7089307904243469}, {0.0565570704638958, -0.4527612030506134, 0.22363899648189545, -0.4776171147823334, -0.4429882764816284, 0.09122249484062195, 0.08279165625572205, 0.29376256465911865, -0.23718500137329102, -0.5789054036140442, 0.28780052065849304, 0.6442199945449829, 0.03741508722305298, -0.220468670129776, -0.644933819770813, -0.13106265664100647, 0.5042467713356018, 0.43313512206077576, 0.5279864072799683, -0.5684875249862671, -0.8156968355178833, -0.5465362668037415, -0.5424111485481262, 0.04707803204655647, 0.2047167718410492, -0.3449491560459137, -0.26257622241973877, -0.4042203426361084}, {0.002476541558280587, -0.21414169669151306, -0.11842579394578934, 0.14450429379940033, -0.01525128073990345, -0.12563736736774445, -0.27338773012161255, 0.009645791724324226, -0.25494587421417236, -0.2797246277332306, -0.2301362156867981, -0.40248778462409973, -0.2902604341506958, 0.19436009228229523, -0.11030247807502747, 0.08137191087007523, -0.1867382973432541, -0.7496097683906555, -0.008727616630494595, 0.22033251821994781, 0.19767463207244873, 0.11307194083929062, -0.8412720561027527, 0.2657962143421173, -0.07668104767799377, 0.06086883693933487, 0.3835994601249695, -1.091362476348877}, {0.05102699622511864, -0.8378904461860657, 0.4566768705844879, -0.2630152404308319, -0.23932738602161407, -0.19857573509216309, 0.30443575978279114, -0.14038261771202087, -0.14678728580474854, -0.40179580450057983, -0.35921597480773926, -0.14929337799549103, 0.12302257865667343, 0.10777170211076736, -0.12337932735681534, -0.33727583289146423, -0.28758835792541504, 0.37838035821914673, 0.3109462559223175, 0.15170936286449432, 0.17238374054431915, -0.7253879308700562, -0.23942553997039795, 0.11120962351560593, 0.2859588861465454, 0.4778689444065094, -0.679128885269165, -0.226375013589859}, {0.03254811838269234, -0.20261096954345703, -0.07562973350286484, -0.10781332850456238, -0.10312259197235107, -0.07764437049627304, -0.04054751992225647, -0.07112596929073334, -0.06557303667068481, -0.12047363817691803, -0.062015969306230545, -0.026542047038674355, -0.01934126764535904, -0.09312712401151657, -0.03113151155412197, -0.051008112728595734, -0.05768309533596039, -0.10491270571947098, -0.0717678889632225, -0.04455398768186569, -0.02723315730690956, -0.057788874953985214, -0.0033781195525079966, -0.03603564202785492, -0.006476488430052996, -0.021566126495599747, -0.04043968394398689, 0.007654271088540554}, {-0.08095347136259079, -0.26414069533348083, -0.09814666211605072, -0.04380079358816147, -0.5849603414535522, -0.7097421288490295, -0.9047000408172607, -1.3424301147460938, -0.31041404604911804, -0.25597554445266724, -0.11997552961111069, 0.20276427268981934, 0.36256903409957886, 0.019292958080768585, -0.041115161031484604, 0.12530303001403809, 0.20739392936229706, 0.3235205411911011, -0.05591806769371033, -0.05841316655278206, 0.038499265909194946, 0.18055571615695953, 0.293590784072876, 0.16785693168640137, 0.24048064649105072, 0.07176923751831055, 0.08983936905860901, 0.22106173634529114}, {-0.017707331106066704, 0.12255413830280304, -0.6240278482437134, -0.04464518278837204, -0.1846076399087906, 0.6399872899055481, 0.12881889939308167, 0.22656285762786865, -0.1679985672235489, -0.28858682513237, 0.5312493443489075, 0.049816571176052094, -0.24046465754508972, -0.1774766743183136, -0.09163064509630203, 0.7954617142677307, -0.39598366618156433, -0.4399476945400238, 0.6123018860816956, 0.45216771960258484, 0.6593272089958191, -0.07644930481910706, -0.4521935284137726, 0.012832398526370525, 0.028779083862900734, 0.6450971961021423, 0.575737714767456, 0.6349318027496338}, {-0.03650929406285286, -0.14473311603069305, -0.5584736466407776, -0.029627997428178787, -0.1539306640625, -0.12314235419034958, 0.08387640863656998, -0.0337577685713768, -0.17351587116718292, -0.19245818257331848, -0.16416308283805847, 0.016272591426968575, 0.36373433470726013, 0.04089183360338211, 0.02371835894882679, -0.22523774206638336, -0.15100933611392975, 0.45591863989830017, -0.1123512014746666, 0.061778921633958817, -0.13473178446292877, -0.40654733777046204, 0.4156742990016937, -0.03619186207652092, 0.24843069911003113, 0.29947373270988464, 0.36726078391075134, 1.2590346336364746}, {-0.1366739124059677, 0.41514185070991516, -0.2774442732334137, -0.3785100281238556, -0.43781572580337524, 0.0857686847448349, 0.548991322517395, 0.3008037805557251, -0.710213303565979, 0.02195434831082821, 0.5724306702613831, 0.5335829854011536, 0.09624887257814407, 1.017358660697937, 0.8264562487602234, 0.4335733652114868, 0.2976129651069641, -0.07695961743593216, 0.08250663429498672, 0.12967929244041443, -0.04427557811141014, 0.24989163875579834, 0.08119788765907288, 0.05688076093792915, 0.14414691925048828, -0.15780726075172424, 0.12778723239898682, 0.17664006352424622}, {0.045846302062273026, -0.4202306270599365, 0.24253332614898682, 0.058551233261823654, 0.13127459585666656, -0.08259733766317368, -0.5951005220413208, 0.010317057371139526, 0.32319802045822144, -0.2788604497909546, -0.10889868438243866, -0.6505680084228516, 0.0621410608291626, -0.22810311615467072, -0.0803237184882164, 0.4647519290447235, -0.6627072691917419, 0.20077340304851532, 0.1278313249349594, 0.021397558972239494, -0.017719708383083344, -0.65326988697052, 0.03247045353055, -0.003151470795273781, -0.089555524289608, -0.21280834078788757, -0.18042130768299103, -0.13124220073223114}, {0.08920250833034515, -0.4041590988636017, 0.11126764863729477, -0.38825124502182007, -0.37751445174217224, 0.3841644823551178, 0.13915617763996124, -0.427076131105423, -0.42071813344955444, -0.8185845017433167, -0.6395564675331116, -0.3830700218677521, -0.34343987703323364, 0.14143605530261993, 0.2065681666135788, -0.5982153415679932, -0.2753662168979645, -0.5253153443336487, 0.1136728972196579, 0.303848534822464, -0.3599269390106201, -0.48723894357681274, 0.1170220747590065, 0.1082770973443985, 0.2027408331632614, -0.6000553369522095, -0.2399190366268158, 0.21266664564609528}, {-0.044174984097480774, 0.10084715485572815, -0.7766823768615723, 0.5814716219902039, 0.2989753484725952, -0.04704820364713669, -0.23142951726913452, 0.16222569346427917, 0.026166614145040512, 0.3819707930088043, 0.0457681305706501, -0.0551467202603817, 0.09645840525627136, -0.28990161418914795, 0.11402436345815659, 0.445557564496994, 0.3328436315059662, 0.6563848853111267, -0.22550760209560394, 0.1100253015756607, -0.29362085461616516, 0.35912737250328064, 0.07314564287662506, 0.3241541087627411, -0.04152493178844452, -0.18172766268253326, 0.3779054582118988, 0.30225080251693726}, {0.0354388952255249, -0.45912227034568787, 0.07555098086595535, -0.047884486615657806, 0.12533819675445557, 0.11261603981256485, 0.5056780576705933, -0.15080063045024872, -0.14207696914672852, -0.24237896502017975, -0.4537515342235565, -0.7382211685180664, -1.396830439567566, -0.05796787142753601, -0.0972527340054512, -0.0011085039004683495, 0.15182892978191376, 0.38325998187065125, -0.013696794398128986, -0.05116301029920578, 0.24685567617416382, 0.17722700536251068, -0.011363615281879902, 0.032823070883750916, 0.23471832275390625, 0.2214534878730774, -0.12878315150737762, 0.07269603759050369}, {0.1021164283156395, -0.979482114315033, 0.10424260795116425, 0.20152615010738373, -0.4474649131298065, -0.5927112698554993, -0.4682328701019287, -0.25608980655670166, -0.03509359434247017, -0.3745705783367157, -0.5153190493583679, -0.5731074810028076, -0.558528482913971, -0.08479820191860199, -0.38562700152397156, -0.4411310851573944, -0.5317122340202332, -0.5145424604415894, -0.046643827110528946, -0.2316707819700241, -0.3664470911026001, -0.3545966148376465, -0.313737690448761, 0.09879656881093979, -0.2625102400779724, -0.306001216173172, -0.29944929480552673, 0.03161349147558212}, {-0.03801499307155609, -0.2233135849237442, -0.10620100051164627, 0.2713835537433624, 0.21967564523220062, 0.251351535320282, 0.16949021816253662, 0.15099139511585236, 0.05300286412239075, 0.08299478143453598, 0.011512423865497112, 0.01530615333467722, 0.07382016628980637, -0.18710920214653015, 0.03905392810702324, 0.16468313336372375, 0.22495073080062866, 0.3159700930118561, -0.1615748107433319, -0.16977524757385254, -0.17270493507385254, 0.1490594446659088, 0.4793047308921814, -0.0045040980912745, -0.3750409185886383, -0.5658650994300842, -0.7609032392501831, -0.9970420598983765}, {-0.06860953569412231, 0.1561063975095749, 0.41900986433029175, -0.09340472519397736, 0.05546368286013603, -0.32329270243644714, -0.3049590587615967, -0.057696402072906494, -0.17760413885116577, -0.21533682942390442, -0.06622635573148727, -0.20747050642967224, -0.13626375794410706, -0.16855809092521667, -0.06624997407197952, 0.17109455168247223, 0.265641987323761, 0.2269686758518219, -0.31261059641838074, -0.3254770040512085, -0.17686116695404053, -0.184734046459198, -0.17058107256889343, -0.13638293743133545, -0.25341087579727173, -0.06822904199361801, -0.17498566210269928, -0.15365538001060486}, {-0.09274652600288391, 0.8195863366127014, -0.6974982619285583, 0.19567207992076874, 0.3114858567714691, 0.3193179965019226, 0.3051777482032776, 0.1686609983444214, 0.28975042700767517, 0.3609328269958496, 0.34076830744743347, 0.3451266586780548, 0.2754822373390198, 0.2944789528846741, 0.3471467196941376, 0.3111295998096466, 0.36336469650268555, 0.3138508200645447, 0.3493599593639374, 0.3804861307144165, 0.3554949462413788, 0.38007041811943054, 0.304755836725235, 0.1720620095729828, 0.3196488618850708, 0.3476446270942688, 0.2819644510746002, 0.20534354448318481}, {-0.04308394342660904, 0.4313099980354309, 0.0190417543053627, -0.36723119020462036, -0.17420481145381927, 0.5145810842514038, 0.5347347855567932, 0.6282756328582764, 1.2653520107269287, 1.1850699186325073, 0.8361583352088928, 0.4141540825366974, 0.26177582144737244, 0.06430555135011673, 0.4607594609260559, -0.0807068794965744, -0.09359037131071091, 0.09638888388872147, 0.525905191898346, 0.5729591250419617, -0.02258281223475933, -0.17060524225234985, 0.12351763993501663, 0.08509236574172974, 0.4710988402366638, 0.17080940306186676, 0.250908762216568, -0.09069673717021942}, {0.07291662693023682, 0.08596876263618469, -0.08287191390991211, 0.26005038619041443, 0.46491068601608276, 0.5783225893974304, 0.15600703656673431, -0.26880383491516113, -0.17159603536128998, 0.18245145678520203, 0.6828884482383728, -0.21175506711006165, -0.057075608521699905, -0.31850534677505493, 0.12133979052305222, 0.5726630091667175, -0.07307758182287216, -0.0253745187073946, -0.05841955170035362, -0.2049519568681717, 0.542971670627594, -0.0039001810364425182, -0.027620088309049606, -0.4046057164669037, -0.07061299681663513, 0.5127297043800354, 0.17255832254886627, -0.37250733375549316}, {-0.11166863888502121, 0.055800892412662506, -0.5167198777198792, 0.2324250191450119, 0.40913817286491394, 0.6140636801719666, 0.4707394242286682, 1.522460699081421, 0.28594499826431274, 0.3309996426105499, 0.08542972803115845, -0.28014466166496277, 0.139140322804451, 0.1942225694656372, 0.1311720907688141, 0.06602678447961807, 0.13316340744495392, 0.5902721881866455, 0.03358441963791847, -0.01826644130051136, 0.2206089198589325, 0.3234162926673889, 0.29170212149620056, 0.027043171226978302, 0.2018718421459198, -0.010219907388091087, 0.35940054059028625, 0.07707080245018005}, {0.02553723379969597, 0.461318701505661, -0.4059189260005951, 0.05942573770880699, -0.010037711821496487, -0.13757778704166412, 0.22961010038852692, 0.2251977026462555, 1.0914969444274902, 0.9033216834068298, 0.83197420835495, 0.7612583637237549, 0.05771542713046074, -0.10955284535884857, -0.004019961226731539, 0.4693775475025177, 0.07826275378465652, -0.13095584511756897, -0.2168196588754654, -0.3515476584434509, 0.7580985426902771, 0.20290978252887726, -0.16279703378677368, -0.06892823427915573, -0.20307579636573792, 0.954958975315094, -0.2317219376564026, -0.1928693652153015}, {0.062168460339307785, -0.5123471617698669, -0.263359934091568, -0.7685256600379944, 0.08967547863721848, 0.24563723802566528, 0.3980844020843506, 0.3117550015449524, -0.7312137484550476, -0.06169243901968002, 0.25126340985298157, 0.2695813477039337, 0.23361706733703613, -0.969958484172821, 0.12066813558340073, 0.15110082924365997, 0.22164055705070496, 0.14506936073303223, -0.8025405406951904, 0.26169300079345703, 0.11112350225448608, 0.29015427827835083, 0.34564951062202454, -0.9369366765022278, 0.41549447178840637, 0.2582719624042511, 0.3374422788619995, 0.3025016188621521}, {-0.1270698755979538, 0.429225891828537, -0.49225398898124695, -0.11553260684013367, -0.23649732768535614, 0.8932956457138062, -0.11381787061691284, -0.300383061170578, -0.08516164869070053, -0.04815308749675751, 0.6397905349731445, 0.05467788130044937, -0.17419259250164032, 0.05954163148999214, 0.11605441570281982, 0.46235892176628113, 0.005171304568648338, -0.3957885801792145, 0.19777722656726837, 0.7243578433990479, 0.8090712428092957, 0.8684667348861694, 1.0440218448638916, 0.435382217168808, 0.20173248648643494, -0.50189208984375, -0.127868190407753, -0.049834541976451874}, {0.0026459188666194677, 0.11711517721414566, -0.7256444692611694, -0.08485592901706696, 0.9629834890365601, 0.09173507988452911, 0.244176983833313, 0.24677251279354095, 0.15705431997776031, 0.7062681913375854, -0.5933635234832764, -0.10675647109746933, 0.04850605130195618, 0.13815787434577942, 0.4868027865886688, -0.48046332597732544, 0.09973080456256866, 0.0552331916987896, 1.0236599445343018, 1.0715246200561523, 0.8364623188972473, 0.6795467138290405, 0.1431518793106079, -0.09264400601387024, -0.24593685567378998, 0.0526106022298336, 0.5356892347335815, 0.4176342785358429}, {-0.17575381696224213, 0.9493538737297058, -0.9680318832397461, 0.344186007976532, 0.37747424840927124, 0.3827437460422516, 0.3655855357646942, 0.32791411876678467, 0.3741169273853302, 0.42540842294692993, 0.4716174900531769, 0.4630044102668762, 0.4119097888469696, 0.43781936168670654, 0.4984303414821625, 0.3960149586200714, 0.4152538776397705, 0.3874683082103729, 0.37821871042251587, 0.41086938977241516, 0.436718225479126, 0.38621312379837036, 0.3685840666294098, 0.3631429970264435, 0.3682745099067688, 0.3622629940509796, 0.41871270537376404, 0.3119860589504242}, {-0.06097084656357765, 0.3522926867008209, -0.07554367929697037, 0.31942737102508545, 0.029151281341910362, 0.15592512488365173, -0.0009292215690948069, 0.18485626578330994, 0.39177006483078003, 0.2792249321937561, 0.12014344334602356, 0.09458812326192856, 0.028401147574186325, 1.115199089050293, 0.8369911313056946, 0.602891206741333, 0.28732630610466003, -0.11038826406002045, -0.5364417433738708, -0.08979910612106323, 0.6724634766578674, 0.34956303238868713, 0.27176162600517273, -0.5280332565307617, -0.5781199932098389, 0.6316017508506775, 0.41322362422943115, 0.18675293028354645}, {0.06110076978802681, 0.20676849782466888, -0.21055933833122253, 0.14543284475803375, -0.2691429555416107, 0.23192094266414642, -0.16181010007858276, -0.07387831062078476, 0.2630201280117035, -0.1249636858701706, 0.16139020025730133, 0.12681415677070618, 0.24008934199810028, 0.5166671872138977, 0.84417724609375, 0.928178071975708, 0.5734097361564636, 0.7494409680366516, 0.45103031396865845, 0.29169872403144836, -0.17037302255630493, -0.6708592176437378, 0.1958291381597519, 0.17509706318378448, 0.2388417273759842, -0.3683401942253113, -0.46702516078948975, -0.12833642959594727}, {0.00030645611695945263, -0.19412267208099365, -0.1942126452922821, 0.8911823034286499, 0.8041935563087463, 0.6952621936798096, 0.5451593399047852, 0.4937603175640106, -0.24343731999397278, -0.1464550644159317, -0.12816737592220306, 0.024196654558181763, 0.036258477717638016, -0.1814306229352951, -0.21442382037639618, -0.11105196923017502, -0.22053563594818115, -0.24859702587127686, -0.22910651564598083, -0.2101702243089676, -0.14243045449256897, -0.2865407168865204, -0.18984046578407288, -0.07871726900339127, -0.2595853805541992, -0.24533933401107788, -0.26216810941696167, -0.16304023563861847}, {0.052463531494140625, 0.1486791968345642, -0.579024612903595, 1.088742733001709, -0.13386118412017822, -0.1609494388103485, -0.09612634778022766, -0.09550110250711441, 0.9107480645179749, -0.14887897670269012, -0.017151640728116035, 0.020924121141433716, 0.04268282279372215, 0.9172422885894775, 0.04447457566857338, -0.02752840891480446, 0.022488543763756752, -0.09672117233276367, 0.8158107995986938, 0.15294760465621948, 0.04637422040104866, 0.024195043370127678, -0.08632858097553253, 0.4717424511909485, 0.18674905598163605, 0.10150022804737091, 0.025798514485359192, -0.1546076387166977}, {0.029881251975893974, 0.49499452114105225, -0.026262039318680763, 0.00900306273251772, -0.036245543509721756, -0.11946964263916016, 0.172474667429924, 0.5267413854598999, 0.07936062663793564, -0.15437465906143188, 0.16969208419322968, 0.7578750252723694, 0.4837819039821625, 0.08440805226564407, 0.20724894106388092, 0.07721617817878723, 0.7230514883995056, 0.023518960922956467, 0.3058747947216034, 0.1142619401216507, 0.08739539235830307, 0.8077057003974915, -0.38012027740478516, 0.23245155811309814, 0.10439647734165192, -0.07647071778774261, 1.3155752420425415, -0.46643584966659546}, {0.10903043299913406, -0.004875070881098509, 0.2575789988040924, 0.14737094938755035, 0.43150651454925537, -0.5420994162559509, -0.3059577941894531, -0.2527901232242584, 0.19769372045993805, 0.38301345705986023, -0.10965324938297272, -0.21152931451797485, -0.0738074779510498, 0.1658964455127716, 0.4326992332935333, 0.4845859110355377, 0.1578446626663208, -0.10062657296657562, -0.1752672642469406, -0.37322744727134705, 0.17257146537303925, 0.2496408224105835, 0.12594257295131683, -0.37234362959861755, -0.12441913038492203, -0.026296446099877357, 0.1662571132183075, -0.0028839746955782175}, {-0.014218885451555252, -0.5738092064857483, 0.23660679161548615, -0.10611919313669205, -0.12041497230529785, -0.1564393788576126, -0.2974553406238556, -0.13557544350624084, -0.03920785337686539, 0.22239501774311066, -0.6583126187324524, -0.4981720745563507, -0.34942877292633057, 0.09956511110067368, 0.07194441556930542, -0.8891360759735107, 0.09037145227193832, 0.4524118900299072, 0.1884671002626419, 0.04436931014060974, -0.9194300770759583, 0.5126015543937683, 0.5571795105934143, 0.25728949904441833, 0.03548843413591385, -1.0185256004333496, 0.30711427330970764, 0.39558374881744385}, {-0.014499297365546227, -0.6686705946922302, -0.036153871566057205, -1.3211073875427246, -0.6752616167068481, -0.7146933078765869, -0.549763023853302, -0.11895440518856049, 0.5944733619689941, 0.46897026896476746, 0.03513138368725777, -0.41634684801101685, -0.11872824281454086, 0.40422236919403076, 0.26827922463417053, 0.0015694501344114542, -0.1268347054719925, 0.18456166982650757, 0.060881517827510834, 0.1850985437631607, 0.20143119990825653, -0.07189079374074936, 0.19972868263721466, 0.16691307723522186, 0.16700705885887146, 0.14965561032295227, -0.07053949683904648, 0.2440711408853531}, {-0.30115965008735657, 0.3020112216472626, -0.6229689121246338, 0.19976438581943512, 0.25084272027015686, 0.08908466249704361, 0.12059653550386429, 0.03533867746591568, 0.2703179121017456, 0.3352479934692383, 0.3428271412849426, 0.4156206548213959, 0.3420707583427429, 0.2064814567565918, 0.35532060265541077, 0.08173895627260208, 0.07825019955635071, 0.221553236246109, 0.1776820570230484, 0.22577251493930817, 0.22278828918933868, 0.2640128433704376, 0.180125430226326, 0.11645812541246414, 0.3808441460132599, 0.1748972088098526, 0.04822747781872749, 0.20747071504592896}, {0.004458575043827295, 0.03752393275499344, 0.1197284460067749, 0.429423987865448, 0.2881259620189667, 0.6022155284881592, -0.4153423011302948, -0.5097853541374207, 0.42615923285484314, 0.44554516673088074, 0.7217490673065186, 0.8117141127586365, 0.72388756275177, 0.015255422331392765, -0.22130870819091797, 0.13519121706485748, 0.3975375294685364, 0.1678304821252823, 0.10857963562011719, -0.3138495981693268, 0.1589823067188263, 0.2486751675605774, 0.40141168236732483, 0.018049899488687515, -0.08904679864645004, -0.08511554449796677, 0.1515214890241623, 0.4401805102825165}, {-0.15634094178676605, -0.19944559037685394, -0.16159050166606903, 0.537737250328064, 0.047764409333467484, -0.14748850464820862, 0.1200181245803833, -0.07930611819028854, 0.1614770144224167, 0.7068870067596436, 0.5102498531341553, 0.8125320076942444, 0.9490340948104858, 0.2141641080379486, 0.5533105731010437, 0.23265130817890167, 0.15047943592071533, -0.514159083366394, -0.028046829625964165, 0.6813269257545471, 0.1514519900083542, -0.1020088791847229, -0.04611760750412941, 0.22561359405517578, 0.43252548575401306, -0.050761569291353226, -0.09585573524236679, -0.15603257715702057}, {-0.08421202749013901, 0.33921104669570923, -0.41581854224205017, -0.21174439787864685, 0.4582148492336273, 0.11856566369533539, 0.10920864343643188, -0.059966351836919785, 0.3425080180168152, 0.4195125102996826, 0.02871912717819214, 0.06811660528182983, 0.0683729499578476, 0.6100324988365173, 0.2850392162799835, -0.039775870740413666, -0.11169159412384033, -0.18508493900299072, 0.730349063873291, -0.10342872887849808, -0.19325177371501923, -0.12663674354553223, -0.11998621374368668, 1.3490771055221558, -0.5284110307693481, -0.12912636995315552, -0.060148727148771286, -0.1581180840730667}, {0.13426083326339722, -0.13176080584526062, 1.2296770811080933, -0.07961347699165344, -0.3992340862751007, -0.3328780233860016, -0.3540795147418976, -0.06446079909801483, -0.3728063106536865, -0.44019535183906555, -0.4748293459415436, -0.4214479923248291, -0.37979984283447266, -0.31887421011924744, -0.46707987785339355, -0.34212198853492737, -0.4332870543003082, -0.3801964819431305, -0.3589206337928772, -0.49498450756073, -0.5273376107215881, -0.4567064344882965, -0.40370914340019226, -0.004378970246762037, -0.3736163079738617, -0.3421406149864197, -0.34401506185531616, -0.011685256846249104}, {0.08239886164665222, -0.8746750354766846, 0.520552933216095, -0.2309003621339798, -0.27933767437934875, -0.20904868841171265, -0.29178568720817566, -0.056779034435749054, -0.28577834367752075, -0.25492337346076965, -0.26360198855400085, -0.2623720169067383, -0.2106320858001709, -0.11835736036300659, -0.04690302908420563, -0.06490934640169144, -0.13744433224201202, -0.21501925587654114, -0.036219630390405655, -0.11873988062143326, -0.09084317088127136, -0.2095029354095459, -0.11422516405582428, -0.016950659453868866, -0.2354726791381836, -0.17757123708724976, -0.05872594937682152, -0.23141008615493774}, {0.030258534476161003, -0.5337088108062744, -0.06049085408449173, -0.06599123775959015, -0.016824429854750633, -0.1420319825410843, -0.03433123230934143, -0.10755813121795654, -0.011755664832890034, -0.033444661647081375, -0.10537318140268326, -0.04665432870388031, -0.0709884762763977, -0.09382390230894089, -0.05977355316281319, -0.006864430848509073, -0.07894037663936615, -0.07580714672803879, -0.12620750069618225, -0.07429014146327972, -0.11756139993667603, -0.03486189246177673, -0.07912899553775787, -0.038790758699178696, -0.06529578566551208, -0.020097605884075165, -0.06760886311531067, 0.006338239647448063}, {-0.008149570785462856, -0.2281409353017807, -0.02317221276462078, 0.10482294857501984, -0.026631563901901245, -0.02272041141986847, -0.1762792021036148, -0.06379090994596481, 0.28265300393104553, 0.1829858273267746, -0.1753186285495758, -0.16000571846961975, -0.03318013623356819, 0.28647878766059875, 0.06253796070814133, -0.3300016224384308, -0.10609311610460281, -0.14531269669532776, -0.7605944275856018, -0.4989122152328491, -0.3356994390487671, -0.05982646346092224, 0.06342680007219315, -0.04135109484195709, 0.32415950298309326, 0.2208917886018753, -0.07768300175666809, -0.15703800320625305}, {0.03806011378765106, -0.6677188873291016, 0.15192484855651855, -0.16433456540107727, -0.34537896513938904, -0.020495647564530373, -0.03346096724271774, 0.223424032330513, -0.02972494252026081, -0.3487086594104767, -0.0456627681851387, -0.11218554526567459, -0.00014366689720191061, 0.4491022527217865, -0.5417236089706421, -0.6263294816017151, -0.6973318457603455, -0.9182674288749695, -0.2974551320075989, -0.7037410736083984, 0.0874515250325203, 0.14197714626789093, 0.4558337330818176, -0.5843172669410706, -0.5606727004051208, 0.45348820090293884, 0.44328850507736206, 0.4209005534648895}, {-0.08474959433078766, 0.15526627004146576, -0.7985652089118958, 0.21260187029838562, 0.3656609356403351, 0.12335719168186188, 0.060457415878772736, 0.24970696866512299, 0.4984481930732727, 0.3631579279899597, 0.26680564880371094, 0.5937404036521912, 0.2675668001174927, 0.26715323328971863, -0.2635864317417145, -0.6670373678207397, 0.5595815181732178, 0.3275291323661804, 0.3265022933483124, -0.0923314318060875, 0.2361195683479309, 0.8254050016403198, 0.5882598757743835, 0.8333842158317566, 0.4826344847679138, 0.6576237082481384, 0.013852320611476898, -0.13133659958839417}, {-0.03767941892147064, -0.16735343635082245, 0.07242633402347565, 0.09715986251831055, -0.08629732578992844, -0.12105050683021545, 0.19429436326026917, -1.189113974571228, -0.0438414141535759, -0.13045798242092133, 0.17313389480113983, 0.222298264503479, -0.6784869432449341, 0.044389013200998306, -0.04566064849495888, 0.1745270937681198, -0.18878957629203796, -0.68072509765625, -0.17901289463043213, -0.13348782062530518, -0.280407577753067, -0.5236465930938721, -0.09434037655591965, 0.3562553822994232, -0.14296357333660126, -0.17816492915153503, -0.262240469455719, 0.2708267867565155}, {-0.14643076062202454, 0.3134414553642273, -0.016158653423190117, 0.4832289218902588, 0.35327669978141785, 0.033485930413007736, 1.404250144958496, -0.4109203517436981, 0.3232615888118744, 0.03948039561510086, 0.14370359480381012, 1.0806249380111694, -0.43028610944747925, 0.19681444764137268, 0.3559668958187103, 0.24551646411418915, 0.7668668031692505, 0.26227831840515137, 0.24610893428325653, 0.03931723162531853, 0.1685093492269516, 0.42881014943122864, 0.605613648891449, 0.07715323567390442, 0.2259686291217804, 0.12414932996034622, 0.28258103132247925, 0.6711070537567139}, {-0.03460083529353142, 0.015175103209912777, -0.0020290936809033155, -0.2801230251789093, -0.049781594425439835, -0.08237257599830627, -0.24321754276752472, -0.30726316571235657, -0.1131473034620285, -0.016173556447029114, -0.0010477738687768579, -0.20699340105056763, -0.2045988142490387, -0.10566984117031097, -0.0597367063164711, -0.1446806639432907, -0.008996298536658287, -0.1636381596326828, -0.34909534454345703, -0.10394063591957092, 0.07907130569219589, 0.0491563156247139, 0.07572714239358902, 0.8712359666824341, 0.8652707934379578, 0.8136559128761292, 0.7329977750778198, 0.4842419922351837}, {0.028292212635278702, -0.6930311322212219, 0.4168195426464081, -0.722553014755249, 0.6128503084182739, 0.37802034616470337, -0.12130801379680634, -0.16137754917144775, -0.4547799825668335, 0.019849296659231186, -0.07699695229530334, 0.02751479111611843, 0.11456470936536789, -0.46225056052207947, -0.4128100574016571, -0.21820463240146637, -0.05070912092924118, -0.012455608695745468, 0.17457029223442078, -0.6548964381217957, 0.2514891028404236, 0.09665688127279282, -0.023784032091498375, 0.34345829486846924, -1.0899158716201782, 0.057933658361434937, -0.10579057782888412, -0.09446477890014648}, {0.06298044323921204, -0.5140762329101562, 0.10901061445474625, 0.25055184960365295, 0.16310572624206543, 0.1660183221101761, -0.2003139704465866, -0.25939759612083435, -0.759786069393158, -0.5441654324531555, -0.433865487575531, -0.2903525233268738, 0.20317135751247406, -0.05961161479353905, 0.1883774697780609, 0.07006954401731491, -0.348635733127594, 0.00569637306034565, -0.12705902755260468, 0.06386853754520416, 0.30274978280067444, -0.06455851346254349, -0.16498570144176483, -0.2735350728034973, -0.05759710818529129, -0.09640154242515564, -0.2553178668022156, 0.1108042374253273}, {0.16303423047065735, -0.840851902961731, 0.3045694828033447, 0.5177968144416809, 0.010460598394274712, -0.0009595230803824961, -0.164739727973938, -0.2865234613418579, -0.1834029257297516, 0.4267294108867645, 0.0837775319814682, -0.5739225745201111, -0.17942845821380615, 0.06667495518922806, 0.46038922667503357, 0.14962272346019745, -0.34685906767845154, 0.23869825899600983, -0.28814902901649475, -0.7657412886619568, -0.866352379322052, -0.9862637519836426, -0.18093055486679077, -0.2750402092933655, -0.2612379789352417, 0.14520415663719177, 0.41632893681526184, -0.3018798232078552}, {-0.15189743041992188, 0.24816209077835083, -0.39726874232292175, 0.10362628102302551, 0.22738219797611237, 0.13067540526390076, 0.29548943042755127, 0.37722209095954895, 0.17870138585567474, 0.2407064139842987, 0.19497083127498627, 0.3211122453212738, -0.09292492270469666, -0.12265130877494812, 0.4053817391395569, -0.11827366054058075, 0.45297837257385254, 0.11928819864988327, 0.9772109389305115, 0.5449104905128479, 0.39806750416755676, 0.4030953049659729, 0.16402702033519745, -0.14901259541511536, -0.15305542945861816, 0.16489744186401367, 0.21413367986679077, 0.5390959978103638}, {-0.054573457688093185, -0.22824183106422424, -0.3203968405723572, -0.15810002386569977, 0.5835301876068115, 0.38719215989112854, 0.4236435294151306, 0.640129566192627, -0.14881178736686707, 0.47540283203125, 0.09412529319524765, 0.06462755799293518, -0.6389226317405701, -0.10056259483098984, 0.5633905529975891, 0.08276329189538956, -0.1411363184452057, -0.009574373252689838, -0.03582749515771866, 0.6443657279014587, -0.017103971913456917, -0.17268119752407074, 0.06117372587323189, -0.04281193017959595, 0.7488794922828674, -0.06866982579231262, 0.06887611001729965, -0.11549514532089233}, {0.01342778280377388, -0.4836217761039734, -0.11072295904159546, 0.6476761698722839, 0.5931163430213928, -0.7808675169944763, -0.35797253251075745, -0.2272079437971115, 0.7021985054016113, -0.022765103727579117, -0.8641810417175293, -0.20821577310562134, -0.1716800034046173, -0.2285567671060562, -0.4907127618789673, -0.4427620768547058, 0.20067904889583588, 0.24365925788879395, -0.2677304446697235, -0.33728840947151184, 0.0702209398150444, 0.09022712707519531, 0.1330493539571762, -0.3614550530910492, -0.30246731638908386, 0.012839858420193195, 0.3226088583469391, 0.06072837859392166}, {-0.040193911641836166, -0.6861724853515625, -0.4070025682449341, 0.1424286812543869, 0.21161821484565735, 0.36073726415634155, 0.3628085255622864, -0.0990212932229042, 0.42990466952323914, 0.5575714707374573, 0.37092170119285583, 0.2522738575935364, 0.1157609149813652, 0.47637075185775757, 0.48690155148506165, 0.30947044491767883, 0.2960883677005768, 0.07852909713983536, 0.3973768353462219, 0.13431915640830994, 0.36592432856559753, 0.17452998459339142, 0.13116753101348877, -0.42777925729751587, -0.37024176120758057, -0.43283072113990784, -0.5338147878646851, -0.4905080199241638}, {-0.12332254648208618, 0.23759916424751282, -0.2621895968914032, 0.03406616672873497, 0.5511227250099182, -0.12509968876838684, -0.4177529215812683, -0.47927144169807434, 0.14296410977840424, 0.4820209741592407, 0.22033001482486725, -0.13066789507865906, -0.7484548091888428, 0.23563754558563232, 0.2622942626476288, 0.582843542098999, 0.7955005764961243, 0.9946928024291992, 0.14746436476707458, 0.043333325535058975, -0.07848695665597916, 0.10714565217494965, 0.12493138015270233, 0.1611987203359604, 0.04742865636944771, -0.26901474595069885, -0.10293031483888626, 0.010696852579712868}, {0.04099375382065773, -3.2305996417999268, 0.2543967366218567, -0.059577129781246185, -0.14682938158512115, -0.0733993723988533, -0.07150989025831223, -0.08204008638858795, -0.12635663151741028, -0.10393626242876053, -0.022796161472797394, 0.007641270756721497, -0.08665978163480759, -0.01694418303668499, -0.0025942830834537745, -0.03163212165236473, -0.022262264043092728, -0.07357636839151382, -0.07581206411123276, -0.06286846846342087, -0.1153038740158081, -0.04352688044309616, -0.08158870041370392, -0.08570341020822525, -0.06179278343915939, -0.11247510462999344, 0.0021329170558601618, -0.029320182278752327}, {0.029462160542607307, -0.5271976590156555, 0.18926401436328888, 0.02871791645884514, -0.23120182752609253, -0.786915123462677, 0.6471821665763855, 0.4379161298274994, 0.20970848202705383, -0.06591341644525528, -0.7760671973228455, 0.38167643547058105, 0.5764249563217163, 0.014545980840921402, 0.17091333866119385, -0.9253398776054382, -0.09902273863554001, -0.05899110808968544, 0.4204649329185486, 0.21064306795597076, -0.5640349984169006, -0.24353162944316864, -0.18500371277332306, -0.026613807305693626, -0.06437907367944717, -0.34146401286125183, -0.35460934042930603, -0.2743520736694336}, {-0.052965063601732254, -0.5605072379112244, 0.07962799817323685, -0.02648513950407505, -0.2291896939277649, -0.16507042944431305, -0.016116635873913765, 0.4122294485569, 0.023346038535237312, 0.06569206714630127, -0.0031419098377227783, 0.18163825571537018, 0.08935528993606567, -0.09544392675161362, -0.3773246705532074, 0.0589076466858387, 0.40520086884498596, -0.07905229926109314, -0.49348345398902893, -0.35177019238471985, -0.5805748105049133, 0.30384382605552673, 0.058458756655454636, -0.26937973499298096, -0.2887529134750366, -0.48755502700805664, 0.22864623367786407, 0.08268418908119202}, {-0.1134001687169075, -0.1595868170261383, 0.14256395399570465, 0.029054423794150352, 0.15920008718967438, 0.11821631342172623, 0.41081133484840393, 0.22583164274692535, 0.4875009059906006, -0.017819786444306374, 0.18353310227394104, 0.18164801597595215, 0.5451951622962952, 0.04068929702043533, 0.5024164319038391, 0.4954160749912262, 0.15857921540737152, 0.07034330070018768, 0.10076071321964264, -0.22763016819953918, 0.3141815662384033, 0.10078883916139603, 0.3922852873802185, 0.34453365206718445, 0.168269544839859, 0.42013704776763916, 0.07419819384813309, -0.14518938958644867}, {-0.06957618147134781, -0.06440338492393494, -0.7259829640388489, 0.5161219835281372, 0.09093577414751053, 0.4290890097618103, 0.4202098250389099, -0.027972804382443428, 0.545386791229248, 0.44505423307418823, -0.12706060707569122, 0.10054849833250046, 0.056948449462652206, 0.08831918239593506, 0.8375925421714783, 0.025092219933867455, 0.21887224912643433, 0.2599436938762665, -0.6995351910591125, 0.9659162163734436, 0.2467847764492035, 0.5137833952903748, 0.21108582615852356, -0.11285984516143799, 1.2240996360778809, -0.16404935717582703, 0.22046460211277008, 0.013526036404073238}, {-0.004826321732252836, -0.005929495673626661, 0.07865772396326065, -0.35655465722084045, -0.260633260011673, -0.37299594283103943, -0.3571874499320984, 0.6748940348625183, -0.013674028217792511, -0.27069777250289917, -0.28626859188079834, -0.02211541309952736, 0.8759161233901978, -0.2193540334701538, -0.2950937747955322, -0.1518949717283249, -0.01741132326424122, 0.7278527617454529, -0.10758645832538605, -0.14286479353904724, -0.12058365345001221, 0.05432174354791641, 0.7359171509742737, -0.20074452459812164, -0.24474677443504333, -0.20014965534210205, -0.2710004448890686, 0.5048877596855164}, {0.06318517029285431, -0.06626387685537338, 0.09102978557348251, 0.2806074619293213, -0.5871695280075073, 0.01448263693600893, -0.17774152755737305, -0.015175321139395237, 0.26823174953460693, -0.5144285559654236, -0.10162042826414108, -0.11051122844219208, -0.056919533759355545, -0.0963352620601654, -0.292245477437973, 0.07747644931077957, 0.049891501665115356, 0.04416292905807495, -0.10346058011054993, -0.27070391178131104, 0.16639839112758636, 0.13697180151939392, -0.03080388717353344, -0.3958549499511719, -0.08085988461971283, -0.15026159584522247, -0.2458583563566208, -0.1183728277683258}, {-0.031412992626428604, -0.5603559017181396, 0.23181116580963135, 0.13550354540348053, 0.1384330689907074, 0.466655433177948, 0.013126186095178127, -0.1315859854221344, 0.19236598908901215, 0.18724070489406586, 0.3651496469974518, -0.2081764191389084, -0.21705558896064758, -0.8947001695632935, -0.8844435811042786, -0.9548132419586182, -0.8363487720489502, -0.43193918466567993, 0.14401763677597046, 0.17948108911514282, 0.22730839252471924, -0.05247826129198074, -0.04454374313354492, 0.22061742842197418, 0.2703307569026947, 0.2895837426185608, -0.10765346139669418, -0.1715518683195114}, {-0.08773751556873322, 0.1905992329120636, -0.1878463476896286, -0.06142798811197281, -0.07157573848962784, -0.15859191119670868, 0.2888740599155426, 0.29501354694366455, -0.18804210424423218, 0.03719957917928696, 0.04348141327500343, 0.43497395515441895, 0.3348860740661621, 0.046619195491075516, -0.012931774370372295, 0.43330755829811096, 0.783429741859436, 0.7513718605041504, 0.42782992124557495, 0.4602666199207306, 0.8619009256362915, 0.21070736646652222, -0.6946675181388855, 0.36241528391838074, 0.5762568712234497, 0.41478705406188965, -0.7064434289932251, -0.7981423139572144}, {0.0158368032425642, -0.46186450123786926, -0.04968561232089996, 0.08248921483755112, 0.09503590315580368, -0.02358037419617176, -0.31207606196403503, 0.5838796496391296, -0.015739191323518753, 0.14295169711112976, 0.06756915897130966, -0.23699864745140076, -0.031251370906829834, 0.044411782175302505, 0.07595864683389664, -0.06131885573267937, -0.2911010682582855, -0.03894522413611412, 0.26580068469047546, 0.10324547439813614, -0.22770865261554718, -0.43839356303215027, -0.10662800073623657, -1.1684633493423462, -0.6824188828468323, -0.5405550003051758, -0.3048187494277954, 0.12504103779792786}};
const float dense1_biases[DENSE_NUM] =
-{-1.7320090532302856, -1.6262712478637695, -0.7219676971435547, -1.6883859634399414, -1.355366587638855, -1.4961345195770264, -1.6774159669876099, -1.9836738109588623, -1.8204424381256104, -1.6768863201141357, -1.5860340595245361, 0.4256221652030945, -1.9900296926498413, -2.060673952102661, -1.487168788909912, -1.653613567352295, -0.49618664383888245, -1.0318562984466553, -1.2956619262695312, -2.130068778991699, -2.124798536300659, -1.6073938608169556, -1.4884546995162964, -1.7450541257858276, -1.508810043334961, -1.4361188411712646, -1.4151768684387207, -1.6134501695632935, -1.9257988929748535, -1.8976153135299683, -1.6919738054275513, -1.7137935161590576, -0.9487504363059998, -0.7779767513275146, -2.0696449279785156, -0.4453120529651642, -0.8720207214355469, -2.00007963180542, -1.6582602262496948, -0.6423311233520508, -1.3238186836242676, -1.8345296382904053, -1.4237842559814453, -0.6334408521652222, -1.3415791988372803, -1.5188286304473877, -1.5377963781356812, -1.4456733465194702, -1.7134979963302612, -1.762224793434143, -1.760365605354309, -1.7037813663482666, -1.612302541732788, -1.613434910774231, -1.8743529319763184, -1.6047550439834595, -1.9443285465240479, -1.041770577430725, 0.48393940925598145, -1.487646460533142, -2.1693429946899414, -1.207763671875, -0.9444307684898376, -1.1276359558105469};
+{-0.1444406658411026, -0.9969395995140076, -0.6437257528305054, -0.5090100169181824, -0.4562266170978546, -0.7947681546211243, -0.66095370054245, -0.0757993534207344, -0.6305758357048035, -0.6522586345672607, -0.6137698292732239, 0.06795938313007355, -0.5988752841949463, -0.022649021819233894, -0.559893012046814, -0.34122252464294434, 0.21291229128837585, -0.9544443488121033, -0.5839042663574219, -0.3325875997543335, -0.8768086433410645, -0.3371303975582123, -0.804802417755127, -0.7296857833862305, -0.24707458913326263, -0.9100144505500793, -0.7247095704078674, -0.6324146389961243, -0.42117181420326233, -1.2145949602127075, -0.7118635177612305, -0.9112556576728821, -0.21369697153568268, -0.10298735648393631, -0.8274878263473511, -0.6126794219017029, -0.7786099314689636, -0.5083696246147156, -0.38434338569641113, -0.468181848526001, -0.5246707201004028, -0.6266580820083618, -0.3932459354400635, -0.6446056365966797, -0.8690927028656006, -0.7806448936462402, -0.7514670491218567, -0.4992736577987671, -0.4725331962108612, -0.8359085321426392, -0.3995131254196167, -0.701408326625824, 0.13735836744308472, -0.7701425552368164, 0.37747254967689514, -0.8496323227882385, -0.41388845443725586, -0.3626680374145508, -0.4750637412071228, -1.0076007843017578, -0.4247843325138092, -0.8280375599861145, -0.8584521412849426, -0.49181294441223145};
const float output_weights[2][DENSE_NUM] =
-{{-0.1246807649731636, -0.08505872637033463, -0.0652783066034317, 0.1350107192993164, 0.1698562055826187, 0.400063693523407, 0.17860691249370575, -0.1349184215068817, 0.20356398820877075, 0.16311302781105042, -0.036207523196935654, 0.7803400754928589, -0.13074463605880737, -0.06796154379844666, 0.20493201911449432, 0.14702282845973969, -0.11247620731592178, 0.22241809964179993, 0.1635751873254776, -0.08345462381839752, -0.2028568834066391, 0.12081773579120636, -0.1835630089044571, 0.1626814305782318, 0.16333818435668945, -0.27365756034851074, 0.13540410995483398, -0.13346917927265167, -0.1633249968290329, 0.17652902007102966, 0.1970495879650116, -0.0996168851852417, 0.1257164627313614, -0.02319495752453804, 0.1254752278327942, 0.004205659963190556, -0.11657992005348206, -0.13747099041938782, -0.12851183116436005, -0.13266359269618988, 0.15070892870426178, 0.18036587536334991, -0.120721235871315, -0.07944180071353912, -0.07511389255523682, -0.14644883573055267, 0.11276227235794067, 0.1335425227880478, -0.12701821327209473, 0.20198681950569153, -0.06599707156419754, -0.14891819655895233, 0.2015286684036255, 0.17373384535312653, 0.1385129988193512, 0.1480085849761963, 0.20751388370990753, -0.127104252576828, -0.5856947302818298, -0.26959943771362305, -0.10330907255411148, 0.14857497811317444, -0.168384850025177, -0.23837287724018097}, {0.05711914226412773, 0.1704198718070984, 0.07292810082435608, -0.1523439884185791, -0.20949530601501465, -0.33654606342315674, -0.23295333981513977, 0.09389320015907288, -0.23792678117752075, -0.17215877771377563, 0.06109726428985596, -0.7076484560966492, 0.0808710902929306, 0.06764110177755356, -0.08750396966934204, -0.12129006534814835, 0.08196759223937988, -0.22181545197963715, -0.10018306225538254, 0.09599480032920837, 0.2410762906074524, -0.16045424342155457, 0.12080714106559753, -0.14531971514225006, -0.14728260040283203, 0.389263778924942, -0.14980417490005493, 0.14908818900585175, 0.1427009552717209, -0.18783621490001678, -0.17802631855010986, 0.10279617458581924, -0.1660611927509308, 0.03492075577378273, -0.0730394646525383, 0.011791321448981762, 0.09671367704868317, 0.10834173858165741, 0.12392941862344742, 0.08413772284984589, -0.18994614481925964, -0.20133660733699799, 0.07802799344062805, 0.06276662647724152, 0.06052928790450096, 0.12486152350902557, -0.10323746502399445, -0.1355014443397522, 0.16498015820980072, -0.2137404978275299, 0.10234697163105011, 0.12195070087909698, -0.15739789605140686, -0.13428226113319397, -0.0960799902677536, -0.1424444168806076, -0.18782544136047363, 0.14121107757091522, 0.6669175624847412, 0.2753967046737671, 0.09798707813024521, -0.16682972013950348, 0.1646665632724762, 0.24278126657009125}};
+{{-0.10164133459329605, -0.06545510143041611, -0.12559004127979279, -0.09770263731479645, 0.020511239767074585, -0.11956804245710373, 0.0725698173046112, 0.09884587675333023, 0.03334106504917145, -0.07531746476888657, -0.04404358193278313, 0.04667624458670616, -0.10733920335769653, 0.11603111028671265, -0.09832630306482315, -0.029710080474615097, 0.6112914681434631, 0.09875980764627457, 0.04528747498989105, 0.04975724592804909, 0.05296019837260246, -0.1494731307029724, 0.06372635811567307, 0.05117323249578476, -0.4960876405239105, 0.08172430098056793, 0.09049712121486664, 0.16494503617286682, 0.12463495880365372, 0.10889994353055954, 0.0901939794421196, -0.07425925135612488, -0.09327994287014008, 0.07225991785526276, 0.0995996817946434, 0.1002214103937149, 0.13605892658233643, -0.2738678455352783, 0.07213583588600159, 0.031051557511091232, -0.09413432329893112, -0.05657240375876427, 0.023954149335622787, -0.11132869869470596, 0.0918613076210022, 0.1731780767440796, -0.048148252069950104, -0.08594620227813721, -0.07079077512025833, 0.028347637504339218, 0.04007003828883171, -0.08521876484155655, -0.13736766576766968, 0.0973486453294754, -0.3953056037425995, -0.09303829818964005, 0.0926792323589325, 0.08662958443164825, 0.07239469885826111, 0.12995171546936035, -0.08624651283025742, -0.13703757524490356, 0.1074426919221878, -0.05400789529085159}, {0.09475231915712357, 0.10763916373252869, 0.10490848124027252, 0.051702577620744705, -0.025973767042160034, 0.1243276372551918, -0.09184729307889938, -0.09110323339700699, -0.10927686840295792, 0.07648954540491104, 0.08314546942710876, -0.054432936012744904, 0.11420167982578278, -0.14501862227916718, 0.07449985295534134, 0.04114171117544174, -0.5540419816970825, -0.11702275276184082, -0.057106584310531616, -0.11389349400997162, -0.04799086973071098, 0.11528362333774567, -0.10561501979827881, -0.06099977344274521, 0.5406088829040527, -0.07843243330717087, -0.07121624052524567, -0.15534670650959015, -0.10739737004041672, -0.10599866509437561, -0.03090781159698963, 0.1024080142378807, 0.11164399981498718, -0.10347762703895569, -0.09762325882911682, -0.044070787727832794, -0.1382112205028534, 0.2635824978351593, -0.013381495140492916, -0.017522230744361877, 0.09075458347797394, 0.08058229833841324, -0.03840004280209541, 0.08596818149089813, -0.10802465677261353, -0.17988164722919464, 0.08185803890228271, 0.09076226502656937, 0.042497776448726654, -0.0991385206580162, -0.03188726678490639, 0.0789727196097374, 0.12080144137144089, -0.12002957612276077, 0.3941708207130432, 0.07739747315645218, -0.04954647645354271, -0.10626203566789627, -0.054530855268239975, -0.19077910482883453, 0.07939524203538895, 0.10724455863237381, -0.09315766394138336, 0.07806982845067978}};
const float output_bias[2] =
-{0.5831990242004395, 0.4281694293022156};
+{0.3762611150741577, 0.6172211170196533};
diff --git a/include/weights.h b/include/weights.h
index c4e0c3c..7a37ed9 100644
--- a/include/weights.h
+++ b/include/weights.h
@@ -15,10 +15,9 @@
along with ct. If not, see <https://www.gnu.org/licenses/>.
*/
-#define INP_NUM 3 + 5*5
+#define INP_NUM 3 + 5 * 5
#define DENSE_NUM 64
-
extern const float dense1_weights[DENSE_NUM][INP_NUM];
extern const float dense1_biases[DENSE_NUM];
extern const float output_weights[2][DENSE_NUM];
diff --git a/include/xorshift64.h b/include/xorshift64.h
index b9ba97a..c3542c6 100644
--- a/include/xorshift64.h
+++ b/include/xorshift64.h
@@ -22,13 +22,14 @@
extern uint64_t xors;
-#define XORSHIFT64 { \
- xors ^= xors >> 12; \
- xors ^= xors << 25; \
- xors ^= xors >> 27; \
+#define XORSHIFT64 \
+ { \
+ xors ^= xors >> 12; \
+ xors ^= xors << 25; \
+ xors ^= xors >> 27; \
}
-#define RANDOM64 (xors*0x2545F4914F6CDD1D)
+#define RANDOM64 (xors * 0x2545F4914F6CDD1D)
#define RANDOM32 ((uint32_t)RANDOM64)
#endif
diff --git a/include/zobrist.c b/include/zobrist.c
index 1fdd8a9..d8d1856 100644
--- a/include/zobrist.c
+++ b/include/zobrist.c
@@ -27,13 +27,14 @@ static uint64_t *zobrist;
// Exported method implementations
// ===================================================================
-int zobrist_init(void) {
- if (zobrist != NULL) return EXIT_FAILURE;
+int zobrist_init(const uint8_t board_size) {
+ if (zobrist != NULL)
+ return EXIT_FAILURE;
- zobrist = malloc(sizeof(uint64_t)*board_size*board_size*(15*2*3));
+ zobrist = malloc(sizeof(uint64_t) * board_size * board_size * (15 * 2 * 3));
// TODO: trap errno
- for (int k=0; k<board_size*board_size*(15*2*3); k++) {
+ for (int k = 0; k < board_size * board_size * (15 * 2 * 3); k++) {
XORSHIFT64;
zobrist[k] = RANDOM64;
}
@@ -48,14 +49,14 @@ void zobrist_free(void) {
}
}
-uint64_t zobrist_compute(void) {
+uint64_t zobrist_compute(tak_state_p state) {
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[l*(15*2*3)+h*2*3+(c&1)*3+s];
+ for (uint8_t l = 0; l < state->board_size * state->board_size; l++) {
+ colour_stack_t c = state->colours[l];
+ const uint8_t count = COUNT_AT(state, l);
+ enum STONE_VARIANT s = STONE_AT(state, l);
+ for (uint8_t h = 0; h < count; h++, c >>= 1)
+ hash ^= zobrist[l * (15 * 2 * 3) + h * 2 * 3 + (c & 1) * 3 + s];
}
return hash;
}
diff --git a/include/zobrist.h b/include/zobrist.h
index be93910..6a1de4f 100644
--- a/include/zobrist.h
+++ b/include/zobrist.h
@@ -15,12 +15,12 @@
along with ct. If not, see <https://www.gnu.org/licenses/>.
*/
-#include <xorshift64.h>
-#include <tak.h>
#include <actions.h>
+#include <tak.h>
+#include <xorshift64.h>
void zobrist_free(void);
-int zobrist_init(void);
+int zobrist_init(const uint8_t board_size);
-uint64_t zobrist_compute(void);
+uint64_t zobrist_compute(tak_state_p state);