perft-test.c/common-test.h: add sentinel for temp tests / TT stats
This commit is contained in:
@@ -28,29 +28,25 @@ struct fentest {
|
|||||||
char *comment;
|
char *comment;
|
||||||
char *fen;
|
char *fen;
|
||||||
} fentest[] = {
|
} fentest[] = {
|
||||||
/******************* TEMP TESTS BELOW *******************/
|
/************************************************************
|
||||||
|
* TEMP TESTS BELOW - only run them (till sentinel below) *
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* { __LINE__, MOVEGEN | MOVEDO | PERFT,
|
* { __LINE__, FEN | MOVEGEN | MOVEDO | PERFT,
|
||||||
* "bug perft TT après 1.b4 f5",
|
* "startpos + 1.e4 e5 2.Nf3 Nc6 3.Bb5 a6 4.Ba4",
|
||||||
* "1nbqkbn1/ppp1p1pp/8/r1rpPpK1/1P6/8/P1PP1PPP/RNBQ1BNR w - f6 0 2"
|
* "r1bqkbnr/1ppp1ppp/p1n5/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R b KQkq - 1 4"
|
||||||
|
* },
|
||||||
|
* { __LINE__, FEN | MOVEGEN | MOVEDO | PERFT,
|
||||||
|
* "",
|
||||||
|
* "r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - 0 1"
|
||||||
* },
|
* },
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/******************************************************************
|
||||||
* { __LINE__, MOVEGEN | MOVEDO | PERFT,
|
* DO NOT DELETE NEXT LINE - sentinel entry for temp tests above. *
|
||||||
* "bug perft TT après 1.b4",
|
* ignored if first array entry. *
|
||||||
* "1nbqkbn1/ppp1pppp/8/r1rpP1K1/1P6/8/P1PP1PPP/RNBQ1BNR b - - 0 1",
|
******************************************************************/
|
||||||
* },
|
|
||||||
*/
|
|
||||||
|
|
||||||
{ __LINE__, MOVEGEN | MOVEDO | PERFT,
|
|
||||||
"bug perft TT",
|
|
||||||
"1nbqkbn1/ppp1pppp/8/r1rpP1K1/8/8/PPPP1PPP/RNBQ1BNR w - d6 0 1",
|
|
||||||
},
|
|
||||||
|
|
||||||
/* ***************** END of TEMP TESTS ******************/
|
|
||||||
/* below line ignored if first test */
|
|
||||||
{ __LINE__, 0, NULL, NULL },
|
{ __LINE__, 0, NULL, NULL },
|
||||||
|
|
||||||
{ __LINE__, MOVEGEN | MOVEDO | PERFT,
|
{ __LINE__, MOVEGEN | MOVEDO | PERFT,
|
||||||
@@ -154,40 +150,45 @@ struct fentest {
|
|||||||
"checker: h4",
|
"checker: h4",
|
||||||
"4k3/8/8/8/7b/8/8/4K3 w - - 0 1"
|
"4k3/8/8/8/7b/8/8/4K3 w - - 0 1"
|
||||||
},
|
},
|
||||||
|
/*
|
||||||
|
* { __LINE__, FEN | MOVEGEN | MOVEDO | PERFT,
|
||||||
|
* "1.e3 - perft bug",
|
||||||
|
* "rnbqkbnr/pppppppp/8/8/8/4P3/PPPP1PPP/RNBQKBNR b KQkq - 0 1"
|
||||||
|
* },
|
||||||
|
* { __LINE__, FEN | MOVEGEN | MOVEDO | PERFT | PERFT,
|
||||||
|
* "1.e3 Nc6 - perft bug",
|
||||||
|
* "r1bqkbnr/pppppppp/2n5/8/8/4P3/PPPP1PPP/RNBQKBNR w KQkq - 1 2"
|
||||||
|
* },
|
||||||
|
* { __LINE__, FEN | MOVEGEN | MOVEDO | PERFT | PERFT,
|
||||||
|
* "1.e3 Nc6 2.Ke2 - perft bug",
|
||||||
|
* "r1bqkbnr/pppppppp/2n5/8/8/4P3/PPPPKPPP/RNBQ1BNR b kq - 2 2"
|
||||||
|
* },
|
||||||
|
* { __LINE__, FEN | MOVEGEN | MOVEDO | PERFT,
|
||||||
|
* "1.e3 Nc6 2.Ke2 Nd4+ - perft bug",
|
||||||
|
* "r1bqkbnr/pppppppp/8/8/3n4/4P3/PPPPKPPP/RNBQ1BNR w kq - 3 3"
|
||||||
|
* },
|
||||||
|
*/
|
||||||
// First game moves
|
// First game moves
|
||||||
{ __LINE__, FEN | MOVEGEN | MOVEDO | PERFT,
|
{ __LINE__, FEN | MOVEGEN | MOVEDO | PERFT,
|
||||||
"startpos",
|
"startpos",
|
||||||
"rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"
|
"rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"
|
||||||
},
|
},
|
||||||
//{ __LINE__, FEN | MOVEGEN | MOVEDO | PERFT,
|
|
||||||
// "1.e3 - perft bug",
|
|
||||||
// "rnbqkbnr/pppppppp/8/8/8/4P3/PPPP1PPP/RNBQKBNR b KQkq - 0 1"
|
|
||||||
//},
|
|
||||||
//{ __LINE__, FEN | MOVEGEN | MOVEDO | PERFT | PERFT,
|
|
||||||
// "1.e3 Nc6 - perft bug",
|
|
||||||
// "r1bqkbnr/pppppppp/2n5/8/8/4P3/PPPP1PPP/RNBQKBNR w KQkq - 1 2"
|
|
||||||
//},
|
|
||||||
//{ __LINE__, FEN | MOVEGEN | MOVEDO | PERFT | PERFT,
|
|
||||||
// "1.e3 Nc6 2.Ke2 - perft bug",
|
|
||||||
// "r1bqkbnr/pppppppp/2n5/8/8/4P3/PPPPKPPP/RNBQ1BNR b kq - 2 2"
|
|
||||||
//},
|
|
||||||
{ __LINE__, FEN | MOVEGEN | MOVEDO | PERFT,
|
{ __LINE__, FEN | MOVEGEN | MOVEDO | PERFT,
|
||||||
"1.e3 Nc6 2.Ke2 Nd4+ - perft bug",
|
"startpos + 1.e4",
|
||||||
"r1bqkbnr/pppppppp/8/8/3n4/4P3/PPPPKPPP/RNBQ1BNR w kq - 3 3"
|
|
||||||
},
|
|
||||||
{ __LINE__, FEN | MOVEGEN | MOVEDO | PERFT,
|
|
||||||
"1.e4",
|
|
||||||
"rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq - 0 1"
|
"rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq - 0 1"
|
||||||
},
|
},
|
||||||
{ __LINE__, FEN | MOVEGEN | MOVEDO | PERFT,
|
{ __LINE__, FEN | MOVEGEN | MOVEDO | PERFT,
|
||||||
"1.Nh3",
|
"startpos + 1.e4 e5 2.Nf3",
|
||||||
"rnbqkbnr/pppppppp/8/8/8/7N/PPPPPPPP/RNBQKB1R b KQkq - 1 1"
|
"rnbqkbnr/pppp1ppp/8/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq - 1 2"
|
||||||
},
|
},
|
||||||
{ __LINE__, FEN | MOVEGEN | MOVEDO | PERFT,
|
{ __LINE__, FEN | MOVEGEN | MOVEDO | PERFT,
|
||||||
"1.e4 e5 2.Nf3 Nc6",
|
"startpos + 1.e4 e5 2.Nf3 Nc6",
|
||||||
"r1bqkbnr/pp1ppppp/2n5/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - 0 1"
|
"r1bqkbnr/pppp1ppp/2n5/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - 2 3"
|
||||||
|
},
|
||||||
|
{ __LINE__, FEN | MOVEGEN | MOVEDO | PERFT,
|
||||||
|
"startpos + 1.e4 e5 2.Nf3 Nc6 3.Bb5 a6 4.Ba4",
|
||||||
|
"r1bqkbnr/1ppp1ppp/p1n5/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R b KQkq - 1 4"
|
||||||
},
|
},
|
||||||
|
|
||||||
// castling test
|
// castling test
|
||||||
// both can castle queen only
|
// both can castle queen only
|
||||||
{ __LINE__, FEN | MOVEGEN | MOVEDO | PERFT,
|
{ __LINE__, FEN | MOVEGEN | MOVEDO | PERFT,
|
||||||
|
@@ -255,21 +255,29 @@ static __unused void compare_moves(movelist_t *fish, movelist_t *me)
|
|||||||
|
|
||||||
static int usage(char *prg)
|
static int usage(char *prg)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Usage: %s [-cmv][-d depth] [-p perft-version] \n", prg);
|
fprintf(stderr, "Usage: %s [-cms][-d depth] [-p version] [-t size:\n", prg);
|
||||||
fprintf(stderr, "\t-c/m: print comments/moves, -n: no SF check, -d: depth, -p: 1-3, \n");
|
fprintf(stderr, "\t-c: do *not* print FEN comments\n");
|
||||||
|
fprintf(stderr, "\t-d depth: perft depth (default: 6)");
|
||||||
|
fprintf(stderr, "\t-m: print moves details\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-p flavor: perft flavor, 1:perft, 2:perft_alt 3:both, default:1\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int ac, char**av)
|
int main(int ac, char**av)
|
||||||
{
|
{
|
||||||
int test_line;
|
int curtest = 0;
|
||||||
u64 sf_count = 0, my_count;
|
u64 sf_count = 0, my_count;
|
||||||
bool comment = false;
|
bool comment = true, sf_run = false, moves_output = 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();
|
||||||
movelist_t fishmoves;
|
movelist_t fishmoves;
|
||||||
FILE *outfd = NULL;
|
FILE *outfd = NULL;
|
||||||
|
s64 ms, lps;
|
||||||
|
int opt, depth = 6, run = 3, tt = 32, newtt = 32;
|
||||||
struct {
|
struct {
|
||||||
s64 count, ms;
|
s64 count, ms;
|
||||||
s64 minlps, maxlps;
|
s64 minlps, maxlps;
|
||||||
@@ -279,54 +287,73 @@ int main(int ac, char**av)
|
|||||||
{ .minlps=LONG_MAX },
|
{ .minlps=LONG_MAX },
|
||||||
{ .minlps=LONG_MAX },
|
{ .minlps=LONG_MAX },
|
||||||
};
|
};
|
||||||
s64 ms, lps;
|
|
||||||
|
|
||||||
int opt, depth = 6, run = 3;
|
while ((opt = getopt(ac, av, "cd:mp:st:")) != -1) {
|
||||||
bool sf_run = true, perft_output = false;
|
|
||||||
|
|
||||||
while ((opt = getopt(ac, av, "cmnd:p:")) != -1) {
|
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'c':
|
case 'c':
|
||||||
comment = true;
|
comment = false;
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
depth = atoi(optarg);
|
depth = atoi(optarg);
|
||||||
break;
|
if (depth <= 0)
|
||||||
case 'p': /* 1 or 2 or 3 for both */
|
depth = 6;
|
||||||
run = atoi(optarg);
|
|
||||||
break;
|
|
||||||
case 'n':
|
|
||||||
sf_run = false;
|
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
perft_output = true;
|
moves_output = false;
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
run = atoi(optarg);
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
sf_run = true;
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
newtt = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return usage(*av);
|
return usage(*av);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("perft: depth = %d run = %x stockfish = %s\n",
|
if (!run) {
|
||||||
depth, run, sf_run? "true": "false");
|
printf("Nothing to do, exiting\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
init_all();
|
init_all();
|
||||||
|
if (newtt != 32 && newtt > 1) {
|
||||||
|
printf("changing TT size from %d to %d\n", tt, newtt);
|
||||||
|
tt_create(newtt);
|
||||||
|
tt = newtt;
|
||||||
|
}
|
||||||
|
printf("%s: depth:%d tt_size:%d run:%x SF:%s\n",
|
||||||
|
*av,
|
||||||
|
depth, newtt, run,
|
||||||
|
sf_run? "yes": "no");
|
||||||
|
|
||||||
if (!run)
|
tt_info();
|
||||||
exit(0);
|
printf("\n");
|
||||||
|
|
||||||
|
printf("move_t size:%lu\n", sizeof(move_t));
|
||||||
|
|
||||||
if (sf_run)
|
if (sf_run)
|
||||||
outfd = open_stockfish();
|
outfd = open_stockfish();
|
||||||
|
|
||||||
CLOCK_DEFINE(clock, CLOCK_MONOTONIC);
|
CLOCK_DEFINE(clock, CLOCK_MONOTONIC);
|
||||||
while ((fen = next_fen(PERFT | MOVEDO))) {
|
while ((fen = next_fen(PERFT | MOVEDO))) {
|
||||||
if (comment)
|
|
||||||
printf("%s\n", *cur_comment()? cur_comment(): "<FIXME>");
|
|
||||||
test_line = cur_line();
|
|
||||||
tt_clear();
|
|
||||||
if (!(fenpos = fen2pos(pos, fen))) {
|
if (!(fenpos = fen2pos(pos, fen))) {
|
||||||
printf("wrong fen line = %d: [%s]\n", test_line, fen);
|
printf("wrong fen line:%d fen:%s\n\n", cur_line(), fen);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
curtest++;
|
||||||
|
printf("test:%d line:%d", curtest, cur_line());
|
||||||
|
if (comment)
|
||||||
|
printf(" comment:%s\n",
|
||||||
|
*cur_comment()? cur_comment(): "no test desc");
|
||||||
|
printf("\t%s\n", fen);
|
||||||
|
|
||||||
|
tt_clear();
|
||||||
|
|
||||||
pos = fenpos;
|
pos = fenpos;
|
||||||
if (sf_run) {
|
if (sf_run) {
|
||||||
stockfish_fen(outfd, fen);
|
stockfish_fen(outfd, fen);
|
||||||
@@ -345,15 +372,13 @@ int main(int ac, char**av)
|
|||||||
if (lps < res[2].minlps)
|
if (lps < res[2].minlps)
|
||||||
res[2].minlps = lps;
|
res[2].minlps = lps;
|
||||||
}
|
}
|
||||||
printf("SF : line=%3d perft=%'lu %'ldms lps=%'lu \"%s\"\n",
|
printf("Stockfish : perft:%'lu ms:%'ld lps:%'lu\n",
|
||||||
test_line, sf_count, ms,
|
sf_count, ms, lps);
|
||||||
lps,
|
|
||||||
fen);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (run & 1) {
|
if (run & 1) {
|
||||||
clock_start(&clock);
|
clock_start(&clock);
|
||||||
my_count = perft(pos, depth, 1, perft_output);
|
my_count = perft(pos, depth, 1, moves_output);
|
||||||
ms = clock_elapsed_ms(&clock);
|
ms = clock_elapsed_ms(&clock);
|
||||||
if (!ms) {
|
if (!ms) {
|
||||||
res[0].skipped++;
|
res[0].skipped++;
|
||||||
@@ -369,20 +394,17 @@ int main(int ac, char**av)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!sf_run || sf_count == my_count) {
|
if (!sf_run || sf_count == my_count) {
|
||||||
printf("pt1 OK : line=%3d perft=%'lu %'ldms lps=%'lu \"%s\"\n",
|
printf("perft : perft:%'lu ms:%'ld lps:%'lu ",
|
||||||
test_line, my_count, ms,
|
my_count, ms, lps);
|
||||||
lps,
|
tt_stats();
|
||||||
fen);
|
|
||||||
} else {
|
} else {
|
||||||
printf("pt1 ERR: line=%3d sf=%'lu me=%'lu \"%s\"\n",
|
printf("perft : perft:%'lu ***ERROR***\n", my_count);
|
||||||
test_line, sf_count, my_count, fen);
|
|
||||||
}
|
}
|
||||||
tt_stats();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (run & 2) {
|
if (run & 2) {
|
||||||
clock_start(&clock);
|
clock_start(&clock);
|
||||||
my_count = perft_alt(pos, depth, 1, perft_output);
|
my_count = perft_alt(pos, depth, 1, moves_output);
|
||||||
ms = clock_elapsed_ms(&clock);
|
ms = clock_elapsed_ms(&clock);
|
||||||
if (!ms) {
|
if (!ms) {
|
||||||
res[1].skipped++;
|
res[1].skipped++;
|
||||||
@@ -398,13 +420,10 @@ int main(int ac, char**av)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!sf_run || sf_count == my_count) {
|
if (!sf_run || sf_count == my_count) {
|
||||||
printf("pt2 OK : line=%3d perft=%'lu %'ldms lps=%'lu \"%s\"\n",
|
printf("perft_alt : perft:%'lu ms:%'ld lps:%'lu\n",
|
||||||
test_line, my_count, ms,
|
my_count, ms, lps);
|
||||||
lps,
|
|
||||||
fen);
|
|
||||||
} else {
|
} else {
|
||||||
printf("pt2 ERR: line=%3d sf=%'lu me=%'lu \"%s\"\n",
|
printf("perft_alt : perft:%'lu ***ERROR***\n", my_count);
|
||||||
test_line, sf_count, my_count, fen);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
@@ -413,29 +432,32 @@ int main(int ac, char**av)
|
|||||||
if (sf_run) {
|
if (sf_run) {
|
||||||
if (!res[2].ms)
|
if (!res[2].ms)
|
||||||
res[2].ms = 1;
|
res[2].ms = 1;
|
||||||
printf("total SF %'lums %'lums lps=%'lu min=%'lu max=%'lu (skipped %d)\n",
|
printf("total Stockfish : perft:%'lums ms:%'lums lps:%'lu min:%'lu max:%'lu "
|
||||||
|
"(skipped %d/%d)\n",
|
||||||
res[2].count, res[2].ms,
|
res[2].count, res[2].ms,
|
||||||
res[2].count * 1000l / res[2].ms,
|
res[2].count * 1000l / res[2].ms,
|
||||||
res[2].minlps, res[2].maxlps,
|
res[2].minlps, res[2].maxlps,
|
||||||
res[2].skipped);
|
res[0].skipped, curtest);
|
||||||
}
|
}
|
||||||
if (run & 1) {
|
if (run & 1) {
|
||||||
if (!res[0].ms)
|
if (!res[0].ms)
|
||||||
res[0].ms = 1;
|
res[0].ms = 1;
|
||||||
printf("total perft %'lums %'lums lps=%'lu min=%'lu max=%'lu (skipped %d)\n",
|
printf("total perft : perft:%'lums ms:%'lums lps:%'lu min:%'lu max:%'lu "
|
||||||
|
"(skipped %d/%d)\n",
|
||||||
res[0].count, res[0].ms,
|
res[0].count, res[0].ms,
|
||||||
res[0].count * 1000l / res[0].ms,
|
res[0].count * 1000l / res[0].ms,
|
||||||
res[0].minlps, res[0].maxlps,
|
res[0].minlps, res[0].maxlps,
|
||||||
res[0].skipped);
|
res[0].skipped, curtest);
|
||||||
}
|
}
|
||||||
if (run & 2) {
|
if (run & 2) {
|
||||||
if (!res[1].ms)
|
if (!res[1].ms)
|
||||||
res[1].ms = 1;
|
res[1].ms = 1;
|
||||||
printf("total perft2 %'lums %'lums lps=%'lu min=%'lu max=%'lu (skipped %d)\n",
|
printf("total perft_alt : perft:%'lums ms:%'lums lps:%'lu min:%'lu max:%'lu "
|
||||||
|
"(skipped %d/%d)\n",
|
||||||
res[1].count, res[1].ms,
|
res[1].count, res[1].ms,
|
||||||
res[1].count * 1000l / res[1].ms,
|
res[1].count * 1000l / res[1].ms,
|
||||||
res[1].minlps, res[1].maxlps,
|
res[1].minlps, res[1].maxlps,
|
||||||
res[1].skipped);
|
res[0].skipped, curtest);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user