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