本文整理汇总了C#中Position.pieces_CtPt方法的典型用法代码示例。如果您正苦于以下问题:C# Position.pieces_CtPt方法的具体用法?C# Position.pieces_CtPt怎么用?C# Position.pieces_CtPt使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Position
的用法示例。
在下文中一共展示了Position.pieces_CtPt方法的8个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: GetScaleFactor
internal override ScaleFactor GetScaleFactor(Position pos)
{
Debug.Assert(verify_material(pos, strongSide, Value.BishopValueMg, 2));
Debug.Assert(verify_material(pos, weakSide, Value.BishopValueMg, 0));
var wbsq = pos.square(PieceType.BISHOP, strongSide);
var bbsq = pos.square(PieceType.BISHOP, weakSide);
if (!Square.opposite_colors(wbsq, bbsq))
{
return ScaleFactor.SCALE_FACTOR_NONE;
}
var ksq = pos.square(PieceType.KING, weakSide);
var psq1 = pos.square(PieceType.PAWN, strongSide, 0);
var psq2 = pos.square(PieceType.PAWN, strongSide, 1);
var r1 = Square.rank_of(psq1);
var r2 = Square.rank_of(psq2);
SquareT blockSq1, blockSq2;
if (Rank.relative_rank_CtSt(strongSide, psq1) > Rank.relative_rank_CtSt(strongSide, psq2))
{
blockSq1 = psq1 + Square.pawn_push(strongSide);
blockSq2 = Square.make_square(Square.file_of(psq2), Square.rank_of(psq1));
}
else
{
blockSq1 = psq2 + Square.pawn_push(strongSide);
blockSq2 = Square.make_square(Square.file_of(psq1), Square.rank_of(psq2));
}
switch (Utils.distance_File(psq1, psq2))
{
case 0:
// Both pawns are on the same file. It's an easy draw if the defender firmly
// controls some square in the frontmost pawn's path.
if (Square.file_of(ksq) == Square.file_of(blockSq1)
&& Rank.relative_rank_CtSt(strongSide, ksq) >= Rank.relative_rank_CtSt(strongSide, blockSq1)
&& Square.opposite_colors(ksq, wbsq))
{
return ScaleFactor.SCALE_FACTOR_DRAW;
}
return ScaleFactor.SCALE_FACTOR_NONE;
case 1:
// Pawns on adjacent files. It's a draw if the 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 && Square.opposite_colors(ksq, wbsq)
&& (bbsq == blockSq2
|| (pos.attacks_from_PtS(PieceType.BISHOP, blockSq2) & pos.pieces_CtPt(weakSide, PieceType.BISHOP))!=0
|| Utils.distance_Rank(r1, r2) >= 2))
{
return ScaleFactor.SCALE_FACTOR_DRAW;
}
if (ksq == blockSq2 && Square.opposite_colors(ksq, wbsq)
&& (bbsq == blockSq1
|| (pos.attacks_from_PtS(PieceType.BISHOP, blockSq1) & pos.pieces_CtPt(weakSide, PieceType.BISHOP))!=0))
{
return ScaleFactor.SCALE_FACTOR_DRAW;
}
return ScaleFactor.SCALE_FACTOR_NONE;
default:
// The pawns are not on the same file or adjacent files. No scaling.
return ScaleFactor.SCALE_FACTOR_NONE;
}
}
示例2: evaluate
internal static ScoreT evaluate(ColorT Us, Position pos, Entry e)
{
var Them = (Us == Color.WHITE ? Color.BLACK : Color.WHITE);
var Up = (Us == Color.WHITE ? Square.DELTA_N : Square.DELTA_S);
var Right = (Us == Color.WHITE ? Square.DELTA_NE : Square.DELTA_SW);
var Left = (Us == Color.WHITE ? Square.DELTA_NW : Square.DELTA_SE);
BitboardT b;
var score = Score.SCORE_ZERO;
var ourPawns = pos.pieces_CtPt(Us, PieceType.PAWN);
var theirPawns = pos.pieces_CtPt(Them, PieceType.PAWN);
e.passedPawns[Us] = Bitboard.Create(0);
e.kingSquares[Us] = Square.SQ_NONE;
e.semiopenFiles[Us] = 0xFF;
e.pawnAttacks[Us] = Bitboard.shift_bb(Right, ourPawns) | Bitboard.shift_bb(Left, ourPawns);
e.pawnsOnSquares[Us, Color.BLACK] = Bitcount.popcount_Max15(ourPawns & Bitboard.DarkSquares);
e.pawnsOnSquares[Us, Color.WHITE] = pos.count(PieceType.PAWN, Us) - e.pawnsOnSquares[Us, Color.BLACK];
// Loop through all pawns of the current color and score each pawn
for (var idx = 0; idx < 16; idx++)
{
var s = pos.square(PieceType.PAWN, Us, idx);
if (s == Square.SQ_NONE)
{
break;
}
Debug.Assert(pos.piece_on(s) == Piece.make_piece(Us, PieceType.PAWN));
var f = Square.file_of(s);
// This file cannot be semi-open
e.semiopenFiles[Us] &= ~(1 << f);
// Flag the pawn
var neighbours = ourPawns & Utils.adjacent_files_bb(f);
var doubled = ourPawns & Utils.forward_bb(Us, s);
bool opposed = (theirPawns & Utils.forward_bb(Us, s)) != 0;
var passed = (theirPawns & Utils.passed_pawn_mask(Us, s)) == 0;
bool lever = (theirPawns & Utils.StepAttacksBB[Piece.make_piece(Us, PieceType.PAWN), s]) != 0;
var phalanx = neighbours & Utils.rank_bb_St(s);
var supported = neighbours & Utils.rank_bb_St(s - Up);
bool connected = (supported | phalanx) != 0;
var isolated = neighbours == 0;
// Test for backward pawn.
// If the pawn is passed, isolated, lever or connected it cannot be
// backward. If there are friendly pawns behind on adjacent files
// or if it is sufficiently advanced, it cannot be backward either.
bool backward;
if ((passed | isolated | lever | connected) || (ourPawns & Utils.pawn_attack_span(Them, s)) != 0
|| (Rank.relative_rank_CtSt(Us, s) >= Rank.RANK_5))
{
backward = false;
}
else
{
// We now know 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 picking the closest pawn there.
b = Utils.pawn_attack_span(Us, s) & (ourPawns | theirPawns);
b = Utils.pawn_attack_span(Us, s) & Utils.rank_bb_St(Utils.backmost_sq(Us, b));
// If we have an enemy pawn in the same or next rank, the pawn is
// backward because it cannot advance without being captured.
backward = ((b | Bitboard.shift_bb(Up, b)) & theirPawns) != 0;
}
Debug.Assert(opposed | passed | (Utils.pawn_attack_span(Us, s) & theirPawns) != 0);
// 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 == 0)
{
e.passedPawns[Us] = Bitboard.OrWithSquare(e.passedPawns[Us], s);
}
// Score this pawn
if (isolated)
{
score -= Isolated[opposed ? 1 : 0][f];
}
else if (backward)
{
score -= Backward[opposed ? 1 : 0];
}
else if (supported == 0)
{
score -= UnsupportedPawnPenalty;
}
if (connected)
{
//.........这里部分代码省略.........
示例3: do_king_safety
/// Entry::do_king_safety() calculates a bonus for king safety. It is called only
/// when king square changes, which is about 20% of total king_safety() calls.
private ScoreT do_king_safety(ColorT Us, Position pos, SquareT ksq)
{
kingSquares[Us] = ksq;
castlingRights[Us] = pos.can_castle(Us);
var minKingPawnDistance = 0;
var pawns = pos.pieces_CtPt(Us, PieceType.PAWN);
if (pawns != 0)
{
while ((Utils.DistanceRingBB[ksq, minKingPawnDistance++] & pawns) == 0)
{
}
}
if (Rank.relative_rank_CtSt(Us, ksq) > Rank.RANK_4)
{
return Score.make_score(0, -16*minKingPawnDistance);
}
var bonus = shelter_storm(Us, pos, ksq);
// If we can castle use the bonus after the castling if it is bigger
if (pos.can_castle(Movegen.MakeCastling(Us, CastlingSide.KING_SIDE)))
{
bonus = Value.Create(
Math.Max(bonus, shelter_storm(Us, pos, Square.relative_square(Us, Square.SQ_G1))));
}
if (pos.can_castle(Movegen.MakeCastling(Us, CastlingSide.QUEEN_SIDE)))
{
bonus = Value.Create(
Math.Max(bonus, shelter_storm(Us, pos, Square.relative_square(Us, Square.SQ_C1))));
}
return Score.make_score(bonus, -16*minKingPawnDistance);
}
示例4: generate_pawn_moves
internal static ExtMoveArrayWrapper generate_pawn_moves(
ColorT Us,
GenType Type,
Position pos,
ExtMoveArrayWrapper moveList,
BitboardT target,
CheckInfo ci)
{
// Compute our parametrized parameters at compile time, named according to
// the point of view of white side.
var Them = (Us == Color.WHITE ? Color.BLACK : Color.WHITE);
var TRank8BB = (Us == Color.WHITE ? Bitboard.Rank8BB : Bitboard.Rank1BB);
var TRank7BB = (Us == Color.WHITE ? Bitboard.Rank7BB : Bitboard.Rank2BB);
var TRank3BB = (Us == Color.WHITE ? Bitboard.Rank3BB : Bitboard.Rank6BB);
var Up = (Us == Color.WHITE ? Square.DELTA_N : Square.DELTA_S);
var Right = (Us == Color.WHITE ? Square.DELTA_NE : Square.DELTA_SW);
var Left = (Us == Color.WHITE ? Square.DELTA_NW : Square.DELTA_SE);
var emptySquares = Bitboard.Create(0);
var pawnsOn7 = pos.pieces_CtPt(Us, PieceType.PAWN) & TRank7BB;
var pawnsNotOn7 = pos.pieces_CtPt(Us, PieceType.PAWN) & ~TRank7BB;
var enemies = (Type == GenType.EVASIONS
? pos.pieces_Ct(Them) & target
: Type == GenType.CAPTURES ? target : pos.pieces_Ct(Them));
// Single and double pawn pushes, no promotions
if (Type != GenType.CAPTURES)
{
emptySquares = (Type == GenType.QUIETS || Type == GenType.QUIET_CHECKS ? target : ~pos.pieces());
var b1 = Bitboard.shift_bb(Up, pawnsNotOn7) & emptySquares;
var b2 = Bitboard.shift_bb(Up, b1 & TRank3BB) & emptySquares;
if (Type == GenType.EVASIONS) // Consider only blocking squares
{
b1 &= target;
b2 &= target;
}
if (Type == GenType.QUIET_CHECKS)
{
b1 &= pos.attacks_from_PS(PieceType.PAWN, ci.ksq, Them);
b2 &= pos.attacks_from_PS(PieceType.PAWN, ci.ksq, Them);
// Add pawn pushes which give discovered check. This is possible only
// if the pawn is not on the same file as the enemy king, because we
// don't generate captures. Note that a possible discovery check
// promotion has been already generated amongst the captures.
if ((pawnsNotOn7 & ci.dcCandidates) != 0)
{
var dc1 = Bitboard.shift_bb(Up, pawnsNotOn7 & ci.dcCandidates) & emptySquares
& ~Utils.file_bb_St(ci.ksq);
var dc2 = Bitboard.shift_bb(Up, dc1 & TRank3BB) & emptySquares;
b1 |= dc1;
b2 |= dc2;
}
}
while (b1 != 0)
{
var to = Utils.pop_lsb(ref b1);
(moveList).Add(Move.make_move(to - Up, to));
}
while (b2 != 0)
{
var to = Utils.pop_lsb(ref b2);
(moveList).Add(Move.make_move(to - Up - Up, to));
}
}
// Promotions and underpromotions
if (pawnsOn7 != 0 && (Type != GenType.EVASIONS || ((target & TRank8BB) != 0)))
{
if (Type == GenType.CAPTURES)
{
emptySquares = ~pos.pieces();
}
if (Type == GenType.EVASIONS)
{
emptySquares &= target;
}
var b1 = Bitboard.shift_bb(Right, pawnsOn7) & enemies;
var b2 = Bitboard.shift_bb(Left, pawnsOn7) & enemies;
var b3 = Bitboard.shift_bb(Up, pawnsOn7) & emptySquares;
while (b1 != 0)
{
moveList = make_promotions(Type, Right, moveList, Utils.pop_lsb(ref b1), ci);
}
while (b2 != 0)
{
moveList = make_promotions(Type, Left, moveList, Utils.pop_lsb(ref b2), ci);
}
//.........这里部分代码省略.........
示例5: evaluate
/// evaluate() is the main evaluation function. It returns a static evaluation
/// of the position always from the point of view of the side to move.
internal static ValueT evaluate(bool DoTrace, Position pos)
{
Debug.Assert(pos.checkers() == 0);
var ei = new EvalInfo();
ScoreT[] mobility = {Score.SCORE_ZERO, Score.SCORE_ZERO};
// Initialize score by reading the incrementally updated scores included
// in the position object (material + piece square tables).
// Score is computed from the point of view of white.
var score = pos.psq_score();
// Probe the material hash table
var me = Material.probe(pos);
score += me.imbalance();
// If we have a specialized evaluation function for the current material
// configuration, call it and return.
if (me.specialized_eval_exists())
{
return me.evaluate(pos);
}
// Probe the pawn hash table
ei.pi = Pawns.probe(pos);
score += Score.Multiply(ei.pi.pawns_score(), Weights[PawnStructure]);
// Initialize attack and king safety bitboards
ei.attackedBy[Color.WHITE, PieceType.ALL_PIECES] =
ei.attackedBy[Color.BLACK, PieceType.ALL_PIECES] = Bitboard.Create(0);
init_eval_info(Color.WHITE, pos, ei);
init_eval_info(Color.BLACK, pos, ei);
// Pawns blocked or on ranks 2 and 3. Will be excluded from the mobility area
BitboardT[] blockedPawns =
{
pos.pieces_CtPt(Color.WHITE, PieceType.PAWN)
& (Bitboard.shift_bb(Square.DELTA_S, pos.pieces()) | Bitboard.Rank2BB
| Bitboard.Rank3BB),
pos.pieces_CtPt(Color.BLACK, PieceType.PAWN)
& (Bitboard.shift_bb(Square.DELTA_N, pos.pieces()) | Bitboard.Rank7BB
| Bitboard.Rank6BB)
};
// Do not include in mobility squares protected by enemy pawns, or occupied
// by our blocked pawns or king.
BitboardT[] mobilityArea =
{
~(Bitboard.OrWithSquare(ei.attackedBy[Color.BLACK, PieceType.PAWN] | blockedPawns[Color.WHITE]
, pos.square(PieceType.KING, Color.WHITE))),
~(Bitboard.OrWithSquare(ei.attackedBy[Color.WHITE, PieceType.PAWN] | blockedPawns[Color.BLACK]
, pos.square(PieceType.KING, Color.BLACK)))
};
// Evaluate pieces and mobility
score += evaluate_pieces(PieceType.KNIGHT, Color.WHITE, DoTrace, pos, ei, mobility, mobilityArea);
score += Score.Multiply(mobility[Color.WHITE] - mobility[Color.BLACK], Weights[Mobility]);
// Evaluate kings after all other pieces because we need complete attack
// information when computing the king safety evaluation.
score += evaluate_king(Color.WHITE, DoTrace, pos, ei) - evaluate_king(Color.BLACK, DoTrace, pos, ei);
// Evaluate tactical threats, we need full attack information including king
score += evaluate_threats(Color.WHITE, DoTrace, pos, ei) - evaluate_threats(Color.BLACK, DoTrace, pos, ei);
// Evaluate passed pawns, we need full attack information including king
score += evaluate_passed_pawns(Color.WHITE, DoTrace, pos, ei)
- evaluate_passed_pawns(Color.BLACK, DoTrace, pos, ei);
// If both sides have only pawns, score for potential unstoppable pawns
if (pos.non_pawn_material(Color.WHITE) == 0 && pos.non_pawn_material(Color.BLACK) == 0)
{
BitboardT b;
if ((b = ei.pi.passed_pawns(Color.WHITE)) != 0)
{
score += Rank.relative_rank_CtSt(Color.WHITE, Utils.frontmost_sq(Color.WHITE, b)) * Unstoppable;
}
if ((b = ei.pi.passed_pawns(Color.BLACK)) != 0)
{
score -= Rank.relative_rank_CtSt(Color.BLACK, Utils.frontmost_sq(Color.BLACK, b)) * Unstoppable;
}
}
// Evaluate space for both sides, only during opening
if (pos.non_pawn_material(Color.WHITE) + pos.non_pawn_material(Color.BLACK) >= 12222)
{
score += Score.Multiply(evaluate_space(Color.WHITE, pos, ei) - evaluate_space(Color.BLACK, pos, ei), Weights[Space]);
}
// Scale winning side if position is more drawish than it appears
var strongSide = Score.eg_value(score) > Value.VALUE_DRAW ? Color.WHITE : Color.BLACK;
var sf = me.scale_factor(pos, strongSide);
// If we don't already have an unusual scale factor, check for certain
// types of endgames, and use a lower scale for those.
if (me.game_phase() < Phase.PHASE_MIDGAME
&& (sf == ScaleFactor.SCALE_FACTOR_NORMAL || sf == ScaleFactor.SCALE_FACTOR_ONEPAWN))
//.........这里部分代码省略.........
示例6: evaluate_space
// evaluate_space() computes the space evaluation for a given side. The
// space evaluation is a simple bonus based on the number of safe squares
// available for minor pieces on the central four files on ranks 2--4. Safe
// squares one, two or three squares behind a friendly pawn are counted
// twice. Finally, the space bonus is multiplied by a weight. The aim is to
// improve play on game opening.
private static ScoreT evaluate_space(ColorT Us, Position pos, EvalInfo ei)
{
var Them = (Us == Color.WHITE ? Color.BLACK : Color.WHITE);
// Find the safe squares for our pieces inside the area defined by
// SpaceMask[]. A square is unsafe if it is attacked by an enemy
// pawn, or if it is undefended and attacked by an enemy piece.
var safe = SpaceMask[Us] & ~pos.pieces_CtPt(Us, PieceType.PAWN) & ~ei.attackedBy[Them, PieceType.PAWN]
& (ei.attackedBy[Us, PieceType.ALL_PIECES] | ~ei.attackedBy[Them, PieceType.ALL_PIECES]);
// Find all squares which are at most three squares behind some friendly pawn
var behind = pos.pieces_CtPt(Us, PieceType.PAWN);
behind |= (Us == Color.WHITE ? behind >> 8 : behind << 8);
behind |= (Us == Color.WHITE ? behind >> 16 : behind << 16);
// Since SpaceMask[Us.Value] is fully on our half of the board...
Debug.Assert((uint) (safe >> (Us == Color.WHITE ? 32 : 0)) == 0);
// ...count safe + (behind & safe) with a single popcount
var bonus = Bitcount.popcount_Full((Us == Color.WHITE ? safe << 32 : safe >> 32) | (behind & safe));
var weight = pos.count(PieceType.KNIGHT, Us) + pos.count(PieceType.BISHOP, Us)
+ pos.count(PieceType.KNIGHT, Them) + pos.count(PieceType.BISHOP, Them);
return Score.make_score(bonus*weight*weight, 0);
}
示例7: evaluate_threats
// evaluate_threats() assigns bonuses according to the type of attacking piece
// and the type of attacked one.
private static ScoreT evaluate_threats(ColorT Us, bool DoTrace, Position pos, EvalInfo ei)
{
var Them = (Us == Color.WHITE ? Color.BLACK : Color.WHITE);
var Up = (Us == Color.WHITE ? Square.DELTA_N : Square.DELTA_S);
var Left = (Us == Color.WHITE ? Square.DELTA_NW : Square.DELTA_SE);
var Right = (Us == Color.WHITE ? Square.DELTA_NE : Square.DELTA_SW);
var TRank2BB = (Us == Color.WHITE ? Bitboard.Rank2BB : Bitboard.Rank7BB);
var TRank7BB = (Us == Color.WHITE ? Bitboard.Rank7BB : Bitboard.Rank2BB);
const int Defended = 0;
const int Weak = 1;
const int Minor = 0;
const int Rook = 1;
BitboardT b;
var score = Score.SCORE_ZERO;
// Non-pawn enemies attacked by a pawn
var weak = (pos.pieces_Ct(Them) ^ pos.pieces_CtPt(Them, PieceType.PAWN)) & ei.attackedBy[Us, PieceType.PAWN];
if (weak!=0)
{
b = pos.pieces_CtPt(Us, PieceType.PAWN)
& (~ei.attackedBy[Them, PieceType.ALL_PIECES] | ei.attackedBy[Us, PieceType.ALL_PIECES]);
var safeThreats = (Bitboard.shift_bb(Right, b) | Bitboard.shift_bb(Left, b)) & weak;
if ((weak ^ safeThreats)!=0)
{
score += ThreatenedByHangingPawn;
}
while (safeThreats!=0)
{
score += ThreatenedByPawn[Piece.type_of(pos.piece_on(Utils.pop_lsb(ref safeThreats)))];
}
}
// Non-pawn enemies defended by a pawn
var defended = (pos.pieces_Ct(Them) ^ pos.pieces_CtPt(Them, PieceType.PAWN)) & ei.attackedBy[Them, PieceType.PAWN];
// Add a bonus according to the kind of attacking pieces
if (defended!=0)
{
b = defended & (ei.attackedBy[Us, PieceType.KNIGHT] | ei.attackedBy[Us, PieceType.BISHOP]);
while (b!=0)
{
score += Threat[Defended][Minor][Piece.type_of(pos.piece_on(Utils.pop_lsb(ref b)))];
}
b = defended & ei.attackedBy[Us, PieceType.ROOK];
while (b!=0)
{
score += Threat[Defended][Rook][Piece.type_of(pos.piece_on(Utils.pop_lsb(ref b)))];
}
}
// Enemies not defended by a pawn and under our attack
weak = pos.pieces_Ct(Them) & ~ei.attackedBy[Them, PieceType.PAWN] & ei.attackedBy[Us, PieceType.ALL_PIECES];
// Add a bonus according to the kind of attacking pieces
if (weak!=0)
{
b = weak & (ei.attackedBy[Us, PieceType.KNIGHT] | ei.attackedBy[Us, PieceType.BISHOP]);
while (b!=0)
{
score += Threat[Weak][Minor][Piece.type_of(pos.piece_on(Utils.pop_lsb(ref b)))];
}
b = weak & ei.attackedBy[Us, PieceType.ROOK];
while (b!=0)
{
score += Threat[Weak][Rook][Piece.type_of(pos.piece_on(Utils.pop_lsb(ref b)))];
}
b = weak & ~ei.attackedBy[Them, PieceType.ALL_PIECES];
if (b!=0)
{
score += Hanging*Bitcount.popcount_Max15(b);
}
b = weak & ei.attackedBy[Us, PieceType.KING];
if (b!=0)
{
score += Bitboard.more_than_one(b) ? KingOnMany : KingOnOne;
}
}
// Bonus if some pawns can safely push and attack an enemy piece
b = pos.pieces_CtPt(Us, PieceType.PAWN) & ~TRank7BB;
b = Bitboard.shift_bb(Up, b | (Bitboard.shift_bb(Up, b & TRank2BB) & ~pos.pieces()));
b &= ~pos.pieces() & ~ei.attackedBy[Them, PieceType.PAWN]
& (ei.attackedBy[Us, PieceType.ALL_PIECES] | ~ei.attackedBy[Them, PieceType.ALL_PIECES]);
b = (Bitboard.shift_bb(Left, b) | Bitboard.shift_bb(Right, b)) & pos.pieces_Ct(Them)
& ~ei.attackedBy[Us, PieceType.PAWN];
//.........这里部分代码省略.........
示例8: evaluate_pieces
// evaluate_pieces() assigns bonuses and penalties to the pieces of a given color
private static ScoreT evaluate_pieces(
PieceTypeT pieceType,
ColorT Us,
bool DoTrace,
Position pos,
EvalInfo ei,
ScoreT[] mobility,
BitboardT[] mobilityArea)
{
int Pt = pieceType;
if (Pt == PieceType.KING)
{
return Score.SCORE_ZERO;
}
var score = Score.SCORE_ZERO;
var NextPt = (Us == Color.WHITE ? pieceType : pieceType + 1);
var Them = (Us == Color.WHITE ? Color.BLACK : Color.WHITE);
ei.attackedBy[Us, Pt] = Bitboard.Create(0);
for(var idx=0; idx<16;idx++)
{
var s = pos.square(pieceType, Us, idx);
if (s == Square.SQ_NONE)
{
break;
}
// Find attacked squares, including x-ray attacks for bishops and rooks
var b = Pt == PieceType.BISHOP
? Utils.attacks_bb_PtSBb(PieceType.BISHOP, s, pos.pieces() ^ pos.pieces_CtPt(Us, PieceType.QUEEN))
: Pt == PieceType.ROOK
? Utils.attacks_bb_PtSBb(
PieceType.ROOK,
s,
pos.pieces() ^ pos.pieces_CtPtPt(Us, PieceType.ROOK, PieceType.QUEEN))
: pos.attacks_from_PtS(pieceType, s);
if (Bitboard.AndWithSquare(ei.pinnedPieces[Us], s)!=0)
{
b &= Utils.LineBB[pos.square(PieceType.KING, Us), s];
}
ei.attackedBy[Us, PieceType.ALL_PIECES] |= ei.attackedBy[Us, Pt] |= b;
if ((b & ei.kingRing[Them])!=0)
{
ei.kingAttackersCount[Us]++;
ei.kingAttackersWeight[Us] += KingAttackWeights[Pt];
var bb = b & ei.attackedBy[Them, PieceType.KING];
if (bb!=0)
{
ei.kingAdjacentZoneAttacksCount[Us] += Bitcount.popcount_Max15(bb);
}
}
if (Pt == PieceType.QUEEN)
{
b &=
~(ei.attackedBy[Them, PieceType.KNIGHT] | ei.attackedBy[Them, PieceType.BISHOP]
| ei.attackedBy[Them, PieceType.ROOK]);
}
var mob = Pt == PieceType.QUEEN
? Bitcount.popcount_Full(b & mobilityArea[Us])
: Bitcount.popcount_Max15(b & mobilityArea[Us]);
mobility[Us] += MobilityBonus[Pt][mob];
if (Pt == PieceType.BISHOP || Pt == PieceType.KNIGHT)
{
// Bonus for outpost square
if (Rank.relative_rank_CtSt(Us, s) >= Rank.RANK_4 && Rank.relative_rank_CtSt(Us, s) <= Rank.RANK_6
&& (pos.pieces_CtPt(Them, PieceType.PAWN) & Utils.pawn_attack_span(Us, s))==0)
{
score +=
Outpost[Pt == PieceType.BISHOP ? 1 : 0][Bitboard.AndWithSquare(ei.attackedBy[Us, PieceType.PAWN], s)!=0 ? 1 : 0];
}
// Bonus when behind a pawn
if (Rank.relative_rank_CtSt(Us, s) < Rank.RANK_5 && Bitboard.AndWithSquare(pos.pieces_Pt(PieceType.PAWN), (s + Square.pawn_push(Us)))!=0)
{
score += MinorBehindPawn;
}
// Penalty for pawns on same color square of bishop
if (Pt == PieceType.BISHOP)
{
score -= BishopPawns*ei.pi.pawns_on_same_color_squares(Us, s);
}
// 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 (Pt == PieceType.BISHOP && pos.is_chess960()
&& (s == Square.relative_square(Us, Square.SQ_A1) || s == Square.relative_square(Us, Square.SQ_H1)))
{
var d = Square.pawn_push(Us) + (Square.file_of(s) == File.FILE_A ? Square.DELTA_E : Square.DELTA_W);
//.........这里部分代码省略.........