当前位置: 首页>>代码示例>>C#>>正文


C# Position.pieces_PTC方法代码示例

本文整理汇总了C#中Portfish.Position.pieces_PTC方法的典型用法代码示例。如果您正苦于以下问题:C# Position.pieces_PTC方法的具体用法?C# Position.pieces_PTC怎么用?C# Position.pieces_PTC使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在Portfish.Position的用法示例。


在下文中一共展示了Position.pieces_PTC方法的12个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。

示例1: probe

        /// PawnTable::pawn_info() takes a position object as input, computes
        /// a PawnInfo object, and returns a pointer to it. The result is also stored
        /// in an hash table, so we don't have to recompute everything when the same
        /// pawn structure occurs again.
        internal void probe(Position pos, out PawnEntry e)
        {
            Key key = pos.pawn_key();
            e = entries[((UInt32)key) & Constants.PawnTableMask];

            // If pi.key matches the position's pawn hash key, it means that we
            // have analysed this pawn structure before, and we can simply return
            // the information we found the last time instead of recomputing it.
            if (e.key == key) return;

            // Initialize PawnInfo entry
            e.key = key;
            e.passedPawnsWHITE = e.passedPawnsBLACK = 0;
            e.kingSquaresWHITE = e.kingSquaresBLACK = SquareC.SQ_NONE;
            e.halfOpenFilesWHITE = e.halfOpenFilesBLACK = 0xFF;

            // Calculate pawn attacks
            Bitboard wPawns = pos.pieces_PTC(PieceTypeC.PAWN, ColorC.WHITE);
            Bitboard bPawns = pos.pieces_PTC(PieceTypeC.PAWN, ColorC.BLACK);

            e.pawnAttacksWHITE = ((wPawns & ~Constants.FileHBB) << 9) | ((wPawns & ~Constants.FileABB) << 7);
            e.pawnAttacksBLACK = ((bPawns & ~Constants.FileHBB) >> 7) | ((bPawns & ~Constants.FileABB) >> 9);

            // Evaluate pawns for both colors and weight the result
            e.value = evaluate_pawns(ColorC.WHITE, pos, wPawns, bPawns, e)
                       - evaluate_pawns(ColorC.BLACK, pos, bPawns, wPawns, e);

            e.value = Utils.apply_weight(e.value, PawnStructureWeight);

            return;
        }
开发者ID:CVChrisWilson,项目名称:Portfish,代码行数:35,代码来源:PawnInfo.cs

示例2: probe

        /// MaterialTable::material_info() takes a position object as input,
        /// computes or looks up a MaterialInfo object, and returns a pointer to it.
        /// If the material configuration is not already present in the table, it
        /// is stored there, so we don't have to recompute everything when the
        /// same material configuration occurs again.
        internal void probe(Position pos, out MaterialEntry e)
        {
            var key = pos.material_key();
            e = this.entries[((uint)key) & Constants.MaterialTableMask];

            // If mi->key matches the position's material hash key, it means that we
            // have analysed this material configuration before, and we can simply
            // return the information we found the last time instead of recomputing it.
            if (e.key == key)
            {
                return;
            }

            // Initialize MaterialInfo entry
            var npm = pos.non_pawn_material(ColorC.WHITE) + pos.non_pawn_material(ColorC.BLACK);
            e.value = 0;
            e.scalingFunctionWHITE = null;
            e.scalingFunctionBLACK = null;
            e.spaceWeight = 0;
            e.key = key;
            e.factorWHITE = e.factorBLACK = ScaleFactorC.SCALE_FACTOR_NORMAL;
            e.gamePhase = npm >= MidgameLimit
                              ? PhaseC.PHASE_MIDGAME
                              : npm <= EndgameLimit
                                    ? PhaseC.PHASE_ENDGAME
                                    : (((npm - EndgameLimit) * 128) / (MidgameLimit - EndgameLimit));

            // Let's look if we have a specialized evaluation function for this
            // particular material configuration. First we look for a fixed
            // configuration one, then a generic one if previous search failed.
            if ((e.evaluationFunction = Endgame.probeValue(key, out e.evaluationFunctionColor)) != null)
            {
                return;
            }

            if (is_KXK(ColorC.WHITE, pos))
            {
                e.evaluationFunction = Endgame.Endgame_KXK;
                e.evaluationFunctionColor = ColorC.WHITE;
                return;
            }

            if (is_KXK(ColorC.BLACK, pos))
            {
                e.evaluationFunction = Endgame.Endgame_KXK;
                e.evaluationFunctionColor = ColorC.BLACK;
                return;
            }

            if ((pos.pieces_PT(PieceTypeC.PAWN) == 0) && (pos.pieces_PT(PieceTypeC.ROOK) == 0)
                && (pos.pieces_PT(PieceTypeC.QUEEN) == 0))
            {
                // Minor piece endgame with at least one minor piece per side and
                // no pawns. Note that the case KmmK is already handled by KXK.
                Debug.Assert(
                    (pos.pieces_PTC(PieceTypeC.KNIGHT, ColorC.WHITE) | pos.pieces_PTC(PieceTypeC.BISHOP, ColorC.WHITE))
                    != 0);
                Debug.Assert(
                    (pos.pieces_PTC(PieceTypeC.KNIGHT, ColorC.BLACK) | pos.pieces_PTC(PieceTypeC.BISHOP, ColorC.BLACK))
                    != 0);

                if (pos.piece_count(ColorC.WHITE, PieceTypeC.BISHOP) + pos.piece_count(ColorC.WHITE, PieceTypeC.KNIGHT)
                    <= 2
                    && pos.piece_count(ColorC.BLACK, PieceTypeC.BISHOP)
                    + pos.piece_count(ColorC.BLACK, PieceTypeC.KNIGHT) <= 2)
                {
                    e.evaluationFunction = Endgame.Endgame_KmmKm;
                    e.evaluationFunctionColor = pos.sideToMove;
                    return;
                }
            }

            // OK, we didn't find any special evaluation function for the current
            // material configuration. Is there a suitable scaling function?
            //
            // We face problems when there are several conflicting applicable
            // scaling functions and we need to decide which one to use.
            EndgameScaleFactor sf;
            int c;
            if ((sf = Endgame.probeScaleFactor(key, out c)) != null)
            {
                if (c == ColorC.WHITE)
                {
                    e.scalingFunctionWHITE = sf;
                }
                else
                {
                    e.scalingFunctionBLACK = sf;
                }
                return;
            }

            // Generic scaling functions that refer to more then one material
            // distribution. Should be probed after the specialized ones.
            // Note that these ones don't return after setting the function.
//.........这里部分代码省略.........
开发者ID:torfranz,项目名称:Portfish,代码行数:101,代码来源:Material.cs

示例3: move_to_san

        /// move_to_san() takes a position and a legal Move as input and returns its
        /// short algebraic notation representation.
        internal static string move_to_san(Position pos, int m)
        {
            if (m == MoveC.MOVE_NONE)
            {
                return "(none)";
            }

            if (m == MoveC.MOVE_NULL)
            {
                return "(null)";
            }

            Debug.Assert(pos.move_is_legal(m));

            Bitboard others, b;
            Color us = pos.sideToMove;
            var san = new StringBuilder();

            Square from = from_sq(m);
            Square to = to_sq(m);
            Piece pc = pos.piece_on(from);
            PieceType pt = type_of(pc);

            if (type_of_move(m) == MoveTypeC.CASTLING)
            {
                san.Append(to > from ? "O-O" : "O-O-O");
            }
            else
            {
                if (pt != PieceTypeC.PAWN)
                {
                    san.Append(PieceToChar[ColorC.WHITE][pt]); // Upper case

                    // Disambiguation if we have more then one piece of type 'pt' that can
                    // reach 'to' with a legal move.
                    others = b = (pos.attacks_from_PS(pc, to) & pos.pieces_PTC(pt, us)) ^ (ulong)from;
                    while (others != 0)
                    {
                        Move move = make_move(pop_lsb(ref b), to);
                        if (!pos.pl_move_is_legal(move, pos.pinned_pieces()))
                        {
                            others ^= (ulong)from_sq(move);
                        }
                    }

                    if (others != 0)
                    {
                        if ((others & file_bb_S(from)) == 0)
                        {
                            san.Append(file_to_char(file_of(from)));
                        }
                        else if ((others & rank_bb_S(from)) == 0)
                        {
                            san.Append(rank_to_char(rank_of(from)));
                        }
                        else
                        {
                            san.Append(square_to_string(from));
                        }
                    }
                }
                else if (pos.is_capture(m))
                {
                    san.Append(file_to_char(file_of(from)));
                }

                if (pos.is_capture(m))
                {
                    san.Append('x');
                }

                san.Append(square_to_string(to));

                if (type_of_move(m) == MoveTypeC.PROMOTION)
                {
                    san.Append('=');
                    san.Append(PieceToChar[ColorC.WHITE][promotion_type(m)]);
                }
            }

            var ci = CheckInfoBroker.GetObject();
            ci.CreateCheckInfo(pos);
            if (pos.move_gives_check(m, ci))
            {
                var st = new StateInfo();
                pos.do_move(m, st);
                var mlist = MListBroker.GetObject();
                mlist.pos = 0;
                Movegen.generate_legal(pos, mlist.moves, ref mlist.pos);
                san.Append(mlist.pos > 0 ? "+" : "#");
                MListBroker.Free();
                pos.undo_move(m);
            }
            CheckInfoBroker.Free();

            return san.ToString();
        }
开发者ID:torfranz,项目名称:Portfish,代码行数:99,代码来源:Utils.cs

示例4: evaluate_pieces_of_color

        // evaluate_pieces_of_color<>() assigns bonuses and penalties to all the
        // pieces of a given color.
        private static int evaluate_pieces_of_color(int Us, bool Trace, Position pos, EvalInfo ei, ref int mobility)
        {
            var Them = (Us == ColorC.WHITE ? ColorC.BLACK : ColorC.WHITE);
            mobility = ScoreC.SCORE_ZERO;

            // Do not include in mobility squares protected by enemy pawns or occupied by our pieces
            var mobilityArea = ~(ei.attackedBy[Them][PieceTypeC.PAWN] | pos.byColorBB[Us]);

            #region Evaluate pieces

            ulong between = 0;
            var plPos = 0;
            int s, ksq;
            int mob;
            int f;
            int score, scores = ScoreC.SCORE_ZERO;

            var attackedByThemKing = ei.attackedBy[Them][PieceTypeC.KING];
            var attackedByThemPawn = ei.attackedBy[Them][PieceTypeC.PAWN];
            var kingRingThem = ei.kingRing[Them];

            for (var Piece = PieceTypeC.KNIGHT; Piece < PieceTypeC.KING; Piece++)
            {
                score = ScoreC.SCORE_ZERO;
                ei.attackedBy[Us][Piece] = 0;
                var pl = pos.pieceList[Us][Piece];
                plPos = 0;
                while ((s = pl[plPos++]) != SquareC.SQ_NONE)
                {
                    // Find attacked squares, including x-ray attacks for bishops and rooks
                    if (Piece == PieceTypeC.KNIGHT)
                    {
                        between = Utils.StepAttacksBB_KNIGHT[s];
                    }
                    else if (Piece == PieceTypeC.QUEEN)
                    {
#if X64
                        b = Utils.BAttacks[s][(((pos.occupied_squares & Utils.BMasks[s]) * Utils.BMagics[s]) >> Utils.BShifts[s])] | Utils.RAttacks[s][(((pos.occupied_squares & Utils.RMasks[s]) * Utils.RMagics[s]) >> Utils.RShifts[s])];
#else
                        between = Utils.bishop_attacks_bb(s, pos.occupied_squares)
                            | Utils.rook_attacks_bb(s, pos.occupied_squares);
#endif
                    }
                    else if (Piece == PieceTypeC.BISHOP)
                    {
#if X64
                        b = Utils.BAttacks[s][(((
                              (pos.occupied_squares ^ (pos.byTypeBB[PieceTypeC.QUEEN] & pos.byColorBB[Us]))
                            & Utils.BMasks[s]) * Utils.BMagics[s]) >> Utils.BShifts[s])];
#else
                        between = Utils.bishop_attacks_bb(s, pos.occupied_squares ^ pos.pieces_PTC(PieceTypeC.QUEEN, Us));
#endif
                    }
                    else if (Piece == PieceTypeC.ROOK)
                    {
#if X64
                        b = Utils.RAttacks[s][(((
                              (pos.occupied_squares ^ ((pos.byTypeBB[PieceTypeC.ROOK] | pos.byTypeBB[PieceTypeC.QUEEN]) & pos.byColorBB[Us]))
                            & Utils.RMasks[s]) * Utils.RMagics[s]) >> Utils.RShifts[s])];
#else
                        between = Utils.rook_attacks_bb(
                            s,
                            pos.occupied_squares ^ pos.pieces(PieceTypeC.ROOK, PieceTypeC.QUEEN, Us));
#endif
                    }

                    // Update attack info
                    ei.attackedBy[Us][Piece] |= between;

                    // King attacks
                    if ((between & kingRingThem) != 0)
                    {
                        ei.kingAttackersCount[Us]++;
                        ei.kingAttackersWeight[Us] += KingAttackWeights[Piece];
                        var bb = (between & attackedByThemKing); //ei.attackedBy[Them][PieceTypeC.KING]);
                        if (bb != 0)
                        {
#if X64
                            bb -= (bb >> 1) & 0x5555555555555555UL;
                            bb = ((bb >> 2) & 0x3333333333333333UL) + (bb & 0x3333333333333333UL);
                            ei.kingAdjacentZoneAttacksCount[Us] += (int)((bb * 0x1111111111111111UL) >> 60);
#else
                            ei.kingAdjacentZoneAttacksCount[Us] += Bitcount.popcount_1s_Max15(bb);
#endif
                        }
                    }

                    // Mobility
#if X64
                    Bitboard bmob = b & mobilityArea;
                    if (Piece != PieceTypeC.QUEEN)
                    {
                        bmob -= (bmob >> 1) & 0x5555555555555555UL;
                        bmob = ((bmob >> 2) & 0x3333333333333333UL) + (bmob & 0x3333333333333333UL);
                        mob = (int)((bmob * 0x1111111111111111UL) >> 60);
                    }
                    else
                    {
//.........这里部分代码省略.........
开发者ID:torfranz,项目名称:Portfish,代码行数:101,代码来源:Evaluate.cs

示例5: move_to_san

        /// move_to_san() takes a position and a move as input, where it is assumed
        /// that the move is a legal move for the position. The return value is
        /// a string containing the move in short algebraic notation.
        internal static string move_to_san(Position pos, Move m)
        {
            if (m == MoveC.MOVE_NONE)
                return "(none)";

            if (m == MoveC.MOVE_NULL)
                return "(null)";

            Debug.Assert(is_ok_M(m));

            Bitboard attackers;
            bool ambiguousMove, ambiguousFile, ambiguousRank;
            Square sq, from = from_sq(m);
            Square to = to_sq(m);
            PieceType pt = type_of(pos.piece_moved(m));

            StringBuilder san = new StringBuilder();

            if (is_castle(m))
                san.Append((to_sq(m) < from_sq(m) ? "O-O-O" : "O-O"));
            else
            {
                if (pt != PieceTypeC.PAWN)
                {
                    san.Append(piece_type_to_char(pt).ToString());

                    // Disambiguation if we have more then one piece with destination 'to'
                    // note that for pawns is not needed because starting file is explicit.
                    attackers = pos.attackers_to(to) & pos.pieces_PTC(pt, pos.sideToMove);
                    xor_bit(ref attackers, from);
                    ambiguousMove = ambiguousFile = ambiguousRank = false;

                    while (attackers != 0)
                    {
                        sq = pop_1st_bit(ref attackers);

                        // Pinned pieces are not included in the possible sub-set
                        if (!pos.pl_move_is_legal(make_move(sq, to), pos.pinned_pieces()))
                            continue;

                        if (file_of(sq) == file_of(from))
                            ambiguousFile = true;

                        if (rank_of(sq) == rank_of(from))
                            ambiguousRank = true;

                        ambiguousMove = true;
                    }

                    if (ambiguousMove)
                    {
                        if (!ambiguousFile)
                            san.Append(file_to_char(file_of(from)));
                        else if (!ambiguousRank)
                            san.Append(rank_to_char(rank_of(from)));
                        else
                            san.Append(square_to_string(from));
                    }
                }

                if (pos.is_capture(m))
                {
                    if (pt == PieceTypeC.PAWN)
                        san.Append(file_to_char(file_of(from)));

                    san.Append('x');
                }

                san.Append(square_to_string(to));

                if (is_promotion(m))
                {
                    san.Append('=');
                    san.Append(piece_type_to_char(promotion_type(m)));
                }
            }

            CheckInfo ci = CheckInfoBroker.GetObject();
            ci.CreateCheckInfo(pos);
            if (pos.move_gives_check(m, ci))
            {
                StateInfo st = new StateInfo();
                pos.do_move(m, st);
                MList mlist = MListBroker.GetObject(); mlist.pos = 0;
                Movegen.generate_legal(pos, mlist.moves, ref mlist.pos);
                san.Append(mlist.pos > 0 ? "+" : "#");
                MListBroker.Free();
                pos.undo_move(m);
            }
            CheckInfoBroker.Free();

            return san.ToString();
        }
开发者ID:stevemulligan,项目名称:Portfish,代码行数:96,代码来源:Utils.cs

示例6: Endgame_KQKRPs

        /// K and queen vs K, rook and one or more pawns. It tests for fortress draws with
        /// a rook on the third rank defended by a pawn.
        internal static ScaleFactor Endgame_KQKRPs(Color strongerSide, Position pos)
        {
            Color weakerSide = strongerSide ^ 1;

            Debug.Assert(pos.non_pawn_material(strongerSide) == Constants.QueenValueMidgame);
            Debug.Assert(pos.piece_count(strongerSide, PieceTypeC.QUEEN) == 1);
            Debug.Assert(pos.piece_count(strongerSide, PieceTypeC.PAWN) == 0);
            Debug.Assert(pos.piece_count(weakerSide, PieceTypeC.ROOK) == 1);
            Debug.Assert(pos.piece_count(weakerSide, PieceTypeC.PAWN) >= 1);

            Square kingSq = pos.king_square(weakerSide);
            if (Utils.relative_rank_CS(weakerSide, kingSq) <= RankC.RANK_2
                && Utils.relative_rank_CS(weakerSide, pos.king_square(strongerSide)) >= RankC.RANK_4
                && ((pos.pieces_PTC(PieceTypeC.ROOK, weakerSide) & Utils.rank_bb_R(Utils.relative_rank_CR(weakerSide, RankC.RANK_3))) != 0)
                && ((pos.pieces_PTC(PieceTypeC.PAWN, weakerSide) & Utils.rank_bb_R(Utils.relative_rank_CR(weakerSide, RankC.RANK_2))) != 0)
                && ((Position.attacks_from_KING(kingSq) & pos.pieces_PTC(PieceTypeC.PAWN, weakerSide)) != 0)
                )
            {
                Square rsq = pos.pieceList[weakerSide][PieceTypeC.ROOK][0];
                if ((Position.attacks_from_PAWN(rsq, strongerSide) & pos.pieces_PTC(PieceTypeC.PAWN, weakerSide)) != 0)
                    return ScaleFactorC.SCALE_FACTOR_DRAW;
            }
            return ScaleFactorC.SCALE_FACTOR_NONE;
        }
开发者ID:CVChrisWilson,项目名称:Portfish,代码行数:26,代码来源:Endgame.cs

示例7: evaluate_unstoppable_pawns

        // evaluate_unstoppable_pawns() evaluates the unstoppable passed pawns for both sides, this is quite
        // conservative and returns a winning score only when we are very sure that the pawn is winning.
        private static int evaluate_unstoppable_pawns(Position pos, EvalInfo ei)
        {
            ulong b, b2, blockers, supporters, queeningPath, candidates;
            int s, blockSq, queeningSquare;
            int c, winnerSide, loserSide;
            bool pathDefended, opposed;
            int pliesToGo = 0, movesToGo, oppMovesToGo = 0, sacptg, blockersCount, minKingDist, kingptg, d;
            int pliesToQueenWHITE = 256, pliesToQueenBLACK = 256, pliesToQueenWinner = 256;

            // Step 1. Hunt for unstoppable passed pawns. If we find at least one,
            // record how many plies are required for promotion.
            for (c = ColorC.WHITE; c <= ColorC.BLACK; c++)
            {
                // Skip if other side has non-pawn pieces
                if (pos.non_pawn_material(Utils.flip_C(c)) != 0)
                {
                    continue;
                }

                b = ei.pi.passed_pawns(c);

                while (b != 0)
                {
                    s = Utils.pop_lsb(ref b);
                    queeningSquare = Utils.relative_square(c, Utils.make_square(Utils.file_of(s), RankC.RANK_8));
                    queeningPath = Utils.forward_bb(c, s);

                    // Compute plies to queening and check direct advancement
                    movesToGo = Utils.rank_distance(s, queeningSquare)
                                - (Utils.relative_rank_CS(c, s) == RankC.RANK_2 ? 1 : 0);
                    oppMovesToGo = Utils.square_distance(pos.king_square(Utils.flip_C(c)), queeningSquare)
                                   - ((c != pos.sideToMove) ? 1 : 0);
                    pathDefended = ((ei.attackedBy[c][0] & queeningPath) == queeningPath);

                    if (movesToGo >= oppMovesToGo && !pathDefended)
                    {
                        continue;
                    }

                    // Opponent king cannot block because path is defended and position
                    // is not in check. So only friendly pieces can be blockers.
                    Debug.Assert(!pos.in_check());
                    Debug.Assert((queeningPath & pos.occupied_squares) == (queeningPath & pos.pieces_C(c)));

                    // Add moves needed to free the path from friendly pieces and retest condition
                    movesToGo += Bitcount.popcount_1s_Max15(queeningPath & pos.pieces_C(c));

                    if (movesToGo >= oppMovesToGo && !pathDefended)
                    {
                        continue;
                    }

                    pliesToGo = 2 * movesToGo - ((c == pos.sideToMove) ? 1 : 0);

                    if (c == ColorC.WHITE)
                    {
                        pliesToQueenWHITE = Math.Min(pliesToQueenWHITE, pliesToGo);
                    }
                    else
                    {
                        pliesToQueenBLACK = Math.Min(pliesToQueenBLACK, pliesToGo);
                    }
                }
            }

            // Step 2. If either side cannot promote at least three plies before the other side then situation
            // becomes too complex and we give up. Otherwise we determine the possibly "winning side"
            if (Math.Abs(pliesToQueenWHITE - pliesToQueenBLACK) < 3)
            {
                return ScoreC.SCORE_ZERO;
            }

            winnerSide = (pliesToQueenWHITE < pliesToQueenBLACK ? ColorC.WHITE : ColorC.BLACK);
            pliesToQueenWinner = (winnerSide == ColorC.WHITE) ? pliesToQueenWHITE : pliesToQueenBLACK;
            loserSide = Utils.flip_C(winnerSide);

            // Step 3. Can the losing side possibly create a new passed pawn and thus prevent the loss?
            b = candidates = pos.pieces_PTC(PieceTypeC.PAWN, loserSide);

            while (b != 0)
            {
                s = Utils.pop_lsb(ref b);

                // Compute plies from queening
                queeningSquare = Utils.relative_square(loserSide, Utils.make_square(Utils.file_of(s), RankC.RANK_8));
                movesToGo = Utils.rank_distance(s, queeningSquare)
                            - ((Utils.relative_rank_CS(loserSide, s) == RankC.RANK_2) ? 1 : 0);
                pliesToGo = 2 * movesToGo - ((loserSide == pos.sideToMove) ? 1 : 0);

                // Check if (without even considering any obstacles) we're too far away or doubled
                if ((pliesToQueenWinner + 3 <= pliesToGo)
                    || ((Utils.forward_bb(loserSide, s) & pos.pieces_PTC(PieceTypeC.PAWN, loserSide)) != 0))
                {
                    Utils.xor_bit(ref candidates, s);
                }
            }

            // If any candidate is already a passed pawn it _may_ promote in time. We give up.
//.........这里部分代码省略.........
开发者ID:torfranz,项目名称:Portfish,代码行数:101,代码来源:Evaluate.cs

示例8: Endgame_KPsK

        /// K and two or more pawns vs K. There is just a single rule here: If all pawns
        /// are on the same rook file and are blocked by the defending king, it's a draw.
        internal static ScaleFactor Endgame_KPsK(Color strongerSide, Position pos)
        {
            Color weakerSide = strongerSide ^ 1;

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

            Square ksq = pos.king_square(weakerSide);
            Bitboard pawns = pos.pieces_PTC(PieceTypeC.PAWN, strongerSide);

            // Are all pawns on the 'a' file?
            if ((pawns & ~Constants.FileABB) == 0)
            {
                // Does the defending king block the pawns?
                if (Utils.square_distance(ksq, Utils.relative_square(strongerSide, SquareC.SQ_A8)) <= 1
                    || (Utils.file_of(ksq) == FileC.FILE_A
                        && ((Utils.in_front_bb_CS(strongerSide, ksq)) & pawns) == 0))
                    return ScaleFactorC.SCALE_FACTOR_DRAW;
            }
            // Are all pawns on the 'h' file?
            else if ((pawns & ~Constants.FileHBB) == 0)
            {
                // Does the defending king block the pawns?
                if (Utils.square_distance(ksq, Utils.relative_square(strongerSide, SquareC.SQ_H8)) <= 1
                    || (Utils.file_of(ksq) == FileC.FILE_H
                        && ((Utils.in_front_bb_CS(strongerSide, ksq)) & pawns) == 0))
                    return ScaleFactorC.SCALE_FACTOR_DRAW;
            }
            return ScaleFactorC.SCALE_FACTOR_NONE;
        }
开发者ID:CVChrisWilson,项目名称:Portfish,代码行数:34,代码来源:Endgame.cs

示例9: Endgame_KBPsK

        /// K, bishop and one or more pawns vs K. It checks for draws with rook pawns and
        /// a bishop of the wrong color. If such a draw is detected, SCALE_FACTOR_DRAW
        /// is returned. If not, the return value is SCALE_FACTOR_NONE, i.e. no scaling
        /// will be used.
        internal static ScaleFactor Endgame_KBPsK(Color strongerSide, Position pos)
        {
            Color weakerSide = strongerSide ^ 1;

            Debug.Assert(pos.non_pawn_material(strongerSide) == Constants.BishopValueMidgame);
            Debug.Assert(pos.piece_count(strongerSide, PieceTypeC.BISHOP) == 1);
            Debug.Assert(pos.piece_count(strongerSide, PieceTypeC.PAWN) >= 1);

            // No Debug.Assertions about the material of weakerSide, because we want draws to
            // be detected even when the weaker side has some pawns.

            Bitboard pawns = pos.pieces_PTC(PieceTypeC.PAWN, strongerSide);
            File pawnFile = Utils.file_of(pos.pieceList[strongerSide][PieceTypeC.PAWN][0]);

            // All pawns are on a single rook file ?
            if ((pawnFile == FileC.FILE_A || pawnFile == FileC.FILE_H)
                && (((pawns & ~Utils.file_bb_F(pawnFile))) == 0))
            {
                Square bishopSq = pos.pieceList[strongerSide][PieceTypeC.BISHOP][0];
                Square queeningSq = Utils.relative_square(strongerSide, Utils.make_square(pawnFile, RankC.RANK_8));
                Square kingSq = pos.king_square(weakerSide);

                if (Utils.opposite_colors(queeningSq, bishopSq)
                    && Math.Abs(Utils.file_of(kingSq) - pawnFile) <= 1)
                {
                    // The bishop has the wrong color, and the defending king is on the
                    // file of the pawn(s) or the adjacent file. Find the rank of the
                    // frontmost pawn.
                    Rank rank;
                    if (strongerSide == ColorC.WHITE)
                    {
                        for (rank = RankC.RANK_7; (((Utils.rank_bb_R(rank) & pawns)) == 0); rank--) { }
                        Debug.Assert(rank >= RankC.RANK_2 && rank <= RankC.RANK_7);
                    }
                    else
                    {
                        for (rank = RankC.RANK_2; (((Utils.rank_bb_R(rank) & pawns)) == 0); rank++) { }
                        rank = (rank ^ 7);  // HACK to get the relative rank
                        Debug.Assert(rank >= RankC.RANK_2 && rank <= RankC.RANK_7);
                    }
                    // If the defending king has distance 1 to the promotion square or
                    // is placed somewhere in front of the pawn, it's a draw.
                    if (Utils.square_distance(kingSq, queeningSq) <= 1
                        || Utils.relative_rank_CS(strongerSide, kingSq) >= rank)
                        return ScaleFactorC.SCALE_FACTOR_DRAW;
                }
            }
            return ScaleFactorC.SCALE_FACTOR_NONE;
        }
开发者ID:CVChrisWilson,项目名称:Portfish,代码行数:53,代码来源:Endgame.cs

示例10: Endgame_KBPPKB

        /// K, bishop and two pawns vs K and bishop. It detects a few basic draws with
        /// opposite-colored bishops.
        internal static ScaleFactor Endgame_KBPPKB(Color strongerSide, Position pos)
        {
            Color weakerSide = strongerSide ^ 1;

            Debug.Assert(pos.non_pawn_material(strongerSide) == Constants.BishopValueMidgame);
            Debug.Assert(pos.piece_count(strongerSide, PieceTypeC.BISHOP) == 1);
            Debug.Assert(pos.piece_count(strongerSide, PieceTypeC.PAWN) == 2);
            Debug.Assert(pos.non_pawn_material(weakerSide) == Constants.BishopValueMidgame);
            Debug.Assert(pos.piece_count(weakerSide, PieceTypeC.BISHOP) == 1);
            Debug.Assert(pos.piece_count(weakerSide, PieceTypeC.PAWN) == 0);

            Square wbsq = pos.pieceList[strongerSide][PieceTypeC.BISHOP][0];
            Square bbsq = pos.pieceList[weakerSide][PieceTypeC.BISHOP][0];

            if (!Utils.opposite_colors(wbsq, bbsq))
                return ScaleFactorC.SCALE_FACTOR_NONE;

            Square ksq = pos.king_square(weakerSide);
            Square psq1 = pos.pieceList[strongerSide][PieceTypeC.PAWN][0];
            Square psq2 = pos.pieceList[strongerSide][PieceTypeC.PAWN][1];
            Rank r1 = Utils.rank_of(psq1);
            Rank r2 = Utils.rank_of(psq2);
            Square blockSq1, blockSq2;

            if (Utils.relative_rank_CS(strongerSide, psq1) > Utils.relative_rank_CS(strongerSide, psq2))
            {
                blockSq1 = psq1 + Utils.pawn_push(strongerSide);
                blockSq2 = Utils.make_square(Utils.file_of(psq2), Utils.rank_of(psq1));
            }
            else
            {
                blockSq1 = psq2 + Utils.pawn_push(strongerSide);
                blockSq2 = Utils.make_square(Utils.file_of(psq1), Utils.rank_of(psq2));
            }

            switch (Utils.file_distance(psq1, psq2))
            {
                case 0:
                    // Both pawns are on the same file. Easy draw if defender firmly controls
                    // some square in the frontmost pawn's path.
                    if (Utils.file_of(ksq) == Utils.file_of(blockSq1)
                  && Utils.relative_rank_CS(strongerSide, ksq) >= Utils.relative_rank_CS(strongerSide, blockSq1)
                  && Utils.opposite_colors(ksq, wbsq))
                        return ScaleFactorC.SCALE_FACTOR_DRAW;
                    else
                        return ScaleFactorC.SCALE_FACTOR_NONE;

                case 1:
                    // Pawns on adjacent files. Draw if defender firmly controls the square
                    // in front of the frontmost pawn's path, and the square diagonally behind
                    // this square on the file of the other pawn.
                    if (ksq == blockSq1
                        && Utils.opposite_colors(ksq, wbsq)
                        && (bbsq == blockSq2
                            || (((pos.attacks_from_BISHOP(blockSq2) & pos.pieces_PTC(PieceTypeC.BISHOP, weakerSide))) != 0)
                            || Math.Abs(r1 - r2) >= 2))
                        return ScaleFactorC.SCALE_FACTOR_DRAW;

                    else if (ksq == blockSq2
                             && Utils.opposite_colors(ksq, wbsq)
                             && (bbsq == blockSq1
                                 || (((pos.attacks_from_BISHOP(blockSq1) & pos.pieces_PTC(PieceTypeC.BISHOP, weakerSide)))) != 0))
                        return ScaleFactorC.SCALE_FACTOR_DRAW;
                    else
                        return ScaleFactorC.SCALE_FACTOR_NONE;

                default:
                    // The pawns are not on the same file or adjacent files. No scaling.
                    return ScaleFactorC.SCALE_FACTOR_NONE;
            }
        }
开发者ID:CVChrisWilson,项目名称:Portfish,代码行数:73,代码来源:Endgame.cs

示例11: Endgame_KBPKB

        /// K, bishop and a pawn vs K and a bishop. There are two rules: If the defending
        /// king is somewhere along the path of the pawn, and the square of the king is
        /// not of the same color as the stronger side's bishop, it's a draw. If the two
        /// bishops have opposite color, it's almost always a draw.
        internal static ScaleFactor Endgame_KBPKB(Color strongerSide, Position pos)
        {
            Color weakerSide = strongerSide ^ 1;

            Debug.Assert(pos.non_pawn_material(strongerSide) == Constants.BishopValueMidgame);
            Debug.Assert(pos.piece_count(strongerSide, PieceTypeC.BISHOP) == 1);
            Debug.Assert(pos.piece_count(strongerSide, PieceTypeC.PAWN) == 1);
            Debug.Assert(pos.non_pawn_material(weakerSide) == Constants.BishopValueMidgame);
            Debug.Assert(pos.piece_count(weakerSide, PieceTypeC.BISHOP) == 1);
            Debug.Assert(pos.piece_count(weakerSide, PieceTypeC.PAWN) == 0);

            Square pawnSq = pos.pieceList[strongerSide][PieceTypeC.PAWN][0];
            Square strongerBishopSq = pos.pieceList[strongerSide][PieceTypeC.BISHOP][0];
            Square weakerBishopSq = pos.pieceList[weakerSide][PieceTypeC.BISHOP][0];
            Square weakerKingSq = pos.king_square(weakerSide);

            // Case 1: Defending king blocks the pawn, and cannot be driven away
            if (Utils.file_of(weakerKingSq) == Utils.file_of(pawnSq)
                && Utils.relative_rank_CS(strongerSide, pawnSq) < Utils.relative_rank_CS(strongerSide, weakerKingSq)
                && (Utils.opposite_colors(weakerKingSq, strongerBishopSq)
                    || Utils.relative_rank_CS(strongerSide, weakerKingSq) <= RankC.RANK_6))
                return ScaleFactorC.SCALE_FACTOR_DRAW;

            // Case 2: Opposite colored bishops
            if (Utils.opposite_colors(strongerBishopSq, weakerBishopSq))
            {
                // We assume that the position is drawn in the following three situations:
                //
                //   a. The pawn is on rank 5 or further back.
                //   b. The defending king is somewhere in the pawn's path.
                //   c. The defending bishop attacks some square along the pawn's path,
                //      and is at least three squares away from the pawn.
                //
                // These rules are probably not perfect, but in practice they work
                // reasonably well.

                if (Utils.relative_rank_CS(strongerSide, pawnSq) <= RankC.RANK_5)
                    return ScaleFactorC.SCALE_FACTOR_DRAW;
                else
                {
                    Bitboard path = Utils.forward_bb(strongerSide, pawnSq);

                    if ((path & pos.pieces_PTC(PieceTypeC.KING, weakerSide)) != 0)
                        return ScaleFactorC.SCALE_FACTOR_DRAW;

                    if (((pos.attacks_from_BISHOP(weakerBishopSq) & path) != 0)
                        && Utils.square_distance(weakerBishopSq, pawnSq) >= 3)
                        return ScaleFactorC.SCALE_FACTOR_DRAW;
                }
            }
            return ScaleFactorC.SCALE_FACTOR_NONE;
        }
开发者ID:CVChrisWilson,项目名称:Portfish,代码行数:56,代码来源:Endgame.cs

示例12: Endgame_KBPsK

        /// K, bishop and one or more pawns vs K. It checks for draws with rook pawns and
        /// a bishop of the wrong color. If such a draw is detected, SCALE_FACTOR_DRAW
        /// is returned. If not, the return value is SCALE_FACTOR_NONE, i.e. no scaling
        /// will be used.
        internal static int Endgame_KBPsK(int strongerSide, Position pos)
        {
            var weakerSide = strongerSide ^ 1;

            Debug.Assert(pos.non_pawn_material(strongerSide) == Constants.BishopValueMidgame);
            Debug.Assert(pos.piece_count(strongerSide, PieceTypeC.BISHOP) == 1);
            Debug.Assert(pos.piece_count(strongerSide, PieceTypeC.PAWN) >= 1);

            // No Debug.Assertions about the material of weakerSide, because we want draws to
            // be detected even when the weaker side has some pawns.

            var pawns = pos.pieces_PTC(PieceTypeC.PAWN, strongerSide);
            var pawnFile = Utils.file_of(pos.pieceList[strongerSide][PieceTypeC.PAWN][0]);

            // All pawns are on a single rook file ?
            if ((pawnFile == FileC.FILE_A || pawnFile == FileC.FILE_H) && (((pawns & ~Utils.file_bb_F(pawnFile))) == 0))
            {
                var bishopSq = pos.pieceList[strongerSide][PieceTypeC.BISHOP][0];
                var queeningSq = Utils.relative_square(strongerSide, Utils.make_square(pawnFile, RankC.RANK_8));
                var kingSq = pos.king_square(weakerSide);

                if (Utils.opposite_colors(queeningSq, bishopSq) && Math.Abs(Utils.file_of(kingSq) - pawnFile) <= 1)
                {
                    // The bishop has the wrong color, and the defending king is on the
                    // file of the pawn(s) or the adjacent file. Find the rank of the
                    // frontmost pawn.
                    int rank;
                    if (strongerSide == ColorC.WHITE)
                    {
                        for (rank = RankC.RANK_7; (((Utils.rank_bb_R(rank) & pawns)) == 0); rank--)
                        {
                        }
                        Debug.Assert(rank >= RankC.RANK_2 && rank <= RankC.RANK_7);
                    }
                    else
                    {
                        for (rank = RankC.RANK_2; (((Utils.rank_bb_R(rank) & pawns)) == 0); rank++)
                        {
                        }
                        rank = (rank ^ 7); // HACK to get the relative rank
                        Debug.Assert(rank >= RankC.RANK_2 && rank <= RankC.RANK_7);
                    }
                    // If the defending king has distance 1 to the promotion square or
                    // is placed somewhere in front of the pawn, it's a draw.
                    if (Utils.square_distance(kingSq, queeningSq) <= 1
                        || Utils.relative_rank_CS(strongerSide, kingSq) >= rank)
                    {
                        return ScaleFactorC.SCALE_FACTOR_DRAW;
                    }
                }
            }

            // All pawns on same B or G file? Then potential draw
            if ((pawnFile == FileC.FILE_B || pawnFile == FileC.FILE_G)
                  && (pos.pieces_PT(PieceTypeC.PAWN) & ~Utils.file_bb_F(pawnFile)) == 0
                  && pos.non_pawn_material(weakerSide) == 0
                  && pos.piece_count(weakerSide, PieceTypeC.PAWN) >= 1)
            {
                // Get weaker pawn closest to opponent's queening square
                Bitboard wkPawns = pos.pieces_PTC(PieceTypeC.PAWN, weakerSide);
                Square weakerPawnSq = strongerSide == ColorC.WHITE ? Utils.msb(wkPawns) : Utils.lsb(wkPawns);

                Square strongerKingSq = pos.king_square(strongerSide);
                Square weakerKingSq = pos.king_square(weakerSide);
                Square bishopSq = pos.pieceList[strongerSide][PieceTypeC.BISHOP][0];

                // Draw if weaker pawn is on rank 7, bishop can't attack the pawn, and
                // weaker king can stop opposing opponent's king from penetrating.
                if (Utils.relative_rank_CS(strongerSide, weakerPawnSq) == RankC.RANK_7
                    && Utils.opposite_colors(bishopSq, weakerPawnSq)
                    && Utils.square_distance(weakerPawnSq, weakerKingSq) <= Utils.square_distance(weakerPawnSq, strongerKingSq))
                    return ScaleFactorC.SCALE_FACTOR_DRAW;
            }

            return ScaleFactorC.SCALE_FACTOR_NONE;
        }
开发者ID:torfranz,项目名称:Portfish,代码行数:80,代码来源:Endgame.cs


注:本文中的Portfish.Position.pieces_PTC方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。