ref: f770cee72ae565567d0a201cc211cf9329c6c771
parent: e4ef04c293715e65cb66a5922596240ecb99a24b
author: zamfofex <zamfofex@twdb.moe>
date: Wed May 28 17:45:32 EDT 2025
make miscellaneous improvements
--- a/README.md
+++ b/README.md
@@ -47,7 +47,6 @@
These are things that might be resolved eventually.
- the TUI does not let you underpromote
-- no support for `go depth`, `go infinite`, `go mate`
- no support for some seldom used UCI features
download
@@ -120,7 +119,7 @@
After compiling and running it, you may use the mouse to click and move pieces around. (So, they require mouse support from your terminal.)
-To analyse a game with a UCI bot, use `./analyse` followed optionally by the UCI options you want to specify, and then the command of whichever bot you want to use for analysis. (Though note that moonfish has limited analysis capabilities.)
+To analyse a game with a UCI bot, use `./analyse` followed optionally by the UCI options you want to specify, and then the command of whichever bot you want to use for analysis.
~~~
# (analyse a game using Stockfish)
--- a/main.c
+++ b/main.c
@@ -6,6 +6,7 @@
#include <string.h>
#include <stdio.h>
#include <ctype.h>
+#include <math.h>
#include "moonfish.h"
#include "threads.h"
@@ -38,8 +39,13 @@
return -1;
}
-static moonfish_result_t moonfish_go0(void *data)
+static void moonfish_log_result(struct moonfish_result *result)
{+ printf("info depth %.0f nodes %ld time %ld", log(result->node_count) / log(16), result->node_count, result->time);+}
+
+static void moonfish_log(struct moonfish_result *result0, void *data)
+{static struct moonfish_move pv[256];
static struct moonfish_result result;
static struct moonfish_chess chess;
@@ -49,15 +55,23 @@
char name[6];
info = data;
+ count0 = moonfish_getoption(info->options, "MultiPV");
- moonfish_best_move(info->root, &info->result, &info->search_options);
+ if (count0 == 0) {+ moonfish_log_result(result0);
+ printf(" score cp %d\n", result0->score);+ fflush(stdout);
+ return;
+ }
- count0 = moonfish_getoption(info->options, "MultiPV");
for (i = 0 ; i < count0 ; i++) {count = sizeof pv / sizeof *pv;
moonfish_pv(info->root, pv, &result, i, &count);
if (count == 0) continue;
- printf("info depth 1 score cp %d nodes %ld multipv %d pv", result.score, result.node_count, i + 1);+ moonfish_log_result(result0);
+ if (count0 > 1) printf(" multipv %d", i + 1);+ printf(" score cp %d", result.score);+ if (count > 0) printf(" pv");moonfish_root(info->root, &chess);
for (j = 0 ; j < count ; j++) {moonfish_to_uci(&chess, pv + j, name);
@@ -65,15 +79,34 @@
printf(" %s", name);}
printf("\n");+ fflush(stdout);
}
+}
+
+static moonfish_result_t moonfish_go0(void *data)
+{+ static struct moonfish_chess chess;
- printf("info depth 1 score cp %d nodes %ld\n", info->result.score, info->result.node_count);+ struct moonfish_info *info;
+ char name[6];
+ info = data;
moonfish_root(info->root, &chess);
+ if (moonfish_finished(&chess)) {+ printf("bestmove 0000\n");+ fflush(stdout);
+ info->searching = 0;
+ return moonfish_value;
+ }
+
+ moonfish_best_move(info->root, &info->result, &info->search_options);
moonfish_to_uci(&chess, &info->result.move, name);
+ moonfish_log_result(&info->result);
+ printf(" score cp %d\n", info->result.score); printf("bestmove %s\n", name);fflush(stdout);
+ info->searching = 0;
return moonfish_value;
}
@@ -84,6 +117,7 @@
long int our_time, their_time, *xtime, time;
char *arg, *end;
long int node_count;
+ long int depth;
info->searching = 1;
@@ -91,6 +125,7 @@
their_time = -1;
time = -1;
node_count = -1;
+ depth = -1;
moonfish_root(info->root, &chess);
@@ -99,6 +134,8 @@
arg = strtok(NULL, "\r\n\t ");
if (arg == NULL) break;
+ if (!strcmp(arg, "infinite")) continue;
+
if (!strcmp(arg, "wtime") || !strcmp(arg, "btime")) { if (chess.white) {@@ -161,6 +198,24 @@
continue;
}
+
+ if (!strcmp(arg, "depth")) {+
+ arg = strtok(NULL, "\r\n\t ");
+ if (arg == NULL) {+ fprintf(stderr, "malformed 'go depth' command\n");
+ exit(1);
+ }
+
+ errno = 0;
+ depth = strtol(arg, &end, 10);
+ if (errno || *end != 0 || depth < 0) {+ fprintf(stderr, "malformed 'depth' in 'go' command\n");
+ exit(1);
+ }
+
+ continue;
+ }
}
info->search_options.max_time = time;
@@ -168,6 +223,13 @@
info->search_options.thread_count = moonfish_getoption(info->options, "Threads");
info->search_options.node_count = node_count;
+ if (depth >= 0 && depth < 6) {+ node_count = pow(16, depth);
+ if (node_count < info->search_options.node_count || info->search_options.node_count < 0) {+ info->search_options.node_count = node_count;
+ }
+ }
+
#ifdef moonfish_no_threads
moonfish_go0(info);
#else
@@ -184,8 +246,6 @@
exit(1);
}
#endif
-
- info->searching = 0;
}
static void moonfish_position(struct moonfish_root *root)
@@ -325,8 +385,8 @@
#ifndef moonfish_no_threads
{"Threads", "spin", 1, 1, 0xFFFF},#endif
- {"MultiPV", "spin", 0, 0, 256},- {NULL},+ {"MultiPV", "spin", 1, 0, 256},+ {NULL, NULL, 0, 0, 0},};
char *arg;
@@ -345,6 +405,8 @@
info.has_thread = 0;
#endif
+ moonfish_idle(info.root, &moonfish_log, &info);
+
for (;;) {fflush(stdout);
@@ -395,7 +457,7 @@
if (!strcmp(arg, "setoption")) {moonfish_setoption(&info);
- if (info.searching) printf("info string warning: option may only take effect next search request\n");+ if (info.searching) printf("info string warning: option might only take effect next search request\n");continue;
}
--- a/makefile
+++ b/makefile
@@ -30,6 +30,7 @@
lichess: tools/lichess.o tools/https.o
analyse: tools/analyse.o tools/pgn.o
chat: tools/chat.o tools/https.o
+perft: tools/perft.o
$(obj): moonfish.h
$(tool_obj): moonfish.h tools/tools.h
--- a/moonfish.h
+++ b/moonfish.h
@@ -108,6 +108,7 @@
struct moonfish_result {struct moonfish_move move;
long int node_count;
+ long int time;
int score;
};
@@ -210,6 +211,9 @@
/* requests the PV with the given index, with at most 'count' moves */
void moonfish_pv(struct moonfish_root *root, struct moonfish_move *moves, struct moonfish_result *result, int index, int *count);
+
+/* adds an "idle/log" handler, which will be called every once in a while during search */
+void moonfish_idle(struct moonfish_root *root, void (*log)(struct moonfish_result *result, void *data), void *data);
#endif
--- a/scripts/check.sh
+++ b/scripts/check.sh
@@ -7,9 +7,8 @@
go()
{- echo 'setoption name Threads value 1'
echo "position fen $1"
- echo "go nodes $2"
+ echo "go depth $2"
while read -r line
do
case "$line" in "bestmove "*)
@@ -23,8 +22,8 @@
{echo "- - - POSITION $2 - - -" >&2
./perft -F "$3" "$1"
- coproc go "$3" `expr "$1" '*' 4096 + 2048`
- { ./moonfish | tee /dev/fd/3 3> /dev/fd/3 ; } <&"${COPROC[0]}" 3>&"${COPROC[1]}"+ coproc go "$3" "$1"
+ { ./moonfish | tee /dev/fd/3 3> /dev/fd/3 | tail -2 | sed -E 's/ time [^ ]+//g' ; } <&"${COPROC[0]}" 3>&"${COPROC[1]}"echo >&2
}
--- a/scripts/check.txt
+++ b/scripts/check.txt
@@ -1,105 +1,105 @@
perft 0: 1
-info depth 1 score cp 23 nodes 2048
-bestmove e2e4
+info depth 2 nodes 1024 score cp 30
+bestmove b1c3
perft 0: 1
-info depth 1 score cp 213 nodes 2048
+info depth 2 nodes 1024 score cp 223
bestmove e2a6
perft 0: 1
-info depth 1 score cp 136 nodes 2048
+info depth 2 nodes 1024 score cp 123
bestmove b4f4
perft 0: 1
-info depth 1 score cp -481 nodes 2048
-bestmove d2d4
+info depth 2 nodes 1024 score cp -491
+bestmove c4c5
perft 0: 1
-info depth 1 score cp -481 nodes 2048
-bestmove d7d5
+info depth 2 nodes 1024 score cp -491
+bestmove c5c4
perft 0: 1
-info depth 1 score cp 365 nodes 2048
+info depth 2 nodes 1024 score cp 577
bestmove d7c8q
perft 0: 1
-info depth 1 score cp 179 nodes 2048
-bestmove c3d5
+info depth 2 nodes 1024 score cp 96
+bestmove g5f6
perft 1: 20
-info depth 1 score cp -3 nodes 6144
+info depth 2 nodes 1024 score cp 30
bestmove b1c3
perft 1: 48
-info depth 1 score cp 47 nodes 6144
+info depth 2 nodes 1024 score cp 223
bestmove e2a6
perft 1: 14
-info depth 1 score cp 64 nodes 6144
-bestmove b4c4
+info depth 2 nodes 1024 score cp 123
+bestmove b4f4
perft 1: 6
-info depth 1 score cp -442 nodes 6144
+info depth 2 nodes 1024 score cp -491
bestmove c4c5
perft 1: 6
-info depth 1 score cp -442 nodes 6144
+info depth 2 nodes 1024 score cp -491
bestmove c5c4
perft 1: 44
-info depth 1 score cp 600 nodes 6144
-bestmove d7c8r
+info depth 2 nodes 1024 score cp 577
+bestmove d7c8q
perft 1: 46
-info depth 1 score cp -27 nodes 6144
-bestmove c3d5
+info depth 2 nodes 1024 score cp 96
+bestmove g5f6
perft 2: 400
-info depth 1 score cp 0 nodes 10240
+info depth 2 nodes 1024 score cp 30
bestmove b1c3
perft 2: 2039
-info depth 1 score cp 93 nodes 10240
+info depth 2 nodes 1024 score cp 223
bestmove e2a6
perft 2: 191
-info depth 1 score cp 38 nodes 10240
-bestmove b4c4
+info depth 2 nodes 1024 score cp 123
+bestmove b4f4
perft 2: 264
-info depth 1 score cp -173 nodes 10240
+info depth 2 nodes 1024 score cp -491
bestmove c4c5
perft 2: 264
-info depth 1 score cp -173 nodes 10240
+info depth 2 nodes 1024 score cp -491
bestmove c5c4
perft 2: 1486
-info depth 1 score cp 640 nodes 10240
-bestmove d7c8r
+info depth 2 nodes 1024 score cp 577
+bestmove d7c8q
perft 2: 2079
-info depth 1 score cp 15 nodes 10240
-bestmove c3d5
+info depth 2 nodes 1024 score cp 96
+bestmove g5f6
perft 3: 8902
-info depth 1 score cp 9 nodes 14336
+info depth 3 nodes 4096 score cp 2
bestmove b1c3
perft 3: 97862
-info depth 1 score cp 212 nodes 14336
+info depth 3 nodes 4096 score cp 116
bestmove e2a6
perft 3: 2812
-info depth 1 score cp 26 nodes 14336
+info depth 3 nodes 4096 score cp 64
bestmove b4c4
perft 3: 9467
-info depth 1 score cp -343 nodes 14336
-bestmove g1h1
+info depth 3 nodes 4096 score cp -498
+bestmove b4c5
perft 3: 9467
-info depth 1 score cp -343 nodes 14336
-bestmove g8h8
+info depth 3 nodes 4096 score cp -498
+bestmove b5c4
perft 3: 62379
-info depth 1 score cp 640 nodes 14336
-bestmove d7c8r
+info depth 3 nodes 4096 score cp 304
+bestmove d7c8q
perft 3: 89890
-info depth 1 score cp 161 nodes 14336
-bestmove c3d5
+info depth 3 nodes 4096 score cp 35
+bestmove c4d5
perft 4: 197281
-info depth 1 score cp 16 nodes 18432
-bestmove g1f3
+info depth 4 nodes 65536 score cp 37
+bestmove d2d4
perft 4: 4085603
-info depth 1 score cp 217 nodes 18432
+info depth 4 nodes 65536 score cp -78
bestmove e2a6
perft 4: 43238
-info depth 1 score cp 123 nodes 18432
-bestmove b4f4
+info depth 4 nodes 65536 score cp 109
+bestmove b4c4
perft 4: 422333
-info depth 1 score cp -251 nodes 18432
-bestmove f3d4
+info depth 4 nodes 65536 score cp -473
+bestmove c4c5
perft 4: 422333
-info depth 1 score cp -251 nodes 18432
-bestmove f6d5
+info depth 4 nodes 65536 score cp -473
+bestmove c5c4
perft 4: 2103487
-info depth 1 score cp 641 nodes 18432
-bestmove d7c8r
+info depth 4 nodes 65536 score cp 585
+bestmove d7c8q
perft 4: 3894594
-info depth 1 score cp 164 nodes 18432
+info depth 4 nodes 65536 score cp -43
bestmove c3d5
--- a/scripts/compare.sh
+++ b/scripts/compare.sh
@@ -11,9 +11,6 @@
# note: use this script only from the root/project directory
-make=gmake
-which "$make" &> /dev/null || make=make
-
rm -f moonfish
mkdir -p compare
[[ -f compare/openings.fen ]] || wget -O- https://moonfish.cc/pohl.fen.xz | xz -d > compare/openings.fen
@@ -22,7 +19,7 @@
[[ "x$(git status --porcelain)" = x ]] || dirty=-dirty
rev1="$(git rev-parse --short HEAD)"
-"$make" moonfish
+make moonfish
mv -f moonfish compare/moonfish-"$rev1$dirty"
git stash
@@ -29,7 +26,7 @@
git reset --hard "${1:-main}"rev2="$(git rev-parse --short HEAD)"
-"$make" moonfish
+make moonfish
mv -f moonfish compare/moonfish-"$rev2"
[[ "$rev1" = "$rev2" ]] || git reset --hard "$rev1"
@@ -58,7 +55,7 @@
"$cli" \
-engine {name=,cmd=./}moonfish-"$rev1$dirty" \ -engine {name=,cmd=./}moonfish-"$rev2" \- -each $protocol tc=inf/10+0.1 option.Threads=1 \
+ -each $protocol tc=inf/10+0.1 option.MultiPV=0 \
-openings $format file=openings.fen order=random \
-games 2 -rounds 1024 \
-sprt elo0=0 elo1=12 alpha=0.05 beta=0.05 \
--- a/search.c
+++ b/search.c
@@ -18,7 +18,7 @@
#ifdef _WIN32
-static unsigned long int moonfish_clock(void)
+static long int moonfish_clock(void)
{return GetTickCount();
}
@@ -27,7 +27,7 @@
#ifdef moonfish_no_clock
-static unsigned long int moonfish_clock(void)
+static long int moonfish_clock(void)
{time_t t;
if (time(&t) < 0) {@@ -39,7 +39,7 @@
#else
-static unsigned long int moonfish_clock(void)
+static long int moonfish_clock(void)
{struct timespec ts;
if (clock_gettime(CLOCK_MONOTONIC, &ts)) {@@ -56,7 +56,7 @@
struct moonfish_node {struct moonfish_node *parent;
struct moonfish_node *children;
- _Atomic int visits, count, uses;
+ _Atomic int visits, count;
_Atomic short int score;
_Atomic unsigned char bounds[2];
_Atomic unsigned char ignored;
@@ -66,17 +66,11 @@
struct moonfish_root {struct moonfish_node node;
struct moonfish_chess chess;
+#ifndef moonfish_mini
_Atomic int stop;
-};
-
-struct moonfish_thread {-#ifndef moonfish_no_threads
- thrd_t thread;
+ void (*log)(struct moonfish_result *result, void *data);
+ void *data;
#endif
- struct moonfish_root *root;
- unsigned long int time, time0;
- long int node_count;
- unsigned char clean;
};
static short int moonfish_score(struct moonfish_chess *chess)
@@ -125,23 +119,9 @@
static void moonfish_discard(struct moonfish_node *node)
{- int i, count;
-
-#ifdef moonfish_no_threads
- count = node->count;
-#else
- for (;;) {- count = node->count;
- if (count < 0) continue;
- if (atomic_compare_exchange_strong(&node->count, &count, -2)) break;
- }
- for (;;) {- if (node->uses == 0) break;
- }
-#endif
-
- for (i = 0 ; i < count ; i++) moonfish_discard(node->children + i);
- if (count > 0) free(node->children);
+ int i;
+ for (i = 0 ; i < node->count ; i++) moonfish_discard(node->children + i);
+ if (node->count > 0) free(node->children);
node->count = 0;
}
@@ -153,7 +133,6 @@
node->ignored = 0;
node->bounds[0] = 0;
node->bounds[1] = 1;
- node->uses = 0;
}
static int moonfish_compare(const void *ax, const void *bx)
@@ -239,17 +218,6 @@
moonfish_play(chess, &move);
}
-#ifndef moonfish_no_threads
-
-static void moonfish_clear(struct moonfish_node *node)
-{- if (node == NULL) return;
- moonfish_clear(node->parent);
- atomic_fetch_add(&node->uses, -1);
-}
-
-#endif
-
static struct moonfish_node *moonfish_select(struct moonfish_node *node, struct moonfish_chess *chess)
{struct moonfish_node *next;
@@ -262,23 +230,16 @@
count = node->count;
if (count == 0) return node;
#else
- atomic_fetch_add(&node->uses, 1);
for (;;) {count = 0;
if (atomic_compare_exchange_strong(&node->count, &count, -1)) return node;
- if (count == -2) {- moonfish_clear(node);
- return NULL;
- }
if (count > 0) break;
}
#endif
- for (;;) {-
- next = NULL;
- max_confidence = -1;
-
+ max_confidence = -1;
+
+ while (max_confidence < 0) { for (i = 0 ; i < count ; i++) {if (node->children[i].ignored) continue;
if (node->children[i].count == -1) continue;
@@ -288,8 +249,6 @@
max_confidence = confidence;
}
}
-
- if (next != NULL) break;
}
node = next;
@@ -315,7 +274,6 @@
node->visits++;
#else
atomic_fetch_add(&node->visits, 1);
- atomic_fetch_add(&node->uses, -1);
#endif
node = next;
}
@@ -327,23 +285,18 @@
int bound;
i = 1;
-
while (node != NULL) {-
bound = 0;
-
for (j = 0 ; j < node->count ; j++) { if (1 - node->children[j].bounds[1 - i] > bound) {bound = 1 - node->children[j].bounds[1 - i];
}
}
-
for (j = 0 ; j < node->count ; j++) { if (1 - node->children[j].bounds[1 - i] < bound) {node->children[j].ignored = 1;
}
}
-
node->bounds[i] = bound;
node = node->parent;
i = 1 - i;
@@ -350,22 +303,58 @@
}
}
-static void moonfish_search(struct moonfish_node *node, struct moonfish_chess *chess0)
+static moonfish_result_t moonfish_search(void *data)
{- int i;
+ struct moonfish_root *root;
struct moonfish_node *leaf;
struct moonfish_chess chess;
+ int i;
- for (i = 0 ; i < 256 ; i++) {- chess = *chess0;
- leaf = moonfish_select(node, &chess);
- if (leaf == NULL) continue;
+ root = data;
+
+ for (i = 0 ; i < 1024 ; i++) {+ chess = root->chess;
+ leaf = moonfish_select(&root->node, &chess);
moonfish_expand(leaf, &chess);
if (leaf->count == 0 && moonfish_check(&chess)) moonfish_propagate_bounds(leaf);
moonfish_propagate(leaf);
}
+
+ return moonfish_value;
}
+#ifndef moonfish_no_threads
+
+static void moonfish_start(struct moonfish_root *root, int thread_count)
+{+ thrd_t *threads;
+ int i;
+
+ threads = malloc(thread_count * sizeof *threads);
+ if (threads == NULL) {+ perror("malloc");+ exit(1);
+ }
+
+ for (i = 0 ; i < thread_count ; i++) {+ if (thrd_create(&threads[i], &moonfish_search, root) != thrd_success) {+ fprintf(stderr, "could not create thread\n");
+ exit(1);
+ }
+ }
+
+ for (i = 0 ; i < thread_count ; i++) {+ if (thrd_join(threads[i], NULL) != thrd_success) {+ fprintf(stderr, "could not join thread\n");
+ exit(1);
+ }
+ }
+
+ free(threads);
+}
+
+#endif
+
static void moonfish_clean(struct moonfish_node *node)
{int i;
@@ -377,37 +366,13 @@
}
}
-static moonfish_result_t moonfish_start(void *data)
-{- struct moonfish_thread *thread;
- int i, count;
-
- thread = data;
-
- moonfish_search(&thread->root->node, &thread->root->chess);
- while (moonfish_clock() - thread->time0 < thread->time) {-#ifndef moonfish_mini
- if (thread->root->stop) break;
- if (thread->root->node.visits >= thread->node_count) break;
-#endif
- count = thread->root->node.count;
- for (i = 0 ; i < thread->root->node.count ; i++) {- if (thread->root->node.children[i].ignored) count--;
- }
- if (count <= 1) break;
- moonfish_search(&thread->root->node, &thread->root->chess);
- if (thread->clean) moonfish_clean(&thread->root->node);
- }
-
- return moonfish_value;
-}
-
void moonfish_best_move(struct moonfish_root *root, struct moonfish_result *result, struct moonfish_options *options)
{- struct moonfish_thread thread, *threads;
struct moonfish_node *node;
- long int time;
+ long int time, time0;
+ long int node_count;
int i, j;
+ int count;
time = LONG_MAX;
if (options->our_time >= 0) time = options->our_time / 16;
@@ -415,55 +380,38 @@
time -= time / 32 + 125;
if (time < 0) time = 0;
- thread.clean = 1;
- thread.root = root;
- thread.time = time;
- thread.time0 = moonfish_clock();
- if (options->node_count < 0) thread.node_count = LONG_MAX;
- else thread.node_count = root->node.visits + options->node_count;
+ time0 = moonfish_clock();
+ node_count = options->node_count;
+ if (node_count < 0) node_count = LONG_MAX;
+ for (;;) {#ifdef moonfish_no_threads
-
- moonfish_start(&thread);
-
+ moonfish_search(root);
#else
-
- threads = malloc(options->thread_count * sizeof *threads);
- if (threads == NULL) {- perror("malloc");- exit(1);
- }
-
- for (i = 0 ; i < options->thread_count ; i++) {- threads[i] = thread;
- thread.clean = 0;
- if (thrd_create(&threads[i].thread, &moonfish_start, threads + i) != thrd_success) {- fprintf(stderr, "could not create thread\n");
- exit(1);
+ moonfish_start(root, options->thread_count);
+#endif
+ moonfish_clean(&root->node);
+ if (root->node.count > 0) qsort(root->node.children, root->node.count, sizeof root->node, &moonfish_compare);
+ for (i = 0 ; i < root->node.count ; i++) {+ node = root->node.children + i;
+ for (j = 0 ; j < node->count ; j++) node->children[j].parent = node;
}
- }
-
- for (i = 0 ; i < options->thread_count ; i++) {- if (thrd_join(threads[i].thread, NULL) != thrd_success) {- fprintf(stderr, "could not join thread\n");
- exit(1);
+ moonfish_node_move(root->node.children, &root->chess, &result->move);
+ result->score = root->node.score;
+ result->node_count = root->node.visits;
+ result->time = moonfish_clock() - time0;
+#ifndef moonfish_mini
+ if (root->log != NULL) (*root->log)(result, root->data);
+ if (root->stop) break;
+ if (root->node.visits >= node_count) break;
+#endif
+ if (result->time >= time) break;
+ count = root->node.count;
+ for (i = 0 ; i < root->node.count ; i++) {+ if (root->node.children[i].ignored) count--;
}
+ if (count <= 1) break;
}
-
- free(threads);
-
-#endif
-
- moonfish_clean(&root->node);
-
- if (root->node.count > 0) qsort(root->node.children, root->node.count, sizeof root->node, &moonfish_compare);
- for (i = 0 ; i < root->node.count ; i++) {- node = root->node.children + i;
- for (j = 0 ; j < node->count ; j++) node->children[j].parent = node;
- }
- moonfish_node_move(root->node.children, &root->chess, &result->move);
- result->score = root->node.score;
- result->node_count = root->node.visits;
}
void moonfish_reroot(struct moonfish_root *root, struct moonfish_chess *chess)
@@ -518,6 +466,9 @@
exit(1);
}
+#ifndef moonfish_mini
+ root->log = NULL;
+#endif
root->stop = 0;
moonfish_node(&root->node);
moonfish_chess(&root->chess);
@@ -583,6 +534,12 @@
node = best_node;
}
+}
+
+void moonfish_idle(struct moonfish_root *root, void (*log)(struct moonfish_result *result, void *data), void *data)
+{+ root->log = log;
+ root->data = data;
}
#endif
--
⑨