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


C# Position.piece_on方法代码示例

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


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

示例1: book_key

        // book_key() returns the PolyGlot hash key of the given position
        private static UInt64 book_key(Position pos)
        {
            UInt64 key = 0;
            Bitboard b = pos.occupied_squares;

            while (b != 0)
            {
                // Piece offset is at 64 * polyPiece where polyPiece is defined as:
                // BP = 0, WP = 1, BN = 2, WN = 3, ... BK = 10, WK = 11
                Square s = Utils.pop_1st_bit(ref b);
                Piece p = pos.piece_on(s);
                int polyPiece = 2 * (Utils.type_of(p) - 1) + (Utils.color_of(p) == ColorC.WHITE ? 1 : 0);
                key ^= PolyGlotRandoms[ZobPieceOffset + (64 * polyPiece + s)];
            }

            b = (ulong)pos.can_castle_CR(CastleRightC.ALL_CASTLES);

            while (b != 0)
                key ^= PolyGlotRandoms[ZobCastleOffset + Utils.pop_1st_bit(ref b)];

            if (pos.st.epSquare != SquareC.SQ_NONE)
                key ^= PolyGlotRandoms[ZobEnPassantOffset + Utils.file_of(pos.st.epSquare)];

            if (pos.sideToMove == ColorC.WHITE)
                key ^= PolyGlotRandoms[ZobTurnOffset + 0];

            return key;
        }
开发者ID:stevemulligan,项目名称:Portfish,代码行数:29,代码来源:Book.cs

示例2: 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

示例3: evaluate_pawns

        /// PawnTable::evaluate_pawns() evaluates each pawn of the given color
        internal static Score evaluate_pawns(Color Us, Position pos, Bitboard ourPawns, Bitboard theirPawns, PawnEntry e)
        {
            Color Them = (Us == ColorC.WHITE ? ColorC.BLACK : ColorC.WHITE);

            Bitboard b;
            Square s;
            File f;
            Rank r;
            bool passed, isolated, doubled, opposed, chain, backward, candidate;
            Score value = ScoreC.SCORE_ZERO;
            Square[] pl = pos.pieceList[Us][PieceTypeC.PAWN];
            int plPos = 0;

            // Loop through all pawns of the current color and score each pawn
            while ((s = pl[plPos++]) != SquareC.SQ_NONE)
            {
                Debug.Assert(pos.piece_on(s) == Utils.make_piece(Us, PieceTypeC.PAWN));

                f = (s & 7);
                r = (s >> 3);

                // This file cannot be half open
                if (Us == ColorC.WHITE)
                {
                    e.halfOpenFilesWHITE &= ~(1 << f);
                }
                else
                {
                    e.halfOpenFilesBLACK &= ~(1 << f);
                }

                // Our rank plus previous one. Used for chain detection
                b = Utils.RankBB[r] | Utils.RankBB[Us == ColorC.WHITE ? r - 1 : r + 1];

                // Flag the pawn as passed, isolated, doubled or member of a pawn
                // chain (but not the backward one).
                chain = (ourPawns & Utils.AdjacentFilesBB[f] & b) != 0;
                isolated = (ourPawns & Utils.AdjacentFilesBB[f]) == 0;
                doubled = (ourPawns & Utils.ForwardBB[Us][s]) != 0;
                opposed = (theirPawns & Utils.ForwardBB[Us][s]) != 0;
                passed = (theirPawns & Utils.PassedPawnMask[Us][s]) == 0;

                // Test for backward pawn
                backward = false;

                // If the pawn is passed, isolated, or member of a pawn chain it cannot
                // be backward. If there are friendly pawns behind on adjacent files
                // or if can capture an enemy pawn it cannot be backward either.
                if (!(passed | isolated | chain)
                    && (((ourPawns & Utils.AttackSpanMask[Them][s])) == 0)
                    && ((((Utils.StepAttacksBB[((Us << 3) | PieceTypeC.PAWN)][s]) & theirPawns)) == 0))
                {
                    // We now know that there are no friendly pawns beside or behind this
                    // pawn on adjacent files. We now check whether the pawn is
                    // backward by looking in the forward direction on the adjacent
                    // files, and seeing whether we meet a friendly or an enemy pawn first.
                    b = Utils.StepAttacksBB[((Us << 3) | PieceTypeC.PAWN)][s];

                    // Note that we are sure to find something because pawn is not passed
                    // nor isolated, so loop is potentially infinite, but it isn't.
                    while ((b & (ourPawns | theirPawns)) == 0)
                    {
                        if (Us == ColorC.WHITE) { b <<= 8; } else { b >>= 8; }
                    }

                    // The friendly pawn needs to be at least two ranks closer than the
                    // enemy pawn in order to help the potentially backward pawn advance.
                    backward = (((b | (Us == ColorC.WHITE ? b << 8 : b >> 8)) & theirPawns) != 0);
                }

                Debug.Assert(opposed | passed | (((Utils.AttackSpanMask[Us][s] & theirPawns)) != 0));

                // A not passed pawn is a candidate to become passed if it is free to
                // advance and if the number of friendly pawns beside or behind this
                // pawn on adjacent files is higher or equal than the number of
                // enemy pawns in the forward direction on the adjacent files.
                candidate = !(opposed | passed | backward | isolated)
                           && (b = Utils.AttackSpanMask[Them][s + (Us == ColorC.WHITE ? SquareC.DELTA_N : SquareC.DELTA_S)] & ourPawns) != 0
                           && Bitcount.popcount_1s_Max15(b) >= Bitcount.popcount_1s_Max15(Utils.AttackSpanMask[Us][s] & theirPawns);

                // Passed pawns will be properly scored in evaluation because we need
                // full attack info to evaluate passed pawns. Only the frontmost passed
                // pawn on each file is considered a true passed pawn.
                if (passed && !doubled)
                {
                    if (Us == ColorC.WHITE)
                    {
                        e.passedPawnsWHITE |= Utils.SquareBB[s];
                    }
                    else
                    {
                        e.passedPawnsBLACK |= Utils.SquareBB[s];
                    }
                }

                // Score this pawn
                if (isolated)
                    value -= IsolatedPawnPenalty[opposed ? 1 : 0][f];

//.........这里部分代码省略.........
开发者ID:CVChrisWilson,项目名称:Portfish,代码行数:101,代码来源:PawnInfo.cs

示例4: connected_threat

        // connected_threat() tests whether it is safe to forward prune a move or if
        // is somehow connected to the threat move returned by null search.
        static bool connected_threat(Position pos, Move m, Move threat)
        {
            Debug.Assert(Utils.is_ok_M(m));
            Debug.Assert(Utils.is_ok_M(threat));
            Debug.Assert(!pos.is_capture_or_promotion(m));
            Debug.Assert(!pos.is_passed_pawn_push(m));

            Square mfrom, mto, tfrom, tto;

            mfrom = Utils.from_sq(m);
            mto = Utils.to_sq(m);
            tfrom = Utils.from_sq(threat);
            tto = Utils.to_sq(threat);

            // Case 1: Don't prune moves which move the threatened piece
            if (mfrom == tto)
                return true;

            // Case 2: If the threatened piece has value less than or equal to the
            // value of the threatening piece, don't prune moves which defend it.
            if (pos.is_capture(threat)
                && (Position.PieceValueMidgame[pos.piece_on(tfrom)] >= Position.PieceValueMidgame[pos.piece_on(tto)]
                    || Utils.type_of(pos.piece_on(tfrom)) == PieceTypeC.KING)
                && pos.move_attacks_square(m, tto))
                return true;

            // Case 3: If the moving piece in the threatened move is a slider, don't
            // prune safe moves which block its ray.
            if (piece_is_slider(pos.piece_on(tfrom))
                && (Utils.bit_is_set(Utils.between_bb(tfrom, tto), mto) != 0)
                && pos.see(m, true) >= 0)
                return true;

            return false;
        }
开发者ID:stevemulligan,项目名称:Portfish,代码行数:37,代码来源:Search.cs

示例5: search


//.........这里部分代码省略.........
                    ss[ssPos].killers1 = ss[ssPos].killers0;
                    ss[ssPos].killers0 = ttMove;
                }

                MovesSearchedBroker.Free();
                return ttValue;
            }

            // Step 5. Evaluate the position statically and update parent's gain statistics
            if (inCheck)
                ss[ssPos].eval = ss[ssPos].evalMargin = ValueC.VALUE_NONE;
            else if (tteHasValue)
            {
                Debug.Assert(tte.static_value() != ValueC.VALUE_NONE);
                ss[ssPos].eval = tte.static_value();
                ss[ssPos].evalMargin = tte.static_value_margin();
                refinedValue = refine_eval(tte, ttValue, ss[ssPos].eval);
            }
            else
            {
                refinedValue = ss[ssPos].eval = Evaluate.do_evaluate(false, pos, ref ss[ssPos].evalMargin);
                TT.store(posKey, ValueC.VALUE_NONE, Bound.BOUND_NONE, DepthC.DEPTH_NONE, MoveC.MOVE_NONE, ss[ssPos].eval, ss[ssPos].evalMargin);
            }

            // Update gain for the parent non-capture move given the static position
            // evaluation before and after the move.
            if ((move = ss[ssPos - 1].currentMove) != MoveC.MOVE_NULL
                && ss[ssPos - 1].eval != ValueC.VALUE_NONE
                && ss[ssPos].eval != ValueC.VALUE_NONE
                && (pos.captured_piece_type() == 0)
                && !Utils.is_special(move))
            {
                Square to = Utils.to_sq(move);
                H.update_gain(pos.piece_on(to), to, -ss[ssPos - 1].eval - ss[ssPos].eval);
            }

            // Step 6. Razoring (is omitted in PV nodes)
            if (!PvNode && !inCheck
                && depth < RazorDepth
                && refinedValue + razor_margin(depth) < beta
                && ttMove == MoveC.MOVE_NONE
                && Math.Abs(beta) < ValueC.VALUE_MATE_IN_MAX_PLY
                && !pos.pawn_on_7th(pos.sideToMove))
            {
                Value rbeta = beta - razor_margin(depth);
                Value v = qsearch(NodeTypeC.NonPV, pos, ss, ssPos, rbeta - 1, rbeta, DepthC.DEPTH_ZERO);
                if (v < rbeta)
                {
                    // Logically we should return (v + razor_margin(depth)), but
                    // surprisingly this did slightly weaker in tests.
                    MovesSearchedBroker.Free();
                    return v;
                }
            }

            // Step 7. Static null move pruning (is omitted in PV nodes)
            // We're betting that the opponent doesn't have a move that will reduce
            // the score by more than futility_margin(depth) if we do a null move.
            if (!PvNode && !inCheck
                && (ss[ssPos].skipNullMove == 0)
                && depth < RazorDepth
                && Math.Abs(beta) < ValueC.VALUE_MATE_IN_MAX_PLY
                && refinedValue - futility_margin(depth, 0) >= beta
                && (pos.non_pawn_material(pos.sideToMove) != 0))
            {
                MovesSearchedBroker.Free();
开发者ID:stevemulligan,项目名称:Portfish,代码行数:67,代码来源:Search.cs

示例6: check_is_dangerous

        // check_is_dangerous() tests if a checking move can be pruned in qsearch().
        // bestValue is updated only when returning false because in that case move
        // will be pruned.
        static bool check_is_dangerous(Position pos, Move move, Value futilityBase, Value beta)
        {
            Bitboard b, occ, oldAtt, newAtt, kingAtt;
            Square from, to, ksq;
            Piece pc;
            Color them;

            from = Utils.from_sq(move);
            to = Utils.to_sq(move);
            them = Utils.flip_C(pos.sideToMove);
            ksq = pos.king_square(them);
            kingAtt = Position.attacks_from_KING(ksq);
            pc = pos.piece_moved(move);

            occ = pos.occupied_squares ^ Utils.SquareBB[from] ^ Utils.SquareBB[ksq];
            oldAtt = Position.attacks_from(pc, from, occ);
            newAtt = Position.attacks_from(pc, to, occ);

            // Rule 1. Checks which give opponent's king at most one escape square are dangerous
            b = kingAtt & ~pos.pieces_C(them) & ~newAtt & ~(1UL << to);

            if ((b & (b - 1)) == 0) // Catches also !b
                return true;

            // Rule 2. Queen contact check is very dangerous
            if (Utils.type_of(pc) == PieceTypeC.QUEEN
                && (Utils.bit_is_set(kingAtt, to) != 0))
                return true;

            // Rule 3. Creating new double threats with checks
            b = pos.pieces_C(them) & newAtt & ~oldAtt & ~(1UL << ksq);

            while (b != 0)
            {
                // Note that here we generate illegal "double move"!
                if (futilityBase + Position.PieceValueEndgame[pos.piece_on(Utils.pop_1st_bit(ref b))] >= beta)
                    return true;
            }
            return false;
        }
开发者ID:stevemulligan,项目名称:Portfish,代码行数:43,代码来源:Search.cs

示例7: connected_moves

        // connected_moves() tests whether two moves are 'connected' in the sense
        // that the first move somehow made the second move possible (for instance
        // if the moving piece is the same in both moves). The first move is assumed
        // to be the move that was made to reach the current position, while the
        // second move is assumed to be a move from the current position.
        internal static bool connected_moves(Position pos, Move m1, Move m2)
        {
            Square f1, t1, f2, t2;
            Piece p1, p2;
            Square ksq;

            Debug.Assert(Utils.is_ok_M(m1));
            Debug.Assert(Utils.is_ok_M(m2));

            // Case 1: The moving piece is the same in both moves
            f2 = Utils.from_sq(m2);
            t1 = Utils.to_sq(m1);
            if (f2 == t1)
                return true;

            // Case 2: The destination square for m2 was vacated by m1
            t2 = Utils.to_sq(m2);
            f1 = Utils.from_sq(m1);
            if (t2 == f1)
                return true;

            // Case 3: Moving through the vacated square
            p2 = pos.piece_on(f2);
            if (piece_is_slider(p2)
                && (Utils.bit_is_set(Utils.between_bb(f2, t2), f1) != 0))
                return true;

            // Case 4: The destination square for m2 is defended by the moving piece in m1
            p1 = pos.piece_on(t1);
            if ((Utils.bit_is_set(pos.attacks_from_PS(p1, t1), t2)) != 0)
                return true;

            // Case 5: Discovered check, checking piece is the piece moved in m1
            ksq = pos.king_square(pos.sideToMove);
            if (
                piece_is_slider(p1)
                &&
                (Utils.bit_is_set(Utils.between_bb(t1, ksq), f2) != 0)
                &&
                (Utils.bit_is_set(Position.attacks_from(p1, t1, Utils.xor_bit(pos.occupied_squares, f2)), ksq) != 0)
                )
                return true;

            return false;
        }
开发者ID:stevemulligan,项目名称:Portfish,代码行数:50,代码来源:Search.cs

示例8: generate_quiet_check

        internal static void generate_quiet_check(Position pos, MoveStack[] ms, ref int mpos)
        {
            /// generate<MV_NON_CAPTURE_CHECK> generates all pseudo-legal non-captures and knight
            /// underpromotions that give check. Returns a pointer to the end of the move list.
            Debug.Assert(!pos.in_check());

            var ci = CheckInfoBroker.GetObject();
            ci.CreateCheckInfo(pos);
            var target = ~pos.occupied_squares;
            var dc = ci.dcCandidates;

            while (dc != 0)
            {
                var from = Utils.pop_lsb(ref dc);
                var pt = Utils.type_of(pos.piece_on(from));

                if (pt == PieceTypeC.PAWN)
                {
                    continue; // Will be generated together with direct checks
                }

                var b = pos.attacks_from_PTS(pt, from) & ~pos.occupied_squares;

                if (pt == PieceTypeC.KING)
                {
                    b &= ~Utils.PseudoAttacks[PieceTypeC.QUEEN][ci.ksq];
                }

                while (b != 0)
                {
                    ms[mpos++].move = Utils.make_move(from, Utils.pop_lsb(ref b));
                }
            }

            generate_all(GenType.QUIET_CHECKS, pos, ms, ref mpos, pos.sideToMove, target, ci);

            CheckInfoBroker.Free();
        }
开发者ID:torfranz,项目名称:Portfish,代码行数:38,代码来源:Movegen.cs

示例9: evaluate_pieces_of_color


//.........这里部分代码省略.........
                            }
                        }
                        score += ((bonus << 16) + bonus); // Utils.make_score(bonus, bonus);

                        #endregion
                    }

                    if ((Piece == PieceTypeC.ROOK || Piece == PieceTypeC.QUEEN) && Utils.relative_rank_CS(Us, s) >= RankC.RANK_5)
                    {
                        // Major piece on 7th rank
                        if (Utils.relative_rank_CS(Us, s) == RankC.RANK_7
                            && Utils.relative_rank_CS(Us, pos.king_square(Them)) == RankC.RANK_8)
                            score += (Piece == PieceTypeC.ROOK ? RookOn7thBonus : QueenOn7thBonus);

                        // Major piece attacking pawns on the same rank
                        Bitboard pawns = pos.pieces_PTC(PieceTypeC.PAWN, Them) & Utils.rank_bb_S(s);
                        if (pawns != 0)
                        {
                            score += (Piece == PieceTypeC.ROOK ? RookOnPawnBonus : QueenOnPawnBonus) * Bitcount.popcount_1s_Max15(pawns);
                        }
                    }

                    // Special extra evaluation for bishops
                    if (pos.chess960 && (Piece == PieceTypeC.BISHOP))
                    {
                        // An important Chess960 pattern: A cornered bishop blocked by
                        // a friendly pawn diagonally in front of it is a very serious
                        // problem, especially when that pawn is also blocked.
                        if (s == Utils.relative_square(Us, SquareC.SQ_A1)
                            || s == Utils.relative_square(Us, SquareC.SQ_H1))
                        {
                            var d = Utils.pawn_push(Us)
                                    + (Utils.file_of(s) == FileC.FILE_A ? SquareC.DELTA_E : SquareC.DELTA_W);
                            if (pos.piece_on(s + d) == Utils.make_piece(Us, PieceTypeC.PAWN))
                            {
                                if (!pos.is_empty(s + d + Utils.pawn_push(Us)))
                                {
                                    score -= 2 * TrappedBishopA1H1Penalty;
                                }
                                else if (pos.piece_on(s + 2 * d) == Utils.make_piece(Us, PieceTypeC.PAWN))
                                {
                                    score -= TrappedBishopA1H1Penalty;
                                }
                                else
                                {
                                    score -= TrappedBishopA1H1Penalty / 2;
                                }
                            }
                        }
                    }

                    // Special extra evaluation for rooks
                    if (Piece == PieceTypeC.ROOK)
                    {
                        // Open and half-open files
                        f = (s & 7);

                        var halfOpenUs = ((Us == ColorC.WHITE)
                                              ? (ei.pi.halfOpenFilesWHITE & (1 << f))
                                              : (ei.pi.halfOpenFilesBLACK & (1 << f))) != 0;

                        if (halfOpenUs)
                        {
                            if (((Them == ColorC.WHITE)
                                     ? (ei.pi.halfOpenFilesWHITE & (1 << f))
                                     : (ei.pi.halfOpenFilesBLACK & (1 << f))) != 0)
开发者ID:torfranz,项目名称:Portfish,代码行数:67,代码来源:Evaluate.cs

示例10: search


//.........这里部分代码省略.........
                {
                    eval = ss[ssPos].staticEval = Evaluate.do_evaluate(false, pos, ref ss[ssPos].evalMargin);
                }

                // Can ttValue be used as a better position evaluation?
                if (ttValue != ValueC.VALUE_NONE)
                {
                    if ((((tte.type() & Bound.BOUND_LOWER) != 0) && ttValue > eval)
                        || (((tte.type() & Bound.BOUND_UPPER) != 0) && ttValue < eval))
                    {
                        eval = ttValue;
                    }
                }
            }
            else
            {
                eval = ss[ssPos].staticEval = Evaluate.do_evaluate(false, pos, ref ss[ssPos].evalMargin);
                TT.store(
                    posKey,
                    ValueC.VALUE_NONE,
                    Bound.BOUND_NONE,
                    DepthC.DEPTH_NONE,
                    MoveC.MOVE_NONE,
                    ss[ssPos].staticEval,
                    ss[ssPos].evalMargin);
            }

            // Update gain for the parentSplitPoint non-capture move given the static position
            // evaluation before and after the move.
            if ((move = ss[ssPos - 1].currentMove) != MoveC.MOVE_NULL && ss[ssPos - 1].staticEval != ValueC.VALUE_NONE
                && ss[ssPos].staticEval != ValueC.VALUE_NONE && (pos.captured_piece_type() == 0) && Utils.type_of_move(move) == MoveTypeC.NORMAL)
            {
                var to = Utils.to_sq(move);
                H.update_gain(pos.piece_on(to), to, -ss[ssPos - 1].staticEval - ss[ssPos].staticEval);
            }

            // Step 6. Razoring (is omitted in PV nodes)
            if (!PvNode && !inCheck && depth < 4 * DepthC.ONE_PLY && eval + razor_margin(depth) < beta
                && ttMove == MoveC.MOVE_NONE && Math.Abs(beta) < ValueC.VALUE_MATE_IN_MAX_PLY
                && !pos.pawn_on_7th(pos.sideToMove))
            {
                var rbeta = beta - razor_margin(depth);
                var v = qsearch(NodeTypeC.NonPV, false, pos, ss, ssPos, rbeta - 1, rbeta, DepthC.DEPTH_ZERO);
                if (v < rbeta)
                {
                    // Logically we should return (v + razor_margin(depth)), but
                    // surprisingly this did slightly weaker in tests.
                    MovesSearchedBroker.Free();
                    return v;
                }
            }

            // Step 7. Static null move pruning (is omitted in PV nodes)
            // We're betting that the opponent doesn't have a move that will reduce
            // the score by more than futility_margin(depth) if we do a null move.
            if (!PvNode && !inCheck && (ss[ssPos].skipNullMove == 0) && depth < 4 * DepthC.ONE_PLY
                && Math.Abs(beta) < ValueC.VALUE_MATE_IN_MAX_PLY && eval - FutilityMargins[depth][0] >= beta
                && (pos.non_pawn_material(pos.sideToMove) != 0))
            {
                MovesSearchedBroker.Free();
                return eval - FutilityMargins[depth][0];
            }

            // Step 8. Null move search with verification search (is omitted in PV nodes)
            if (!PvNode && !inCheck && (ss[ssPos].skipNullMove == 0) && depth > DepthC.ONE_PLY && eval >= beta
                && Math.Abs(beta) < ValueC.VALUE_MATE_IN_MAX_PLY && (pos.non_pawn_material(pos.sideToMove) != 0))
开发者ID:torfranz,项目名称:Portfish,代码行数:67,代码来源:Search.cs

示例11: generate_evasion

        internal static void generate_evasion(Position pos, MoveStack[] ms, ref int mpos)
        {
            /// generate<EVASIONS> generates all pseudo-legal check evasions when the side
            /// to move is in check. Returns a pointer to the end of the move list.
            Debug.Assert(pos.in_check());

            ulong b;
            int from, checksq;
            var checkersCnt = 0;
            var us = pos.sideToMove;
            var ksq = pos.king_square(us);
            ulong sliderAttacks = 0;
            var checkers = pos.st.checkersBB;

            Debug.Assert(checkers != 0);

            // Find squares attacked by slider checkers, we will remove them from the king
            // evasions so to skip known illegal moves avoiding useless legality check later.
            b = checkers;
            do
            {
                checkersCnt++;
                checksq = Utils.pop_lsb(ref b);

                Debug.Assert(Utils.color_of(pos.piece_on(checksq)) == Utils.flip_C(us));

                switch (Utils.type_of(pos.piece_on(checksq)))
                {
                    case PieceTypeC.BISHOP:
                        sliderAttacks |= Utils.PseudoAttacks[PieceTypeC.BISHOP][checksq];
                        break;
                    case PieceTypeC.ROOK:
                        sliderAttacks |= Utils.PseudoAttacks[PieceTypeC.ROOK][checksq];
                        break;
                    case PieceTypeC.QUEEN:
                        // If queen and king are far or not on a diagonal line we can safely
                        // remove all the squares attacked in the other direction becuase are
                        // not reachable by the king anyway.
                        if ((Utils.between_bb(ksq, checksq) != 0)
                            || ((Utils.bit_is_set(Utils.PseudoAttacks[PieceTypeC.BISHOP][checksq], ksq)) == 0))
                        {
                            sliderAttacks |= Utils.PseudoAttacks[PieceTypeC.QUEEN][checksq];
                        }

                        // Otherwise we need to use real rook attacks to check if king is safe
                        // to move in the other direction. For example: king in B2, queen in A1
                        // a knight in B1, and we can safely move to C1.
                        else
                        {
                            sliderAttacks |= Utils.PseudoAttacks[PieceTypeC.BISHOP][checksq]
                                             | pos.attacks_from_ROOK(checksq);
                        }
                        break;
                    default:
                        break;
                }
            }
            while (b != 0);

            // Generate evasions for king, capture and non capture moves
            b = Position.attacks_from_KING(ksq) & ~pos.pieces_C(us) & ~sliderAttacks;
            from = ksq;
            while (b != 0)
            {
                ms[mpos++].move = Utils.make_move(from, Utils.pop_lsb(ref b));
            }

            // Generate evasions for other pieces only if not under a double check
            if (checkersCnt > 1)
            {
                return;
            }

            // Blocking evasions or captures of the checking piece
            var target = Utils.between_bb(checksq, ksq) | checkers;

            generate_all(GenType.EVASIONS, pos, ms, ref mpos, us, target, null);
        }
开发者ID:torfranz,项目名称:Portfish,代码行数:78,代码来源:Movegen.cs

示例12: refutes

        // refutes() tests whether a 'first' move is able to defend against a 'second'
        // opponent's move. In this case will not be pruned. Normally the second move
        // is the threat (the best move returned from a null search that fails low).
        private static bool refutes(Position pos, int move, int threat)
        {
            Debug.Assert(Utils.is_ok_M(move));
            Debug.Assert(Utils.is_ok_M(threat));
            
            Square mfrom = Utils.from_sq(move);
            Square mto = Utils.to_sq(move);
            Square tfrom = Utils.from_sq(threat);
            Square tto = Utils.to_sq(threat);

            // Don't prune moves of the threatened piece
            if (mfrom == tto)
            {
                return true;
            }

            // If the threatened piece has value less than or equal to the value of the
            // threat piece, don't prune moves which defend it.
            if (pos.is_capture(threat)
                && (Position.PieceValue[PhaseC.MG][pos.piece_on(tfrom)] >= Position.PieceValue[PhaseC.MG][pos.piece_on(tto)]
                    || Utils.type_of(pos.piece_on(tfrom)) == PieceTypeC.KING))
            {
                // Update occupancy as if the piece and the threat are moving
                var occ = Utils.xor_bit(Utils.xor_bit(Utils.xor_bit(pos.occupied_squares, mfrom), mto), tfrom);
                Piece piece = pos.piece_on(mfrom);

                // The piece moved in 'to' attacks the square 's' ?
                if (Utils.bit_is_set(Position.attacks_from(piece, mto, occ), tto) != 0)
                {
                    return true;
                }

                // Scan for possible X-ray attackers behind the moved piece
                var xray = (Utils.rook_attacks_bb(tto, occ)
                        & pos.pieces(PieceTypeC.ROOK, PieceTypeC.QUEEN, Utils.color_of(piece)))
                        | (Utils.bishop_attacks_bb(tto, occ)
                            & pos.pieces(PieceTypeC.BISHOP, PieceTypeC.QUEEN, Utils.color_of(piece)));

                // Verify attackers are triggered by our move and not already existing
                if ((xray != 0) && ((xray ^ (xray & pos.attacks_from_QUEEN(tto))) != 0))
                {
                    return true;
                }
            }

            // Don't prune safe moves which block the threat path
            if ((Utils.bit_is_set(Utils.between_bb(tfrom, tto), mto) != 0) && pos.see(move, true) >= 0)
            {
                return true;
            }

            return false;
        }
开发者ID:torfranz,项目名称:Portfish,代码行数:56,代码来源:Search.cs

示例13: allows

        // allows() tests whether the 'first' move at previous ply somehow makes the
        // 'second' move possible, for instance if the moving piece is the same in
        // both moves. Normally the second move is the threat (the best move returned
        // from a null search that fails low).
        internal static bool allows(Position pos, int first, int second)
        {
            Debug.Assert(Utils.is_ok_M(first));
            Debug.Assert(Utils.is_ok_M(second));
            Debug.Assert(Utils.color_of(pos.piece_on(Utils.from_sq(second))) == 1 - pos.sideToMove);

            Square m1to = Utils.to_sq(first);
            Square m1from = Utils.from_sq(first);
            Square m2to = Utils.to_sq(second);
            Square m2from = Utils.from_sq(second);


            // The piece is the same or second's destination was vacated by the first move
            if (m1to == m2from || m2to == m1from)
            {
                return true;
            }

            // Second one moves through the square vacated by first one
            if (Utils.bit_is_set(Utils.between_bb(m2from, m2to), m1from) != 0)
            {
                return true;
            }

            // Second's destination is defended by the first move's piece
            Bitboard m1att = Position.attacks_from(pos.piece_on(m1to), m1to, pos.occupied_squares ^ (ulong)m2from);
            if (Utils.bit_is_set(m1att, m2to) != 0)
            {
                return true;
            }

            // Second move gives a discovered check through the first's checking piece
            if (Utils.bit_is_set(m1att, pos.king_square(pos.sideToMove)) != 0 &&
                Utils.bit_is_set(Utils.between_bb(m1to, pos.king_square(pos.sideToMove)), m2from) != 0) // TODO: removing condition asserts below
            {
                Debug.Assert(Utils.bit_is_set(Utils.between_bb(m1to, pos.king_square(pos.sideToMove)), m2from) != 0);
                return true;
            }

            return false;
        }
开发者ID:torfranz,项目名称:Portfish,代码行数:45,代码来源:Search.cs

示例14: check_is_dangerous

        // check_is_dangerous() tests if a checking move can be pruned in qsearch().
        // bestValue is updated only when returning false because in that case move
        // will be pruned.
        private static bool check_is_dangerous(Position pos, int move, int futilityBase, int beta)
        {
            //ulong b, occ, oldAtt, newAtt, kingAtt;
            //int from, to, ksq;
            //int pc;
            //int them;

            //from = Utils.from_sq(move);
            //to = Utils.to_sq(move);
            //them = Utils.flip_C(pos.sideToMove);
            //ksq = pos.king_square(them);
            //kingAtt = Position.attacks_from_KING(ksq);
            //pc = pos.piece_moved(move);

            //occ = pos.occupied_squares ^ Utils.SquareBB[from] ^ Utils.SquareBB[ksq];
            //oldAtt = Position.attacks_from(pc, from, occ);
            //newAtt = Position.attacks_from(pc, to, occ);

            //// Rule 1. Checks which give opponent's king at most one escape square are dangerous
            //b = kingAtt & ~pos.pieces_C(them) & ~newAtt & ~(1UL << to);

            //if ((b & (b - 1)) == 0) // Catches also !b
            Piece pc = pos.piece_moved(move);
            Square from = Utils.from_sq(move);
            Square to = Utils.to_sq(move);
            Color them = pos.sideToMove ^ 1;
            Square ksq = pos.king_square(them);
            Bitboard enemies = pos.pieces_C(them);
            Bitboard kingAtt = Position.attacks_from_KING(ksq);
            Bitboard occ = pos.occupied_squares ^ Utils.SquareBB[from] ^ Utils.SquareBB[ksq];
            Bitboard oldAtt = Position.attacks_from(pc, from, occ);
            Bitboard newAtt = Position.attacks_from(pc, to, occ);

            // Checks which give opponent's king at most one escape square are dangerous
            if (!Utils.more_than_one(kingAtt & ~(enemies | newAtt | (ulong)to)))
            {
                return true;
            }

            // Queen contact check is very dangerous
            if (Utils.type_of(pc) == PieceTypeC.QUEEN && (Utils.bit_is_set(kingAtt, to) != 0))
            {
                return true;
            }

            // Creating new double threats with checks is dangerous
            Bitboard b = (enemies ^ (ulong)ksq) & newAtt & ~oldAtt;
            while (b != 0)
            {
                // Note that here we generate illegal "double move"!
                if (futilityBase + Position.PieceValue[PhaseC.EG][pos.piece_on(Utils.pop_lsb(ref b))] >= beta)
                {
                    return true;
                }
            }
            return false;
        }
开发者ID:torfranz,项目名称:Portfish,代码行数:60,代码来源:Search.cs

示例15: generate_quiet_check

        internal static void generate_quiet_check(Position pos, MoveStack[] ms, ref int mpos)
        {
            /// generate<MV_NON_CAPTURE_CHECK> generates all pseudo-legal non-captures and knight
            /// underpromotions that give check. Returns a pointer to the end of the move list.
            Debug.Assert(!pos.in_check());

            Color us = pos.sideToMove;
            CheckInfo ci = CheckInfoBroker.GetObject();
            ci.CreateCheckInfo(pos);
            Bitboard dc = ci.dcCandidates;

            while (dc != 0)
            {
                Square from = Utils.pop_1st_bit(ref dc);
                PieceType pt = Utils.type_of(pos.piece_on(from));

                if (pt == PieceTypeC.PAWN)
                    continue; // Will be generated together with direct checks

                Bitboard b = pos.attacks_from_PTS(pt, from) & ~pos.occupied_squares;

                if (pt == PieceTypeC.KING)
                    b &= ~Utils.PseudoAttacks[PieceTypeC.QUEEN][ci.ksq];

                while (b != 0) { ms[mpos++].move = Utils.make_move(from, Utils.pop_1st_bit(ref b)); }
            }

            generate_pawn_moves(us, MoveType.MV_QUIET_CHECK, pos, ms, ref mpos, ci.dcCandidates, ci.ksq);

            generate_direct_checks(PieceTypeC.KNIGHT, pos, ms, ref mpos, us, ci);
            generate_direct_checks(PieceTypeC.BISHOP, pos, ms, ref mpos, us, ci);
            generate_direct_checks(PieceTypeC.ROOK, pos, ms, ref mpos, us, ci);
            generate_direct_checks(PieceTypeC.QUEEN, pos, ms, ref mpos, us, ci);

            if (pos.can_castle_C(us) != 0)
            {
                generate_castle(CastlingSideC.KING_SIDE, true, pos, ms, ref mpos, us);
                generate_castle(CastlingSideC.QUEEN_SIDE, true, pos, ms, ref mpos, us);
            }

            CheckInfoBroker.Free();
        }
开发者ID:CVChrisWilson,项目名称:Portfish,代码行数:42,代码来源:Movegen.cs


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