From 241156da6f35cb888253e6b8814e7b61a76b4fc7 Mon Sep 17 00:00:00 2001 From: tslil Date: Sun, 30 Aug 2026 19:46:07 +0100 Subject: TD(lambda), and a big rework NOTE: 6x6 weights are as-yet untrained On the performance side: * switch from linked-list chaining hash table to direct mapping * cache check_win by hash * persist transposition tables across plies (this was a big deal and difficult to puzzle out) * add align directives to the network floats * prepare_nn_input gained a small LUT to avoid branching (i suppose you might call this 1D embedding) * apply mtune=native for the native builds On the correctness side: * Zobrist has now includes the ply parity * the network now predicts something in [-1, 1] using tanh (approximated by polynomials) * the training object is now MSE because we're learning a value estimate * use .clangd instead of compile_commands.json On the training side: * completely forgo human-derived data set * implement td(lambda), self-play, tournaments --- include/zobrist.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'include/zobrist.c') diff --git a/include/zobrist.c b/include/zobrist.c index d8d1856..2922abf 100644 --- a/include/zobrist.c +++ b/include/zobrist.c @@ -1,5 +1,5 @@ /* - This file is part of ct. + This file is part of ctak. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -12,10 +12,11 @@ General Public License for more details. You should have received a copy of the GNU General Public License - along with ct. If not, see . + along with ctak. If not, see . */ #include "zobrist.h" +#include "xorshift64.h" // =================================================================== // Variables @@ -35,8 +36,7 @@ int zobrist_init(const uint8_t board_size) { // TODO: trap errno for (int k = 0; k < board_size * board_size * (15 * 2 * 3); k++) { - XORSHIFT64; - zobrist[k] = RANDOM64; + zobrist[k] = rand64(); } return EXIT_SUCCESS; @@ -49,6 +49,11 @@ void zobrist_free(void) { } } + +// a position's value is from the perspective of the player to move, which flips +// with parity, so we must track this +#define PLY_PARITY_MAGIC 0x9E3779B97F4A7C15ULL + uint64_t zobrist_compute(tak_state_p state) { uint64_t hash = 0; for (uint8_t l = 0; l < state->board_size * state->board_size; l++) { @@ -58,5 +63,5 @@ uint64_t zobrist_compute(tak_state_p state) { 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; + return hash ^ ((state->ply & 1) ? PLY_PARITY_MAGIC : 0); } -- cgit v1.3.1