From 73d09ec37f7a70865afbe09cb556e30c8ad27920 Mon Sep 17 00:00:00 2001 From: Bruno Raoult Date: Wed, 3 Jul 2024 21:10:41 +0200 Subject: [PATCH] perft: fix divide (untested for ages!). perft-test: SF uses divide --- src/search.c | 57 ++++++++++++++++------------------------- test/perft-test.c | 64 +++++++++++++++++++++++++++-------------------- 2 files changed, 58 insertions(+), 63 deletions(-) diff --git a/src/search.c b/src/search.c index 65cf9a7..59c1a63 100644 --- a/src/search.c +++ b/src/search.c @@ -26,7 +26,7 @@ * @pos: &position to search * @depth: Wanted depth. * @ply: current perft depth level (root = 1) - * @output: output total for 1st level moves. + * @divide: output total for 1st level moves. * * Run perft on a position. This function displays the available moves at @depth * level for each possible first move, and the total of moves. @@ -42,17 +42,12 @@ * * @return: total moves found at @depth level. */ -u64 perft(pos_t *pos, int depth, int ply, bool output) +u64 perft(pos_t *pos, int depth, int ply, bool divide) { - u64 subnodes, nodes = 0; + u64 subnodes = 0, nodes = 0; movelist_t movelist; move_t *move, *last; state_t state; -# ifdef PERFT_MOVE_HISTORY - static movelist_t stack; - if (ply == 1) - stack.nmoves = 0; -# endif pos_set_checkers_pinners_blockers(pos); @@ -60,12 +55,9 @@ u64 perft(pos_t *pos, int depth, int ply, bool output) last = movelist.move + movelist.nmoves; for (move = movelist.move; move < last; ++move) { if (depth == 1) { - nodes++; + subnodes = 1; } else { move_do(pos, *move, &state); -# ifdef PERFT_MOVE_HISTORY - stack.move[stack.nmoves++] = *move; -# endif if (depth == 2) { movelist_t movelist2; pos_set_checkers_pinners_blockers(pos); @@ -75,26 +67,21 @@ u64 perft(pos_t *pos, int depth, int ply, bool output) if (entry != TT_MISS) { subnodes = HASH_PERFT_VAL(entry->data); } else { - subnodes = perft(pos, depth - 1, ply + 1, output); + subnodes = perft(pos, depth - 1, ply + 1, divide); tt_store_perft(pos->key, depth, subnodes); } } else { - subnodes = perft(pos, depth - 1, ply + 1, output); + subnodes = perft(pos, depth - 1, ply + 1, divide); } - if (output && ply == 1) { - char movestr[8]; - printf("%s: %lu\n", move_to_str(movestr, *move, 0), subnodes); - } - nodes += subnodes; move_undo(pos, *move, &state); -# ifdef PERFT_MOVE_HISTORY - stack.nmoves--; -# endif + } + nodes += subnodes; + if (ply == 1 && divide) { + char movestr[8]; + printf("%s: %lu\n", move_to_str(movestr, *move, 0), subnodes); } } - if (output && ply == 1) - printf("Total: %lu\n", nodes); return nodes; } @@ -103,16 +90,16 @@ u64 perft(pos_t *pos, int depth, int ply, bool output) * @pos: &position to search * @depth: Wanted depth. * @ply: current perft depth level (root = 1) - * @output: output total for 1st level moves. + * @divide: output total for 1st level moves. * * Run perft on a position. This function displays the available moves at @depth * level for each possible first move, and the total of moves. * * @return: total moves found at @depth level. */ -u64 perft_alt(pos_t *pos, int depth, int ply, bool output) +u64 perft_alt(pos_t *pos, int depth, int ply, bool divide) { - u64 subnodes, nodes = 0; + u64 subnodes = 0, nodes = 0; movelist_t movelist; move_t *move, *last; state_t state; @@ -123,7 +110,7 @@ u64 perft_alt(pos_t *pos, int depth, int ply, bool output) last = movelist.move + movelist.nmoves; for (move = movelist.move; move < last; ++move) { if (depth == 1) { - nodes++; + subnodes = 1; } else { move_do_alt(pos, *move, &state); if (depth == 2) { @@ -131,19 +118,17 @@ u64 perft_alt(pos_t *pos, int depth, int ply, bool output) pos_set_checkers_pinners_blockers(pos); subnodes = pos_legal(pos, pos_gen_pseudo(pos, &movelist2))->nmoves; } else { - subnodes = perft_alt(pos, depth - 1, ply + 1, output); + subnodes = perft_alt(pos, depth - 1, ply + 1, divide); } - if (output && ply == 1) { - char movestr[8]; - printf("%s: %lu\n", move_to_str(movestr, *move, 0), subnodes); - } - nodes += subnodes; move_undo_alt(pos, *move, &state); } + nodes += subnodes; + if (ply == 1 && divide) { + char movestr[8]; + printf("%s: %lu\n", move_to_str(movestr, *move, 0), subnodes); + } } - if (output && ply == 1) - printf("Total: %lu\n", nodes); return nodes; } diff --git a/test/perft-test.c b/test/perft-test.c index 2666922..f473886 100644 --- a/test/perft-test.c +++ b/test/perft-test.c @@ -116,9 +116,9 @@ static void stockfish_fen(FILE *desc, char *fen) } static u64 stockfish_perft(FILE *desc, pos_t *pos, movelist_t *movelist, - int depth) + int depth, int divide) { - char *buf = NULL; + char *buf = NULL, movestr[8]; u64 count, mycount = 0, fishcount; size_t alloc = 0; ssize_t buflen; @@ -144,27 +144,37 @@ static u64 stockfish_perft(FILE *desc, pos_t *pos, movelist_t *movelist, break; } //printf("%d: %s\n", line++, buf); - if (sscanf(buf, "%*4s: %lu", &count) == 1) { - square_t from = sq_from_string(buf); - square_t to = sq_from_string(buf + 2); + if (sscanf(buf, "%6[a-z1-8]: %lu", movestr, &count) == 2) { + //printf("read:%s movestr:%s count:%lu\n", buf, movestr, count); + moves[(*nmoves)++] = move_from_str(movestr); mycount += count; - //printf("move found: %c%c->%c%c %s->%s count=%d\n", - // buf[0], buf[1], buf[2], buf[3], - // sq_to_string(from), sq_to_string(to), - // count); - moves[(*nmoves)++] = move_make(from, to); - - } else if (sscanf(buf, "%*5s: %lu", &count) == 1) { - square_t from = sq_from_string(buf); - square_t to = sq_from_string(buf + 2); - piece_type_t promoted = piece_t_from_char(*(buf + 4)); - mycount += count; - //printf("move found: %c%c->%c%c %s->%s count=%d\n", - // buf[0], buf[1], buf[2], buf[3], - // sq_to_string(from), sq_to_string(to), - // count); - moves[(*nmoves)++] = move_make_promote(from, to, promoted); + if (divide) { + printf("%s: %lu\n", movestr, count); + } } + /* + * if (sscanf(buf, "%*4s: %lu", &count) == 1) { + * square_t from = sq_from_string(buf); + * square_t to = sq_from_string(buf + 2); + * mycount += count; + * //printf("move found: %c%c->%c%c %s->%s count=%d\n", + * // buf[0], buf[1], buf[2], buf[3], + * // sq_to_string(from), sq_to_string(to), + * // count); + * moves[(*nmoves)++] = move_make(from, to); + * + * } else if (sscanf(buf, "%*5s: %lu", &count) == 1) { + * square_t from = sq_from_string(buf); + * square_t to = sq_from_string(buf + 2); + * piece_type_t promoted = piece_t_from_char(*(buf + 4)); + * mycount += count; + * //printf("move found: %c%c->%c%c %s->%s count=%d\n", + * // buf[0], buf[1], buf[2], buf[3], + * // sq_to_string(from), sq_to_string(to), + * // count); + * moves[(*nmoves)++] = move_make_promote(from, to, promoted); + * } + */ } //pos->moves.nmoves = nmoves; // printf("fishcount=%d mycount=%d\n", fishcount, mycount); @@ -257,7 +267,7 @@ static int usage(char *prg) { fprintf(stderr, "Usage: %s [-cms][-d depth] [-p version] [-t size:\n", prg); fprintf(stderr, "\t-c: do *not* print FEN comments\n"); - fprintf(stderr, "\t-d depth: perft depth (default: 6)"); + fprintf(stderr, "\t-d depth: perft depth (default: 6)\n"); fprintf(stderr, "\t-m: print moves details\n"); fprintf(stderr, "\t-s: use Stockfish to validate perft result\n"); fprintf(stderr, "\t-t size: Transposition Table size (Mb). Default: 32\n"); @@ -270,7 +280,7 @@ int main(int ac, char**av) { int curtest = 0; u64 sf_count = 0, my_count; - bool comment = true, sf_run = false, moves_output = false; + bool comment = true, sf_run = false, divide = false; char *fen; pos_t *pos = NULL, *fenpos; pos_t *fishpos = pos_new(); @@ -300,7 +310,7 @@ int main(int ac, char**av) depth = 6; break; case 'm': - moves_output = false; + divide = true; break; case 'p': run = atoi(optarg); @@ -359,7 +369,7 @@ int main(int ac, char**av) if (sf_run) { stockfish_fen(outfd, fen); clock_start(&clock); - sf_count = stockfish_perft(outfd, fishpos, &fishmoves, depth); + sf_count = stockfish_perft(outfd, fishpos, &fishmoves, depth, divide); ms = clock_elapsed_ms(&clock); if (!ms) { res[2].skipped++; @@ -380,7 +390,7 @@ int main(int ac, char**av) if (run & 1) { clock_start(&clock); - my_count = perft(pos, depth, 1, moves_output); + my_count = perft(pos, depth, 1, divide); ms = clock_elapsed_ms(&clock); if (!ms) { res[0].skipped++; @@ -408,7 +418,7 @@ int main(int ac, char**av) if (run & 2) { clock_start(&clock); - my_count = perft_alt(pos, depth, 1, moves_output); + my_count = perft_alt(pos, depth, 1, divide); ms = clock_elapsed_ms(&clock); if (!ms) { res[1].skipped++;