Exemplo n.º 1
0
        /// KP vs K. This endgame is evaluated with the help of a bitbase.
        internal static Value Endgame_KPK(Color strongerSide, Position pos)
        {
            Color weakerSide = strongerSide ^ 1;

            Debug.Assert(pos.non_pawn_material(strongerSide) == ValueC.VALUE_ZERO);
            Debug.Assert(pos.non_pawn_material(weakerSide) == ValueC.VALUE_ZERO);
            Debug.Assert(pos.piece_count(strongerSide, PieceTypeC.PAWN) == 1);
            Debug.Assert(pos.piece_count(weakerSide, PieceTypeC.PAWN) == 0);

            Square wksq, bksq, wpsq;
            Color  stm;

            if (strongerSide == ColorC.WHITE)
            {
                wksq = pos.king_square(ColorC.WHITE);
                bksq = pos.king_square(ColorC.BLACK);
                wpsq = pos.pieceList[ColorC.WHITE][PieceTypeC.PAWN][0];
                stm  = pos.sideToMove;
            }
            else
            {
                wksq = Utils.flip_S(pos.king_square(ColorC.BLACK));
                bksq = Utils.flip_S(pos.king_square(ColorC.WHITE));
                wpsq = Utils.flip_S(pos.pieceList[ColorC.BLACK][PieceTypeC.PAWN][0]);
                stm  = Utils.flip_C(pos.sideToMove);
            }

            if (Utils.file_of(wpsq) >= FileC.FILE_E)
            {
                wksq = Utils.mirror(wksq);
                bksq = Utils.mirror(bksq);
                wpsq = Utils.mirror(wpsq);
            }

            if (KPKPosition.probe_kpk_bitbase(wksq, wpsq, bksq, stm) == 0)
            {
                return(ValueC.VALUE_DRAW);
            }

            Value result = ValueC.VALUE_KNOWN_WIN
                           + Constants.PawnValueEndgame
                           + Utils.rank_of(wpsq);

            return(strongerSide == pos.sideToMove ? result : -result);
        }
Exemplo n.º 2
0
        /// K and a pawn vs K and a pawn. This is done by removing the weakest side's
        /// pawn and probing the KP vs K bitbase: If the weakest side has a draw without
        /// the pawn, she probably has at least a draw with the pawn as well. The exception
        /// is when the stronger side's pawn is far advanced and not on a rook file; in
        /// this case it is often possible to win (e.g. 8/4k3/3p4/3P4/6K1/8/8/8 w - - 0 1).
        internal static ScaleFactor Endgame_KPKP(Color strongerSide, Position pos)
        {
            Color weakerSide = strongerSide ^ 1;

            Debug.Assert(pos.non_pawn_material(strongerSide) == ValueC.VALUE_ZERO);
            Debug.Assert(pos.non_pawn_material(weakerSide) == ValueC.VALUE_ZERO);
            Debug.Assert(pos.piece_count(ColorC.WHITE, PieceTypeC.PAWN) == 1);
            Debug.Assert(pos.piece_count(ColorC.BLACK, PieceTypeC.PAWN) == 1);

            Square wksq = pos.king_square(strongerSide);
            Square bksq = pos.king_square(weakerSide);
            Square wpsq = pos.pieceList[strongerSide][PieceTypeC.PAWN][0];
            Color  stm  = pos.sideToMove;

            if (strongerSide == ColorC.BLACK)
            {
                wksq = Utils.flip_S(wksq);
                bksq = Utils.flip_S(bksq);
                wpsq = Utils.flip_S(wpsq);
                stm  = Utils.flip_C(stm);
            }

            if (Utils.file_of(wpsq) >= FileC.FILE_E)
            {
                wksq = Utils.mirror(wksq);
                bksq = Utils.mirror(bksq);
                wpsq = Utils.mirror(wpsq);
            }

            // If the pawn has advanced to the fifth rank or further, and is not a
            // rook pawn, it's too dangerous to assume that it's at least a draw.
            if (Utils.rank_of(wpsq) >= RankC.RANK_5 &&
                Utils.file_of(wpsq) != FileC.FILE_A)
            {
                return(ScaleFactorC.SCALE_FACTOR_NONE);
            }

            // Probe the KPK bitbase with the weakest side's pawn removed. If it's a draw,
            // it's probably at least a draw even with the pawn.
            return((KPKPosition.probe_kpk_bitbase(wksq, wpsq, bksq, stm) != 0) ? ScaleFactorC.SCALE_FACTOR_NONE : ScaleFactorC.SCALE_FACTOR_DRAW);
        }