/* * Probe all tbs, using the cache if available, but blocking and waiting for * disk if we miss in cache. */ bool probe_gtb_hard(const position_t* pos, int* score) { int stm = stm_to_gtb(pos->side_to_move); int ep = ep_to_gtb(pos->ep_square); int castle = castle_to_gtb(pos->castle_rights); unsigned int ws[17], bs[17]; unsigned char wp[17], bp[17]; fill_gtb_arrays(pos, ws, bs, wp, bp); unsigned res; int success = tb_probe_WDL_hard(stm, ep, castle, ws, bs, wp, bp, &res); if (success) { if (res == tb_DRAW) *score = DRAW_VALUE; else if (res == tb_BMATE) *score = -MIN_MATE_VALUE; else if (res == tb_WMATE) *score = MIN_MATE_VALUE; else assert(false); if (pos->side_to_move == BLACK) *score *= -1; } return success; }
void* gtb_probe_firm_worker(void* payload) #endif { (void)payload; while (true) { // Wait for a readied task. int counter = 0; while (++counter < 5000 && !worker_task_ready) {} if (!worker_task_ready) { #ifdef WINDOWS_THREADS while (!worker_task_ready) Sleep(1); #else while (!worker_task_ready) usleep(100); #endif } // We've been woken back up, there must be something for us to do. if (worker_quit) break; unsigned res; int success = tb_probe_WDL_hard(worker_args.stm, worker_args.ep, worker_args.castle, worker_args.ws, worker_args.bs, worker_args.wp, worker_args.bp, &res); (void)success; if (worker_quit) break; worker_task_ready = false; } worker_task_ready = false; worker_quit = false; return 0; }
// probe_egtb() does the actual probing. On failure it returns VALUE_NONE. Value probe_egtb(Position &pos, const int ply, const bool hard, const bool exact) { // Conversion variables Bitboard occ; int count; // stockfish -> egtb int stm, epsquare, castling; unsigned int ws[17], bs[17]; unsigned char wp[17], bp[17]; // egtb -> stockfish int tb_available; unsigned info = tb_UNKNOWN; unsigned pliestomate; // Prepare info for white (stockfish -> egtb) occ = pos.pieces_of_color(WHITE); count = 0; while (occ) { Square s = pop_1st_bit(&occ); ws[count] = s; wp[count] = (unsigned char) pos.type_of_piece_on(s); count++; } ws[count] = tb_NOSQUARE; wp[count] = tb_NOPIECE; // Prepare info for black (stockfish -> egtb) occ = pos.pieces_of_color(BLACK); count = 0; while (occ) { Square s = pop_1st_bit(&occ); bs[count] = s; bp[count] = (unsigned char) pos.type_of_piece_on(s); count++; } bs[count] = tb_NOSQUARE; bp[count] = tb_NOPIECE; // Prepare general info stm = pos.side_to_move(); epsquare = pos.ep_square(); castling = tb_NOCASTLE; if (pos.can_castle(WHITE) || pos.can_castle(BLACK)) { if (Chess960) return VALUE_NONE; if (pos.can_castle_kingside(WHITE)) castling |= tb_WOO; if (pos.can_castle_queenside(WHITE)) castling |= tb_WOOO; if (pos.can_castle_kingside(BLACK)) castling |= tb_BOO; if (pos.can_castle_queenside(BLACK)) castling |= tb_BOOO; } // Do the actual probing if (hard) { if (exact) tb_available = tb_probe_hard (stm, epsquare, castling, ws, bs, wp, bp, &info, &pliestomate); else tb_available = tb_probe_WDL_hard (stm, epsquare, castling, ws, bs, wp, bp, &info); } else { if (exact) tb_available = tb_probe_soft (stm, epsquare, castling, ws, bs, wp, bp, &info, &pliestomate); else tb_available = tb_probe_WDL_soft (stm, epsquare, castling, ws, bs, wp, bp, &info); } // Return probing info (if available) if (tb_available) { pos.set_tb_hits(pos.tb_hits() + 1); if (info == tb_DRAW) return VALUE_DRAW; else if (info == tb_WMATE && stm == tb_WHITE_TO_MOVE) return (exact ? value_mate_in(pliestomate+ply) : VALUE_KNOWN_WIN); else if (info == tb_BMATE && stm == tb_BLACK_TO_MOVE) return (exact ? value_mate_in(pliestomate+ply) : VALUE_KNOWN_WIN); else if (info == tb_WMATE && stm == tb_BLACK_TO_MOVE) return (exact ? value_mated_in(pliestomate+ply) : -VALUE_KNOWN_WIN); else if (info == tb_BMATE && stm == tb_WHITE_TO_MOVE) return (exact ? value_mated_in(pliestomate+ply) : -VALUE_KNOWN_WIN); else return VALUE_NONE; } else return VALUE_NONE; }