void perft_divide(int depth) { char str[10]; unsigned moves[256], count, i; double timespan; uint64_t total, perft; clock_t start, end; printf("Divide (depth %02i)\n", depth); printf("--------------------\n"); start = clock(); count = gen_moves(moves); total = 0, perft = 0; for(i = 0; i < count; i++) { if(board_add(moves[i])) { perft = perft_perft(depth-1); board_subtract(); total += perft; move_to_string(moves[i], str); printf("%-5s %10llu\n", str, (long long unsigned int)perft); } } end = clock(); timespan = (double)(end - start) / CLOCKS_PER_SEC; printf("\nTotal %10llu\n", (long long unsigned int)total); printf("Time %9.3fs\n", timespan); printf("Moves/s %12.1f\n", total/timespan); }
void perft_divide(FILE* stream, Board* board, unsigned int depth) { int i, totalMoves = 0; Move moves[256]; if (depth <= 0) { return; } int num_moves = generate_moves(board, moves); for (i = 0; i < num_moves; ++i) { int numDividedMoves = 0; char moveString[8]; sprint_move(moveString, moves[i]); printf("%s ", moveString); make_move(board, moves[i]); numDividedMoves = perft_perft(board, depth - 1); unmake_move(board, moves[i]); totalMoves += numDividedMoves; printf("%i\n", numDividedMoves); } fprintf(stream, "\nMoves: %i\n", num_moves); fprintf(stream, "Nodes: %i\n", totalMoves); }
int perft_test_perft(EPDFile* epdFile) { int i = 0; Timer totalTimer, perftTimer; printf("Testing %i perfts\n", epdFile->numEPD); start_timer(&totalTimer); for (i = 0; i < epdFile->numEPD; ++i) { EPD* epd = &epdFile->epds[i]; int depth = 1; char depthKey[8]; unsigned int perftExpected = 0, perftActual; printf("%i/%i %s\n", i + 1, epdFile->numEPD, epd->description); while (1) { snprintf(depthKey, 8, "D%i", depth); if (!epd_has_operation(epd, depthKey)) { break; } perftExpected = epd_uint_operation(epd, depthKey); start_timer(&perftTimer); perftActual = perft_perft(&epd->board, depth); stop_timer(&perftTimer); printf("perft %i: %i [%03fs] (%i) %s\n", depth, perftActual, get_elapsed_time(&perftTimer), perftExpected, perftActual == perftExpected ? "PASS" : "FAIL"); if (perftActual != perftExpected) { printf("Fail in perft test\n"); printf("FEN: %s\n", epd->description); printf("Level: %i\n", depth); printf("Expected: %i\n", perftExpected); printf("Found: %i\n", perftActual); return 0; } ++depth; } printf("\n"); } stop_timer(&totalTimer); printf("Perft suite finished in %03fs\n", get_elapsed_time(&totalTimer)); return 1; }
unsigned int perft_perft(Board* board, unsigned int depth) { int i, nperft = 0; Move moves[256]; if (depth == 0) { return 1; } TTEntry* ttentry = get_tt_entry_at_depth(board->zobrist, depth); if (ttentry) { return ttentry->score; } unsigned int numMoves = generate_moves(board, moves); for (i = 0; i < numMoves; ++i) { make_move(board, moves[i]); if ((board->sideToMove == BLACK && !black_attacks_square(board, bit_scan_forward(board->pieces[WHITE_KING]))) || (board->sideToMove == WHITE && !white_attacks_square(board, bit_scan_forward(board->pieces[BLACK_KING])))) { nperft += perft_perft(board, depth - 1); } unmake_move(board, moves[i]); } TTEntry new_entry; new_entry.key = board->zobrist; new_entry.score = nperft; new_entry.depth = depth; put_tt_entry(&new_entry); return nperft; }
uint64_t perft_perft(int depth) { unsigned moves[256], count, i; hash_node* node; uint64_t total; if(depth == 0) return 1; node = hash_find(table, zobrist); if(node != NULL && node->depth == depth) return node->sub_nodes; count = gen_moves(moves); total = 0; for(i = 0; i < count; i++) { if(board_add(moves[i])) { total += perft_perft(depth - 1); board_subtract(); } } hash_add_perft(table, zobrist, depth, total); return total; }