Exemplo n.º 1
0
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);
}
Exemplo n.º 2
0
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;
}