From f7fd2cb6575ab7eca549c86e4745e798a1c221f9 Mon Sep 17 00:00:00 2001 From: Bruno Raoult Date: Mon, 5 Aug 2024 08:26:33 +0200 Subject: [PATCH] merge perft split --- src/perft.c | 80 ++++++++++++++++++++++++++++++++-------------------- src/search.c | 58 +++++++++++++++++++------------------ 2 files changed, 80 insertions(+), 58 deletions(-) diff --git a/src/perft.c b/src/perft.c index 970f1b3..99fdb87 100644 --- a/src/perft.c +++ b/src/perft.c @@ -20,59 +20,79 @@ #include "move-do.h" /** - * perft() - Perform perft on position + * do_perft() - perft engine * @pos: &position to search * @depth: Wanted depth. - * @ply: current perft depth level (root = 1) - * @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. + * Run perft on a position. * * This version uses the algorithm: - * if last depth - * return 1; * gen legal moves + * if last depth + * return number of legal move * loop for legal move * do-move - * perft (depth -1) + * if depth == 2 + * + * do_perft (depth -1) * undo-move * * @return: total moves found at @depth level. */ static u64 do_perft(pos_t *pos, int depth) { - u64 subnodes = 0, nodes = 0; + u64 nodes = 0; movelist_t movelist; move_t *move, *last; state_t state; pos_set_checkers_pinners_blockers(pos); pos_legal(pos, pos_gen_pseudo(pos, &movelist)); - if (depth == 1) - return movelist.nmoves; - last = movelist.move + movelist.nmoves; - for (move = movelist.move; move < last; ++move) { - move_do(pos, *move, &state); - if (depth == 2) { - movelist_t movelist2; - pos_set_checkers_pinners_blockers(pos); - subnodes = pos_legal(pos, pos_gen_pseudo(pos, &movelist2))->nmoves; - } else if (pos->plyroot >= 3) { - hentry_t *entry = tt_probe_perft(pos->key, depth); - if (entry != TT_MISS) { - subnodes = HASH_PERFT_VAL(entry->data); - } else { - subnodes = do_perft(pos, depth - 1); - tt_store_perft(pos->key, depth, subnodes); + //if (depth == 1) + // return movelist.nmoves; + + last = movelist.move + movelist.nmoves; + switch (depth) { + case 1: + /* This case could be removed if 'case 2' is handled in perft() + */ + return movelist.nmoves; + break; + case 2: + /* For depth 2, we directly calculate the possible legal moves + * after each possible moves. + */ + for (move = movelist.move; move < last; ++move) { + move_do(pos, *move, &state); + movelist_t movelist2; + pos_set_checkers_pinners_blockers(pos); + nodes += pos_legal(pos, pos_gen_pseudo(pos, &movelist2))->nmoves; + move_undo(pos, *move, &state); } - } else { - subnodes = do_perft(pos, depth - 1); - } - move_undo(pos, *move, &state); - nodes += subnodes; + break; + default: + /* Default: Search in TT for same key+depth. Use it if found, create + * it otherwise. + */ + for (move = movelist.move; move < last; ++move) { + move_do(pos, *move, &state); + hentry_t *entry = tt_probe_perft(pos->key, depth); + if (entry != TT_MISS) { + nodes += HASH_PERFT_VAL(entry->data); + } else { + u64 subnodes = do_perft(pos, depth - 1); + tt_store_perft(pos->key, depth, subnodes); + nodes += subnodes; + } + move_undo(pos, *move, &state); + } + //} else { + //subnodes = do_perft(pos, depth - 1); } + //move_undo(pos, *move, &state); + //nodes += subnodes; + //} return nodes; } diff --git a/src/search.c b/src/search.c index 4e558d7..c0633e3 100644 --- a/src/search.c +++ b/src/search.c @@ -47,34 +47,36 @@ bool is_draw(pos_t *pos) * * @return: The @pos negamax evaluation. */ -/* - * eval_t negamax(pos_t *pos, int depth, int color) - * { - * move_t *move; - * pos_t *newpos; - * eval_t best = EVAL_MIN, score; - * - * pos->node_count++; - * if (depth == 0) { - * moves_gen_all_nomoves(pos); - * score = eval(pos) * color; - * return score; - * } - * moves_gen_all(pos); - * list_for_each_entry(move, &pos->moves[pos->turn], list) { - * newpos = move_do(pos, move); - * score = -negamax(newpos, depth - 1, -color); - * pos->node_count += newpos->node_count; - * move->negamax = score; - * if (score > best) { - * best = score; - * pos->bestmove = move; - * } - * move_undo(newpos, move); - * } - * return best; - * } - */ +eval_t negamax(pos_t *pos, int depth, int color) +{ + move_t *move, *last; + state_t state; + eval_t best = EVAL_MIN, score; + movelist_t movelist; + + pos->node_count++; + if (depth == 0) { + score = eval(pos) * color; + return score; + } + pos_set_checkers_pinners_blockers(pos); + pos_gen_legal(pos, &movelist); + last = movelist.move + movelist.nmoves; + //moves_gen_all(pos); + for (move = movelist.move; move < last; ++move) { + //list_for_each_entry(move, &pos->moves[pos->turn], list) { + move_do(pos, *move, &state); + score = -negamax(pos, depth - 1, -color); + pos->node_count += pos->node_count; + //move->negamax = score; + if (score > best) { + best = score; + pos->eval = best; + } + move_undo(pos, *move, &state); + } + return best; +} /**