mirror of
https://github.com/sockspls/badfish
synced 2025-04-30 08:43:09 +00:00
Implemented perft
Patch from Joona with extension to benchmark and inclusion of Depth(0) moves generation by me. Note that to test also qsearch and in particulary checks generations a change in the end condition is needed. Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This commit is contained in:
parent
d9b920acfb
commit
fa49311b36
5 changed files with 57 additions and 5 deletions
|
@ -104,7 +104,7 @@ void benchmark(const string& commandLine) {
|
||||||
|
|
||||||
if (limitType == "time")
|
if (limitType == "time")
|
||||||
secsPerPos = val * 1000;
|
secsPerPos = val * 1000;
|
||||||
else if (limitType == "depth")
|
else if (limitType == "depth" || limitType == "perft")
|
||||||
maxDepth = val;
|
maxDepth = val;
|
||||||
else
|
else
|
||||||
maxNodes = val;
|
maxNodes = val;
|
||||||
|
@ -153,7 +153,9 @@ void benchmark(const string& commandLine) {
|
||||||
int dummy[2] = {0, 0};
|
int dummy[2] = {0, 0};
|
||||||
Position pos(*it);
|
Position pos(*it);
|
||||||
cerr << "\nBench position: " << cnt << '/' << positions.size() << endl << endl;
|
cerr << "\nBench position: " << cnt << '/' << positions.size() << endl << endl;
|
||||||
if (!think(pos, true, false, 0, dummy, dummy, 0, maxDepth, maxNodes, secsPerPos, moves))
|
if (limitType == "perft")
|
||||||
|
totalNodes += perft(pos, maxDepth * OnePly);
|
||||||
|
else if (!think(pos, true, false, 0, dummy, dummy, 0, maxDepth, maxNodes, secsPerPos, moves))
|
||||||
break;
|
break;
|
||||||
totalNodes += nodes_searched();
|
totalNodes += nodes_searched();
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,7 @@ int main(int argc, char *argv[]) {
|
||||||
if (string(argv[1]) != "bench" || argc < 4 || argc > 8)
|
if (string(argv[1]) != "bench" || argc < 4 || argc > 8)
|
||||||
cout << "Usage: stockfish bench <hash size> <threads> "
|
cout << "Usage: stockfish bench <hash size> <threads> "
|
||||||
<< "[time = 60s] [fen positions file = default] "
|
<< "[time = 60s] [fen positions file = default] "
|
||||||
<< "[time, depth or node limited = time] "
|
<< "[time, depth, perft or node limited = time] "
|
||||||
<< "[timing file name = none]" << endl;
|
<< "[timing file name = none]" << endl;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -326,6 +326,32 @@ namespace {
|
||||||
//// Functions
|
//// Functions
|
||||||
////
|
////
|
||||||
|
|
||||||
|
|
||||||
|
/// perft() is our utility to verify move generation is bug free. All the
|
||||||
|
/// legal moves up to given depth are generated and counted and the sum returned.
|
||||||
|
|
||||||
|
int perft(Position& pos, Depth depth)
|
||||||
|
{
|
||||||
|
if (depth <= Depth(0)) // Replace with '<' to test also qsearch
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
Move move;
|
||||||
|
MovePicker mp = MovePicker(pos, MOVE_NONE, depth, H);
|
||||||
|
Bitboard dcCandidates = mp.discovered_check_candidates();
|
||||||
|
int sum = 0;
|
||||||
|
|
||||||
|
// Loop through all legal moves
|
||||||
|
while ((move = mp.get_next_move()) != MOVE_NONE)
|
||||||
|
{
|
||||||
|
StateInfo st;
|
||||||
|
pos.do_move(move, st, dcCandidates);
|
||||||
|
sum += perft(pos, depth - OnePly);
|
||||||
|
pos.undo_move(move);
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// think() is the external interface to Stockfish's search, and is called when
|
/// think() is the external interface to Stockfish's search, and is called when
|
||||||
/// the program receives the UCI 'go' command. It initializes various
|
/// the program receives the UCI 'go' command. It initializes various
|
||||||
/// search-related global variables, and calls root_search(). It returns false
|
/// search-related global variables, and calls root_search(). It returns false
|
||||||
|
|
|
@ -69,6 +69,7 @@ extern void stop_threads();
|
||||||
extern bool think(const Position &pos, bool infinite, bool ponder, int side_to_move,
|
extern bool think(const Position &pos, bool infinite, bool ponder, int side_to_move,
|
||||||
int time[], int increment[], int movesToGo, int maxDepth,
|
int time[], int increment[], int movesToGo, int maxDepth,
|
||||||
int maxNodes, int maxTime, Move searchMoves[]);
|
int maxNodes, int maxTime, Move searchMoves[]);
|
||||||
|
extern int perft(Position &pos, Depth depth);
|
||||||
extern int64_t nodes_searched();
|
extern int64_t nodes_searched();
|
||||||
|
|
||||||
|
|
||||||
|
|
23
src/uci.cpp
23
src/uci.cpp
|
@ -61,6 +61,7 @@ namespace {
|
||||||
void set_option(UCIInputParser& uip);
|
void set_option(UCIInputParser& uip);
|
||||||
void set_position(UCIInputParser& uip);
|
void set_position(UCIInputParser& uip);
|
||||||
bool go(UCIInputParser& uip);
|
bool go(UCIInputParser& uip);
|
||||||
|
void perft(UCIInputParser& uip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -155,6 +156,8 @@ namespace {
|
||||||
cout << "key: " << hex << RootPosition.get_key()
|
cout << "key: " << hex << RootPosition.get_key()
|
||||||
<< "\nmaterial key: " << RootPosition.get_material_key()
|
<< "\nmaterial key: " << RootPosition.get_material_key()
|
||||||
<< "\npawn key: " << RootPosition.get_pawn_key() << endl;
|
<< "\npawn key: " << RootPosition.get_pawn_key() << endl;
|
||||||
|
else if (token == "perft")
|
||||||
|
perft(uip);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cout << "Unknown command: " << command << endl;
|
cout << "Unknown command: " << command << endl;
|
||||||
|
@ -318,4 +321,24 @@ namespace {
|
||||||
time, inc, movesToGo, depth, nodes, moveTime, searchMoves);
|
time, inc, movesToGo, depth, nodes, moveTime, searchMoves);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void perft(UCIInputParser& uip) {
|
||||||
|
|
||||||
|
string token;
|
||||||
|
int depth = 0;
|
||||||
|
|
||||||
|
while (!uip.eof())
|
||||||
|
{
|
||||||
|
uip >> token;
|
||||||
|
|
||||||
|
if (token == "depth")
|
||||||
|
uip >> depth;
|
||||||
|
}
|
||||||
|
Position pos = RootPosition;
|
||||||
|
int tm = get_system_time();
|
||||||
|
int n = perft(pos, depth * OnePly);
|
||||||
|
tm = get_system_time() - tm;
|
||||||
|
std::cout << "\nNodes " << n
|
||||||
|
<< "\nTime (ms) " << tm
|
||||||
|
<< "\nNodes/second " << (int)(n/(tm/1000.0)) << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue