merge perft split
This commit is contained in:
80
src/perft.c
80
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;
|
||||
}
|
||||
|
58
src/search.c
58
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;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user