bool CTablebases::probe(eval_t& eval, const CBoard& board) { if (loaded()) { int rgiCounters[10]; for (int32 i = 0; i < 10; ++i) rgiCounters[i] = 0; const int rgsq_cnt = C_PIECES * 5 + 1; square rgsqWhite[rgsq_cnt]; square rgsqBlack[rgsq_cnt]; for (int32 i = 0; i < rgsq_cnt; ++i) rgsqWhite[i] = rgsqBlack[i] = XX; VInitSqCtr(rgiCounters, rgsqWhite, 0, board.getPieceBits(eW_P)); VInitSqCtr(rgiCounters, rgsqWhite, 1, board.getPieceBits(eW_N)); VInitSqCtr(rgiCounters, rgsqWhite, 2, board.getPieceBits(eW_B)); VInitSqCtr(rgiCounters, rgsqWhite, 3, board.getPieceBits(eW_R)); VInitSqCtr(rgiCounters, rgsqWhite, 4, board.getPieceBits(eW_Q)); VInitSqCtr(rgiCounters + 5, rgsqBlack, 0, board.getPieceBits(eB_P)); VInitSqCtr(rgiCounters + 5, rgsqBlack, 1, board.getPieceBits(eB_N)); VInitSqCtr(rgiCounters + 5, rgsqBlack, 2, board.getPieceBits(eB_B)); VInitSqCtr(rgiCounters + 5, rgsqBlack, 3, board.getPieceBits(eB_R)); VInitSqCtr(rgiCounters + 5, rgsqBlack, 4, board.getPieceBits(eB_Q)); int iTb = IDescFindFromCounters(rgiCounters); if (iTb) { bb_t wk = board.getPieceBits(eW_K); while (wk) rgsqWhite[C_PIECES * 5] = popFirstBit(wk); bb_t bk = board.getPieceBits(eB_K); while (bk) rgsqBlack[C_PIECES * 5] = popFirstBit(bk); color side; int fInvert; square* psqW; square* psqB; if (iTb > 0) { side = eWhite == board.getSide() ? x_colorWhite : x_colorBlack; fInvert = 0; psqW = rgsqWhite; psqB = rgsqBlack; } else { side = eWhite == board.getSide() ? x_colorBlack : x_colorWhite; fInvert = 1; psqW = rgsqBlack; psqB = rgsqWhite; iTb = -iTb; } if (FRegisteredFun(iTb, side)) { square sqEnP = eNF != board.getEp() ? board.getEp() : XX; INDEX ind = PfnIndCalcFun(iTb, side) (psqW, psqB, sqEnP, fInvert); int tbValue = L_TbtProbeTable(iTb, side, ind); if (tb_broken != tbValue) { if (tbValue > 0) eval = MATE_VALUE + 2 * (-tb_mate_in_1 + tbValue - 1); else if (tbValue < 0) eval = -MATE_VALUE + 2 * (tb_mate_in_1 + tbValue); else eval = DRAW_VALUE; ++m_hits; return (true); } } } } return(false); }
bool tablebase_t::operator()(const node_t& node, const std::uint_fast8_t height, score_t& score) const { std::uint32_t rgiCounters[10]; unsigned int rgsqWhite[C_PIECES * 5 + 1]; unsigned int rgsqBlack[C_PIECES * 5 + 1]; // initialize counters and piece arrays so the probe code // can compute the modified Godel number. init(rgiCounters, rgsqWhite, 0, node.board_pawns_white()); init(rgiCounters, rgsqWhite, 1, node.board_knights_white()); init(rgiCounters, rgsqWhite, 2, node.board_bishops_white()); init(rgiCounters, rgsqWhite, 3, node.board_rooks_white()); init(rgiCounters, rgsqWhite, 4, node.board_queens_white()); init(rgiCounters + 5, rgsqBlack, 0, node.board_pawns_black()); init(rgiCounters + 5, rgsqBlack, 1, node.board_knights_black()); init(rgiCounters + 5, rgsqBlack, 2, node.board_bishops_black()); init(rgiCounters + 5, rgsqBlack, 3, node.board_rooks_black()); init(rgiCounters + 5, rgsqBlack, 4, node.board_queens_black()); std::lock_guard<std::mutex> lock(const_cast<std::mutex&>(_mutex)); // tablebase registered ? int iTb = IDescFindFromCounters((int*)rgiCounters); if (!iTb) return false; // set up tablebase parameters std::uint32_t invert; int side; unsigned int* psqW; unsigned int* psqB; rgsqWhite[C_PIECES * 5] = node.square_king_white(); rgsqBlack[C_PIECES * 5] = node.square_king_black(); if (iTb > 0) { side = node.color() == black; invert = false; psqW = rgsqWhite; psqB = rgsqBlack; } else { side = node.color() == white; invert = true; psqW = rgsqBlack; psqB = rgsqWhite; iTb = -iTb; } // tablebase registered ? if (!FRegisteredFun(iTb, side)) return false; // get tbValue const unsigned int sqEnP = node.square_en_passant() ? node.square_en_passant() : 127; const std::uint64_t index = PfnIndCalcFun(iTb, side) ((unsigned int *)psqW, (unsigned int *)psqB, sqEnP, invert); const score_t tbValue = L_TbtProbeTable(iTb, side, index); if (tbValue == L_bev_broken) return false; // convert tbValue to score if (tbValue > 0) score = /*Score::max*/ +30000 + 2 * (-L_bev_mi1 + tbValue - 1) - (score_t)height + 1; else if (tbValue < 0) score = /*Score::min*/ -30000 + 2 * (+L_bev_mi1 + tbValue) + (score_t)height; else score = 0;//Score::remis; return true; }