diff options
| author | tslil <tslil@posteo.de> | 2026-09-11 12:56:12 +0100 |
|---|---|---|
| committer | tslil <tslil@posteo.de> | 2026-09-11 17:00:18 +0100 |
| commit | 6e90f1145b2c5c0f2dcc82d21ec45432274b8cad (patch) | |
| tree | 18db1c03ea7c3c4724028fc5154d4bca3d7200a5 /src/match.c | |
| parent | 220a4b79e4b6d742a9ca7c278a1962b870500fbc (diff) | |
move from single candidate td-leaf with gating to tournament of a population
The goal in this change was to overcome the rock-paper-scissors phenomenon that was happening in capability space by having on a single candidate learn to beat the most recent version of itself. In some sense this lead to rotating around in capability space instead of chasing monotonic improvements.
I hope that flipping to a system in which many (N=5) candidates play each other and learn from their own set of diverse games in this pool, combined with --replay-iters, will lead to a given network having to have a much more comprehensive understanding of the space of tactics. I haven't yet had time to train this thorougly, will run those experiments on my desktop computer.
Diffstat (limited to 'src/match.c')
| -rw-r--r-- | src/match.c | 173 |
1 files changed, 0 insertions, 173 deletions
diff --git a/src/match.c b/src/match.c deleted file mode 100644 index 459fab5..0000000 --- a/src/match.c +++ /dev/null @@ -1,173 +0,0 @@ -/* - match, one game of candidate weights against the candidate weights - - Copyright (C) 2026, tslil clingman - - 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 - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with ctak. If not, see <https://www.gnu.org/licenses/>. -*/ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <unistd.h> - -#include "actions.h" -#include "negamax.h" -#include "nn.h" -#include "tak.h" -#include "xorshift64.h" - -// a little gymnastics to insert candidate neural networks -#include "weights_5.h" -#include "weights_6.h" -#include "cand_weights_5.c" -#include "cand_weights_6.c" - -static inline float five_cand(tak_state_p state) { - static float cur_board[FIVE_INP_NUM] NN_ALIGNED; - - nn_prepare_input(cur_board, state, cand_five_embedding); - return eval_net(cur_board, FIVE_INP_NUM, &cand_five_dense_weights[0][0], - cand_five_dense_biases, cand_five_logit_weights, cand_five_logit_bias, - FIVE_DENSE_NUM, state->ply & 1 ? 1.0f : -1.0f); -} - -static inline float six_cand(tak_state_p state) { - static float cur_board[SIX_INP_NUM] NN_ALIGNED; - - nn_prepare_input(cur_board, state, cand_six_embedding); - return eval_net(cur_board, SIX_INP_NUM, &cand_six_dense_weights[0][0], - cand_six_dense_biases, cand_six_logit_weights, cand_six_logit_bias, - SIX_DENSE_NUM, state->ply & 1 ? 1.0f : -1.0f); -} - - -#define MAX_PLY 255 - -static tak_state_p state; - -void negamax_display_progress(const uint8_t cur_depth, - const uint8_t init_depth, - const uint32_t length) { - (void)(cur_depth); - (void)(init_depth); - (void)(length); -} - -// =================================================================== -// Game driver -// =================================================================== - -static int play_game(const nn_function current_fn, const nn_function cand_fn, - const enum COLOUR current_fn_colour, - const uint8_t random_opening_length) { - reset_state(state, state->board_size); - char ptn[16]; - - for (uint32_t ply = 0; ply + negamax_search_depth < MAX_PLY; ply++) { - if (ply < random_opening_length) { - uint32_t n_actions; - action_t *actions = actions_generate(state, &n_actions); - action_to_ptn(actions[rand32() % n_actions], ptn); - } else { - const nn_function fn = - (state->current_colour == current_fn_colour) ? current_fn : cand_fn; - negamax_set_evaluator(fn); - negamax_generate(state); - strcpy(ptn, negamax_ptn); - } - - const enum ACT_RESULT r = do_ptn(state, ptn); - if (r == GAME_END) - break; - if (r != ACT_OK) { - fprintf(stderr, "match: unexpected result %d for ptn %s\n", r, ptn); - return -2; - } - } - - switch (state->won) { - case WIN_DRAW: - return -1; - case WIN_FLAT_BLACK: - case WIN_ROAD_BLACK: - return C_BLACK; - case WIN_FLAT_WHITE: - case WIN_ROAD_WHITE: - return C_WHITE; - default: - // ply cap reached with no winner: a draw - return -1; - } -} - -void do_game(const uint8_t size, const uint8_t random_opening_length, const enum COLOUR current_fn_colour) { - state = new_tak_state(size); - negamax_init(size); - - const nn_function current_fn = - (size == 5) ? &five_nn_fn : &six_nn_fn; - const nn_function cand_fn = (size == 5) ? &five_cand : &six_cand; - - const int winner = play_game(current_fn, cand_fn, current_fn_colour, random_opening_length); - - const char *name; - if (winner == -1) - name = "draw"; - else if (winner == (int)current_fn_colour) - name = "current"; - else - name = "candidate"; - printf("%s %u\n", name, state->ply); - - negamax_free(); - free_tak_state(state); -} - - // =================================================================== - // Main - // =================================================================== - - const char *usage = - "match, one Tak game of the current weights against the candidate.\n\n\ -usage: match <size> <random_opening_length> <depth>\n\n\ -This binary is linked with both the include/weight_* files and the include/cand_weight_* files. It plays a single <size>x<size> game, with a random side choice and both sides using <random_opening_length> random moves at the start of the game. The result format is:\n\n\ -\t<current|candidate|draw> <plies>\n\n\ -nn_train.py runs many of these in parallel to score the candidate against the current weights.\n\n\ -Copyright (C) 2026, tslil clingman\n\n\ -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 the Free Software Foundation, either version 3 of the License, or (at your option) any later version."; - -int main(int argc, char **argv) { - if (argc != 4) { - puts(usage); - return EXIT_FAILURE; - } - - const uint8_t size = (uint8_t)atoi(argv[1]); - const uint8_t random_opening_length = (uint8_t)atoi(argv[2]); - negamax_search_depth = (uint8_t)atoi(argv[3]); - - if (size != 5 && size != 6) { - fprintf(stderr, "match: size must be 5 or 6\n"); - return EXIT_FAILURE; - } - xors = ((uint64_t)time(NULL) ^ ((uint64_t)getpid() << 32)) * - 0x9E3779B97F4A7C15ULL + - 0xC0FFEE; - - do_game(size, random_opening_length, C_BLACK); - do_game(size, random_opening_length, C_WHITE); - - return EXIT_SUCCESS; -} |
