/* * A compromise between probe_hard and probe_soft. Check the cache, and return * if the position is found. If not, use a thread to load the position into * cache in the background while we return to the main search. The background * load uses a worker thread, and has minimal load implications because the * thread is blocked nearly 100% of the time. */ bool probe_gtb_firm(const position_t* pos, int* score) { gtb_args_t args_storage; gtb_args_t* gtb_args = &args_storage; gtb_args->stm = stm_to_gtb(pos->side_to_move); gtb_args->ep = ep_to_gtb(pos->ep_square); gtb_args->castle = castle_to_gtb(pos->castle_rights); fill_gtb_arrays(pos, gtb_args->ws, gtb_args->bs, gtb_args->wp, gtb_args->bp); unsigned res; int success = tb_probe_WDL_soft(gtb_args->stm, gtb_args->ep, gtb_args->castle, gtb_args->ws, gtb_args->bs, gtb_args->wp, gtb_args->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 true; } if (worker_task_ready) return false; memcpy(&worker_args, gtb_args, sizeof(gtb_args_t)); worker_task_ready = true; return false; }
/* * Probe the tb cache only, without considering what's available on disk. */ bool probe_gtb_soft(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_soft(stm, ep, castle, ws, bs, wp, bp, &res); if (success) { if (res == tb_DRAW) *score = DRAW_VALUE; else if (res == tb_BMATE) *score = -MATE_VALUE + 1024; else if (res == tb_WMATE) *score = MATE_VALUE - 1024; else assert(false); if (pos->side_to_move == BLACK) *score *= -1; } return success; }
// 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; }