merge perft split

This commit is contained in:
2024-08-05 08:26:33 +02:00
parent 1ca4eb4443
commit f7fd2cb657
2 changed files with 80 additions and 58 deletions

View File

@@ -20,59 +20,79 @@
#include "move-do.h" #include "move-do.h"
/** /**
* perft() - Perform perft on position * do_perft() - perft engine
* @pos: &position to search * @pos: &position to search
* @depth: Wanted depth. * @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 * Run perft on a position.
* level for each possible first move, and the total of moves.
* *
* This version uses the algorithm: * This version uses the algorithm:
* if last depth
* return 1;
* gen legal moves * gen legal moves
* if last depth
* return number of legal move
* loop for legal move * loop for legal move
* do-move * do-move
* perft (depth -1) * if depth == 2
*
* do_perft (depth -1)
* undo-move * undo-move
* *
* @return: total moves found at @depth level. * @return: total moves found at @depth level.
*/ */
static u64 do_perft(pos_t *pos, int depth) static u64 do_perft(pos_t *pos, int depth)
{ {
u64 subnodes = 0, nodes = 0; u64 nodes = 0;
movelist_t movelist; movelist_t movelist;
move_t *move, *last; move_t *move, *last;
state_t state; state_t state;
pos_set_checkers_pinners_blockers(pos); pos_set_checkers_pinners_blockers(pos);
pos_legal(pos, pos_gen_pseudo(pos, &movelist)); 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) { //if (depth == 1)
move_do(pos, *move, &state); // return movelist.nmoves;
if (depth == 2) {
movelist_t movelist2; last = movelist.move + movelist.nmoves;
pos_set_checkers_pinners_blockers(pos); switch (depth) {
subnodes = pos_legal(pos, pos_gen_pseudo(pos, &movelist2))->nmoves; case 1:
} else if (pos->plyroot >= 3) { /* This case could be removed if 'case 2' is handled in perft()
hentry_t *entry = tt_probe_perft(pos->key, depth); */
if (entry != TT_MISS) { return movelist.nmoves;
subnodes = HASH_PERFT_VAL(entry->data); break;
} else { case 2:
subnodes = do_perft(pos, depth - 1); /* For depth 2, we directly calculate the possible legal moves
tt_store_perft(pos->key, depth, subnodes); * 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 { break;
subnodes = do_perft(pos, depth - 1); default:
} /* Default: Search in TT for same key+depth. Use it if found, create
move_undo(pos, *move, &state); * it otherwise.
nodes += subnodes; */
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; return nodes;
} }

View File

@@ -47,34 +47,36 @@ bool is_draw(pos_t *pos)
* *
* @return: The @pos negamax evaluation. * @return: The @pos negamax evaluation.
*/ */
/* eval_t negamax(pos_t *pos, int depth, int color)
* eval_t negamax(pos_t *pos, int depth, int color) {
* { move_t *move, *last;
* move_t *move; state_t state;
* pos_t *newpos; eval_t best = EVAL_MIN, score;
* eval_t best = EVAL_MIN, score; movelist_t movelist;
*
* pos->node_count++; pos->node_count++;
* if (depth == 0) { if (depth == 0) {
* moves_gen_all_nomoves(pos); score = eval(pos) * color;
* score = eval(pos) * color; return score;
* return score; }
* } pos_set_checkers_pinners_blockers(pos);
* moves_gen_all(pos); pos_gen_legal(pos, &movelist);
* list_for_each_entry(move, &pos->moves[pos->turn], list) { last = movelist.move + movelist.nmoves;
* newpos = move_do(pos, move); //moves_gen_all(pos);
* score = -negamax(newpos, depth - 1, -color); for (move = movelist.move; move < last; ++move) {
* pos->node_count += newpos->node_count; //list_for_each_entry(move, &pos->moves[pos->turn], list) {
* move->negamax = score; move_do(pos, *move, &state);
* if (score > best) { score = -negamax(pos, depth - 1, -color);
* best = score; pos->node_count += pos->node_count;
* pos->bestmove = move; //move->negamax = score;
* } if (score > best) {
* move_undo(newpos, move); best = score;
* } pos->eval = best;
* return best; }
* } move_undo(pos, *move, &state);
*/ }
return best;
}
/** /**