perft: fix divide (untested for ages!). perft-test: SF uses divide
This commit is contained in:
57
src/search.c
57
src/search.c
@@ -26,7 +26,7 @@
|
|||||||
* @pos: &position to search
|
* @pos: &position to search
|
||||||
* @depth: Wanted depth.
|
* @depth: Wanted depth.
|
||||||
* @ply: current perft depth level (root = 1)
|
* @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
|
* Run perft on a position. This function displays the available moves at @depth
|
||||||
* level for each possible first move, and the total of moves.
|
* level for each possible first move, and the total of moves.
|
||||||
@@ -42,17 +42,12 @@
|
|||||||
*
|
*
|
||||||
* @return: total moves found at @depth level.
|
* @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;
|
movelist_t movelist;
|
||||||
move_t *move, *last;
|
move_t *move, *last;
|
||||||
state_t state;
|
state_t state;
|
||||||
# ifdef PERFT_MOVE_HISTORY
|
|
||||||
static movelist_t stack;
|
|
||||||
if (ply == 1)
|
|
||||||
stack.nmoves = 0;
|
|
||||||
# endif
|
|
||||||
|
|
||||||
pos_set_checkers_pinners_blockers(pos);
|
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;
|
last = movelist.move + movelist.nmoves;
|
||||||
for (move = movelist.move; move < last; ++move) {
|
for (move = movelist.move; move < last; ++move) {
|
||||||
if (depth == 1) {
|
if (depth == 1) {
|
||||||
nodes++;
|
subnodes = 1;
|
||||||
} else {
|
} else {
|
||||||
move_do(pos, *move, &state);
|
move_do(pos, *move, &state);
|
||||||
# ifdef PERFT_MOVE_HISTORY
|
|
||||||
stack.move[stack.nmoves++] = *move;
|
|
||||||
# endif
|
|
||||||
if (depth == 2) {
|
if (depth == 2) {
|
||||||
movelist_t movelist2;
|
movelist_t movelist2;
|
||||||
pos_set_checkers_pinners_blockers(pos);
|
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) {
|
if (entry != TT_MISS) {
|
||||||
subnodes = HASH_PERFT_VAL(entry->data);
|
subnodes = HASH_PERFT_VAL(entry->data);
|
||||||
} else {
|
} else {
|
||||||
subnodes = perft(pos, depth - 1, ply + 1, output);
|
subnodes = perft(pos, depth - 1, ply + 1, divide);
|
||||||
tt_store_perft(pos->key, depth, subnodes);
|
tt_store_perft(pos->key, depth, subnodes);
|
||||||
}
|
}
|
||||||
} else {
|
} 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);
|
move_undo(pos, *move, &state);
|
||||||
# ifdef PERFT_MOVE_HISTORY
|
}
|
||||||
stack.nmoves--;
|
nodes += subnodes;
|
||||||
# endif
|
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;
|
return nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,16 +90,16 @@ u64 perft(pos_t *pos, int depth, int ply, bool output)
|
|||||||
* @pos: &position to search
|
* @pos: &position to search
|
||||||
* @depth: Wanted depth.
|
* @depth: Wanted depth.
|
||||||
* @ply: current perft depth level (root = 1)
|
* @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
|
* Run perft on a position. This function displays the available moves at @depth
|
||||||
* level for each possible first move, and the total of moves.
|
* level for each possible first move, and the total of moves.
|
||||||
*
|
*
|
||||||
* @return: total moves found at @depth level.
|
* @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;
|
movelist_t movelist;
|
||||||
move_t *move, *last;
|
move_t *move, *last;
|
||||||
state_t state;
|
state_t state;
|
||||||
@@ -123,7 +110,7 @@ u64 perft_alt(pos_t *pos, int depth, int ply, bool output)
|
|||||||
last = movelist.move + movelist.nmoves;
|
last = movelist.move + movelist.nmoves;
|
||||||
for (move = movelist.move; move < last; ++move) {
|
for (move = movelist.move; move < last; ++move) {
|
||||||
if (depth == 1) {
|
if (depth == 1) {
|
||||||
nodes++;
|
subnodes = 1;
|
||||||
} else {
|
} else {
|
||||||
move_do_alt(pos, *move, &state);
|
move_do_alt(pos, *move, &state);
|
||||||
if (depth == 2) {
|
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);
|
pos_set_checkers_pinners_blockers(pos);
|
||||||
subnodes = pos_legal(pos, pos_gen_pseudo(pos, &movelist2))->nmoves;
|
subnodes = pos_legal(pos, pos_gen_pseudo(pos, &movelist2))->nmoves;
|
||||||
} else {
|
} 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);
|
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;
|
return nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -116,9 +116,9 @@ static void stockfish_fen(FILE *desc, char *fen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static u64 stockfish_perft(FILE *desc, pos_t *pos, movelist_t *movelist,
|
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;
|
u64 count, mycount = 0, fishcount;
|
||||||
size_t alloc = 0;
|
size_t alloc = 0;
|
||||||
ssize_t buflen;
|
ssize_t buflen;
|
||||||
@@ -144,27 +144,37 @@ static u64 stockfish_perft(FILE *desc, pos_t *pos, movelist_t *movelist,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
//printf("%d: %s\n", line++, buf);
|
//printf("%d: %s\n", line++, buf);
|
||||||
if (sscanf(buf, "%*4s: %lu", &count) == 1) {
|
if (sscanf(buf, "%6[a-z1-8]: %lu", movestr, &count) == 2) {
|
||||||
square_t from = sq_from_string(buf);
|
//printf("read:%s movestr:%s count:%lu\n", buf, movestr, count);
|
||||||
square_t to = sq_from_string(buf + 2);
|
moves[(*nmoves)++] = move_from_str(movestr);
|
||||||
mycount += count;
|
mycount += count;
|
||||||
//printf("move found: %c%c->%c%c %s->%s count=%d\n",
|
if (divide) {
|
||||||
// buf[0], buf[1], buf[2], buf[3],
|
printf("%s: %lu\n", movestr, count);
|
||||||
// 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 (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;
|
//pos->moves.nmoves = nmoves;
|
||||||
// printf("fishcount=%d mycount=%d\n", fishcount, mycount);
|
// 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, "Usage: %s [-cms][-d depth] [-p version] [-t size:\n", prg);
|
||||||
fprintf(stderr, "\t-c: do *not* print FEN comments\n");
|
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-m: print moves details\n");
|
||||||
fprintf(stderr, "\t-s: use Stockfish to validate perft result\n");
|
fprintf(stderr, "\t-s: use Stockfish to validate perft result\n");
|
||||||
fprintf(stderr, "\t-t size: Transposition Table size (Mb). Default: 32\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;
|
int curtest = 0;
|
||||||
u64 sf_count = 0, my_count;
|
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;
|
char *fen;
|
||||||
pos_t *pos = NULL, *fenpos;
|
pos_t *pos = NULL, *fenpos;
|
||||||
pos_t *fishpos = pos_new();
|
pos_t *fishpos = pos_new();
|
||||||
@@ -300,7 +310,7 @@ int main(int ac, char**av)
|
|||||||
depth = 6;
|
depth = 6;
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
moves_output = false;
|
divide = true;
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
run = atoi(optarg);
|
run = atoi(optarg);
|
||||||
@@ -359,7 +369,7 @@ int main(int ac, char**av)
|
|||||||
if (sf_run) {
|
if (sf_run) {
|
||||||
stockfish_fen(outfd, fen);
|
stockfish_fen(outfd, fen);
|
||||||
clock_start(&clock);
|
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);
|
ms = clock_elapsed_ms(&clock);
|
||||||
if (!ms) {
|
if (!ms) {
|
||||||
res[2].skipped++;
|
res[2].skipped++;
|
||||||
@@ -380,7 +390,7 @@ int main(int ac, char**av)
|
|||||||
|
|
||||||
if (run & 1) {
|
if (run & 1) {
|
||||||
clock_start(&clock);
|
clock_start(&clock);
|
||||||
my_count = perft(pos, depth, 1, moves_output);
|
my_count = perft(pos, depth, 1, divide);
|
||||||
ms = clock_elapsed_ms(&clock);
|
ms = clock_elapsed_ms(&clock);
|
||||||
if (!ms) {
|
if (!ms) {
|
||||||
res[0].skipped++;
|
res[0].skipped++;
|
||||||
@@ -408,7 +418,7 @@ int main(int ac, char**av)
|
|||||||
|
|
||||||
if (run & 2) {
|
if (run & 2) {
|
||||||
clock_start(&clock);
|
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);
|
ms = clock_elapsed_ms(&clock);
|
||||||
if (!ms) {
|
if (!ms) {
|
||||||
res[1].skipped++;
|
res[1].skipped++;
|
||||||
|
Reference in New Issue
Block a user