本文整理汇总了C#中Position.count方法的典型用法代码示例。如果您正苦于以下问题:C# Position.count方法的具体用法?C# Position.count怎么用?C# Position.count使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Position
的用法示例。
在下文中一共展示了Position.count方法的13个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: normalize
// Map the square as if strongSide is white and strongSide's only pawn
// is on the left half of the board.
protected static SquareT normalize(Position pos, ColorT strongSide, SquareT sq)
{
Debug.Assert(pos.count(PieceType.PAWN, strongSide) == 1);
if (Square.file_of(pos.square(PieceType.PAWN, strongSide)) >= File.FILE_E)
{
sq = Square.Create(sq ^ 7); // Mirror SQ_H1 -> SQ_A1
}
if (strongSide == Color.BLACK)
{
sq = Square.opposite(sq);
}
return sq;
}
示例2: GetScaleFactor
internal override ScaleFactor GetScaleFactor(Position pos)
{
Debug.Assert(pos.non_pawn_material(strongSide) == Value.VALUE_ZERO);
Debug.Assert(pos.count(PieceType.PAWN, strongSide) >= 2);
Debug.Assert(verify_material(pos, weakSide, Value.VALUE_ZERO, 0));
var ksq = pos.square(PieceType.KING, weakSide);
var pawns = pos.pieces_CtPt(strongSide, PieceType.PAWN);
// If all pawns are ahead of the king, on a single rook file and
// the king is within one file of the pawns, it's a draw.
if ((pawns & ~Utils.in_front_bb(weakSide, Square.rank_of(ksq)))==0
&& !((pawns & ~Bitboard.FileABB)!=0 && (pawns & ~Bitboard.FileHBB)!=0)
&& Utils.distance_File(ksq, Utils.lsb(pawns)) <= 1)
{
return ScaleFactor.SCALE_FACTOR_DRAW;
}
return ScaleFactor.SCALE_FACTOR_NONE;
}
示例3: verify_material
protected static bool verify_material(Position pos, ColorT c, ValueT npm, int pawnsCnt)
{
return pos.non_pawn_material(c) == npm && pos.count(PieceType.PAWN, c) == pawnsCnt;
}
示例4: GetValue
internal override ValueT GetValue(Position pos)
{
Debug.Assert(verify_material(pos, weakSide, Value.VALUE_ZERO, 0));
Debug.Assert(pos.checkers()==0); // Eval is never called when in check
// Stalemate detection with lone king
if (pos.side_to_move() == weakSide && new MoveList(GenType.LEGAL, pos).size() == 0)
{
return Value.VALUE_DRAW;
}
var winnerKSq = pos.square(PieceType.KING, strongSide);
var loserKSq = pos.square(PieceType.KING, weakSide);
var result = pos.non_pawn_material(strongSide)
+ pos.count(PieceType.PAWN, strongSide)*Value.PawnValueEg + PushToEdges[loserKSq]
+ PushClose[Utils.distance_Square(winnerKSq, loserKSq)];
if (pos.count(PieceType.QUEEN, strongSide) > 0 || pos.count(PieceType.ROOK, strongSide) > 0
|| (pos.count(PieceType.BISHOP, strongSide) > 0 && pos.count(PieceType.KNIGHT, strongSide) > 0)
|| (pos.count(PieceType.BISHOP, strongSide) > 1
&& Square.opposite_colors(
pos.square(PieceType.BISHOP, strongSide, 0),
pos.square(PieceType.BISHOP, strongSide, 1))))
{
result += Value.VALUE_KNOWN_WIN;
}
return strongSide == pos.side_to_move() ? result : -result;
}
示例5: is_KQKRPs
private static bool is_KQKRPs(Position pos, ColorT us)
{
return pos.count(PieceType.PAWN, us) == 0 && pos.non_pawn_material(us) == Value.QueenValueMg
&& pos.count(PieceType.QUEEN, us) == 1 && pos.count(PieceType.ROOK, Color.opposite(us)) == 1
&& pos.count(PieceType.PAWN, Color.opposite(us)) >= 1;
}
示例6: 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)
{
//.........这里部分代码省略.........
示例7: probe
/// Material::probe() looks up the current position's material configuration in
/// the material hash table. It returns a pointer to the Entry if the position
/// is found. Otherwise a new Entry is computed and stored there, so we don't
/// have to recompute all when the same material configuration occurs again.
internal static MaterialEntry probe(Position pos)
{
var key = pos.material_key();
MaterialEntry e;
if (!pos.this_thread().materialTable.TryGetValue(key, out e))
{
e = new MaterialEntry();
pos.this_thread().materialTable.Add(key, e);
}
else if (e.key == key)
{
return e;
}
e.reset();
e.key = key;
e.factor[Color.WHITE] = e.factor[Color.BLACK] = (ushort) ScaleFactor.SCALE_FACTOR_NORMAL;
e.gamePhase = pos.game_phase();
// Let's look if we have a specialized evaluation function for this particular
// material configuration. Firstly we look for a fixed configuration one, then
// for a generic one if the previous search failed.
if ((e.evaluationFunction = pos.this_thread().endgames.probeEndgameValue(key)) != null)
{
return e;
}
foreach (var c in Color.AllColors)
{
if (is_KXK(pos, c))
{
e.evaluationFunction = EvaluateKXK[c];
return e;
}
}
// OK, we didn't find any special evaluation function for the current material
// configuration. Is there a suitable specialized scaling function?
EndgameScaleFactor sf;
if ((sf = pos.this_thread().endgames.probeEndgameScaleFactor(key)) != null)
{
e.scalingFunction[sf.strong_side()] = sf; // Only strong color assigned
return e;
}
// We didn't find any specialized scaling function, so fall back on generic
// ones that refer to more than one material distribution. Note that in this
// case we don't return after setting the function.
foreach (var c in Color.AllColors)
{
if (is_KBPsKs(pos, c))
{
e.scalingFunction[c] = ScaleKBPsK[c];
}
else if (is_KQKRPs(pos, c))
{
e.scalingFunction[c] = ScaleKQKRPs[c];
}
}
var npm_w = pos.non_pawn_material(Color.WHITE);
var npm_b = pos.non_pawn_material(Color.BLACK);
if (npm_w + npm_b == Value.VALUE_ZERO && (pos.pieces_Pt(PieceType.PAWN) != 0)) // Only pawns on the board
{
if (pos.count(PieceType.PAWN, Color.BLACK) == 0)
{
Debug.Assert(pos.count(PieceType.PAWN, Color.WHITE) >= 2);
e.scalingFunction[Color.WHITE] = ScaleKPsK[Color.WHITE];
}
else if (pos.count(PieceType.PAWN, Color.WHITE) == 0)
{
Debug.Assert(pos.count(PieceType.PAWN, Color.BLACK) >= 2);
e.scalingFunction[Color.BLACK] = ScaleKPsK[Color.BLACK];
}
else if (pos.count(PieceType.PAWN, Color.WHITE) == 1 && pos.count(PieceType.PAWN, Color.BLACK) == 1)
{
// This is a special case because we set scaling functions
// for both colors instead of only one.
e.scalingFunction[Color.WHITE] = ScaleKPKP[Color.WHITE];
e.scalingFunction[Color.BLACK] = ScaleKPKP[Color.BLACK];
}
}
// Zero or just one pawn makes it difficult to win, even with a small material
// advantage. This catches some trivial draws like KK, KBK and KNK and gives a
// drawish scale factor for cases such as KRKBP and KmmKm (except for KBBKN).
if (pos.count(PieceType.PAWN, Color.WHITE) == 0 && npm_w - npm_b <= Value.BishopValueMg)
{
e.factor[Color.WHITE] =
(ushort)
(npm_w < Value.RookValueMg
//.........这里部分代码省略.........
示例8: is_KBPsKs
private static bool is_KBPsKs(Position pos, ColorT us)
{
return pos.non_pawn_material(us) == Value.BishopValueMg && pos.count(PieceType.BISHOP, us) == 1
&& pos.count(PieceType.PAWN, us) >= 1;
}
示例9: search
//.........这里部分代码省略.........
stackPlus1.reduction = Depth.DEPTH_ZERO;
stackPlus2.killers0 = stackPlus2.killers1 = Move.MOVE_NONE;
// Step 4. Transposition table lookup
// We don't want the score of a partial search to overwrite a previous full search
// TT value, so we use a different position key in case of an excluded move.
excludedMove = stack.excludedMove;
posKey = excludedMove != 0 ? pos.exclusion_key() : pos.key();
tte = TranspositionTable.probe(posKey, out ttHit);
stack.ttMove = ttMove = RootNode ? RootMoves[(int) PVIdx].pv[0] : ttHit ? tte.move() : Move.MOVE_NONE;
ttValue = ttHit ? value_from_tt(tte.value(), stack.ply) : Value.VALUE_NONE;
// At non-PV nodes we check for a fail high/low. We don't prune at PV nodes
if (!PvNode
&& ttHit
&& tte.depth() >= depth
&& ttValue != Value.VALUE_NONE // Only in case of TT access race
&& (ttValue >= beta
? (tte.bound() & Bound.BOUND_LOWER) != 0
: (tte.bound() & Bound.BOUND_UPPER) != 0))
{
stack.currentMove = ttMove; // Can be Move.MOVE_NONE
// If ttMove is quiet, update killers, history, counter move on TT hit
if (ttValue >= beta && ttMove != 0 && !pos.capture_or_promotion(ttMove))
update_stats(pos, ss, ttMove, depth, null, 0);
return ttValue;
}
// Step 4a. Tablebase probe
if (!RootNode && Tablebases.Cardinality != 0)
{
var piecesCnt = pos.count(PieceType.ALL_PIECES, Color.WHITE) + pos.count(PieceType.ALL_PIECES, Color.BLACK);
if (piecesCnt <= Tablebases.Cardinality
&& (piecesCnt < Tablebases.Cardinality || depth >= Tablebases.ProbeDepth)
&& pos.rule50_count() == 0)
{
var found = 0;
var v = Tablebases.probe_wdl(pos, ref found);
if (found != 0)
{
Tablebases.Hits++;
var drawScore = Tablebases.UseRule50 ? 1 : 0;
value = v < -drawScore
? -Value.VALUE_MATE + _.MAX_PLY + stack.ply
: v > drawScore
? Value.VALUE_MATE - _.MAX_PLY - stack.ply
: Value.VALUE_DRAW + 2*v*drawScore;
tte.save(posKey, value_to_tt(value, stack.ply), Bound.BOUND_EXACT,
new Depth(Math.Min(_.MAX_PLY - Depth.ONE_PLY_C, (int)depth + 6*Depth.ONE_PLY_C)),
Move.MOVE_NONE, Value.VALUE_NONE, TranspositionTable.generation());
return value;
}
}
}
// Step 5. Evaluate the position statically
if (inCheck)
{
示例10: evaluate
//.........这里部分代码省略.........
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))
{
if (pos.opposite_bishops())
{
// Endgame with opposite-colored bishops and no other pieces (ignoring pawns)
// is almost a draw, in case of KBP vs KB is even more a draw.
if (pos.non_pawn_material(Color.WHITE) == Value.BishopValueMg
&& pos.non_pawn_material(Color.BLACK) == Value.BishopValueMg)
{
sf = Bitboard.more_than_one(pos.pieces_Pt(PieceType.PAWN)) ? (ScaleFactor) (31) : (ScaleFactor) (9);
}
// Endgame with opposite-colored bishops, but also other pieces. Still
// a bit drawish, but not as drawish as with only the two bishops.
else
{
sf = (ScaleFactor) (46*(int) sf/(int) ScaleFactor.SCALE_FACTOR_NORMAL);
}
}
// Endings where weaker side can place his king in front of the opponent's
// pawns are drawish.
else if (Math.Abs(Score.eg_value(score)) <= Value.BishopValueEg && ei.pi.pawn_span(strongSide) <= 1
&& !pos.pawn_passed(Color.opposite(strongSide), pos.square(PieceType.KING, Color.opposite(strongSide))))
{
sf = ei.pi.pawn_span(strongSide) != 0 ? (ScaleFactor) (51) : (ScaleFactor) (37);
}
}
// Scale endgame by number of pawns
var p = pos.count(PieceType.PAWN, Color.WHITE) + pos.count(PieceType.PAWN, Color.BLACK);
var vEg = 1 + Math.Abs(Score.eg_value(score));
sf = (ScaleFactor) (Math.Max((int) sf/2, (int) sf - 8*(int) ScaleFactor.SCALE_FACTOR_NORMAL*(12 - p)/vEg));
// Interpolate between a middlegame and a (scaled by 'sf') endgame score
var v = Score.mg_value(score)*(int) (me.game_phase())
+ Score.eg_value(score)*(Phase.PHASE_MIDGAME - me.game_phase())*(int) sf
/(int) ScaleFactor.SCALE_FACTOR_NORMAL;
v /= (int) (Phase.PHASE_MIDGAME);
// In case of tracing add all single evaluation terms
if (DoTrace)
{
add_IdxSt((int) Term.MATERIAL, pos.psq_score());
add_IdxSt((int) Term.IMBALANCE, me.imbalance());
add_IdxSt(PieceType.PAWN, ei.pi.pawns_score());
add_IdxStSt(
(int) Term.MOBILITY,
Score.Multiply(mobility[Color.WHITE], Weights[Mobility]),
Score.Multiply(mobility[Color.BLACK], Weights[Mobility]));
add_IdxStSt(
(int) Term.SPACE,
Score.Multiply(evaluate_space(Color.WHITE, pos, ei), Weights[Space]),
Score.Multiply(evaluate_space(Color.BLACK, pos, ei), Weights[Space]));
add_IdxSt((int) Term.TOTAL, score);
}
return (pos.side_to_move() == Color.WHITE ? v : -v) + Tempo; // Side to move point of view
}
示例11: 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);
}
示例12: evaluate_passed_pawns
// evaluate_passed_pawns() evaluates the passed pawns of the given color
private static ScoreT evaluate_passed_pawns(ColorT Us, bool DoTrace, Position pos, EvalInfo ei)
{
var Them = (Us == Color.WHITE ? Color.BLACK : Color.WHITE);
var score = Score.SCORE_ZERO;
var b = ei.pi.passed_pawns(Us);
while (b!=0)
{
var s = Utils.pop_lsb(ref b);
Debug.Assert(pos.pawn_passed(Us, s));
int r = Rank.relative_rank_CtSt(Us, s) - Rank.RANK_2;
var rr = r*(r - 1);
ValueT mbonus = Passed[(int) Phase.MG][r], ebonus = Passed[(int) Phase.EG][r];
if (rr != 0)
{
var blockSq = s + Square.pawn_push(Us);
// Adjust bonus based on the king's proximity
ebonus += Utils.distance_Square(pos.square(PieceType.KING, Them), blockSq)*5*rr
- Utils.distance_Square(pos.square(PieceType.KING, Us), blockSq)*2*rr;
// If blockSq is not the queening square then consider also a second push
if (Rank.relative_rank_CtSt(Us, blockSq) != Rank.RANK_8)
{
ebonus -= Utils.distance_Square(pos.square(PieceType.KING, Us), blockSq + Square.pawn_push(Us))*rr;
}
// If the pawn is free to advance, then increase the bonus
if (pos.empty(blockSq))
{
// If there is a rook or queen attacking/defending the pawn from behind,
// consider all the squaresToQueen. Otherwise consider only the squares
// in the pawn's path attacked or occupied by the enemy.
BitboardT squaresToQueen;
BitboardT unsafeSquares;
var defendedSquares = unsafeSquares = squaresToQueen = Utils.forward_bb(Us, s);
var bb = Utils.forward_bb(Them, s) & pos.pieces_PtPt(PieceType.ROOK, PieceType.QUEEN)
& pos.attacks_from_PtS(PieceType.ROOK, s);
if ((pos.pieces_Ct(Us) & bb)==0)
{
defendedSquares &= ei.attackedBy[Us, PieceType.ALL_PIECES];
}
if ((pos.pieces_Ct(Them) & bb) == 0)
{
unsafeSquares &= ei.attackedBy[Them, PieceType.ALL_PIECES] | pos.pieces_Ct(Them);
}
// If there aren't any enemy attacks, assign a big bonus. Otherwise
// assign a smaller bonus if the block square isn't attacked.
var k = unsafeSquares == 0 ? 18 : Bitboard.AndWithSquare(unsafeSquares, blockSq)==0 ? 8 : 0;
// If the path to queen is fully defended, assign a big bonus.
// Otherwise assign a smaller bonus if the block square is defended.
if (defendedSquares == squaresToQueen)
{
k += 6;
}
else if (Bitboard.AndWithSquare(defendedSquares, blockSq)!=0)
{
k += 4;
}
mbonus += k*rr;
ebonus += k*rr;
}
else if (Bitboard.AndWithSquare(pos.pieces_Ct(Us), blockSq)!=0)
{
mbonus += rr*3 + r*2 + 3;
ebonus += rr + r*2;
}
} // rr != 0
if (pos.count(PieceType.PAWN, Us) < pos.count(PieceType.PAWN, Them))
{
ebonus += ebonus/4;
}
score += Score.make_score(mbonus, ebonus) + PassedFile[Square.file_of(s)];
}
if (DoTrace)
{
add_IdxCtSt((int) Term.PASSED, Us, Score.Multiply(score, Weights[PassedPawns]));
}
// Add the scores to the middlegame and endgame eval
return Score.Multiply(score, Weights[PassedPawns]);
}
示例13: evaluate_king
// evaluate_king() assigns bonuses and penalties to a king of a given color
private static ScoreT evaluate_king(ColorT Us, bool DoTrace, Position pos, EvalInfo ei)
{
var Them = (Us == Color.WHITE ? Color.BLACK : Color.WHITE);
var ksq = pos.square(PieceType.KING, Us);
// King shelter and enemy pawns storm
var score = ei.pi.king_safety(Us, pos, ksq);
// Main king safety evaluation
if (ei.kingAttackersCount[Them] != 0)
{
// Find the attacked squares around the king which have no defenders
// apart from the king itself
var undefended = ei.attackedBy[Them, PieceType.ALL_PIECES] & ei.attackedBy[Us, PieceType.KING]
& ~(ei.attackedBy[Us, PieceType.PAWN] | ei.attackedBy[Us, PieceType.KNIGHT]
| ei.attackedBy[Us, PieceType.BISHOP] | ei.attackedBy[Us, PieceType.ROOK]
| ei.attackedBy[Us, PieceType.QUEEN]);
// Initialize the 'attackUnits' variable, which is used later on as an
// index into the KingDanger[] array. The initial value is based on the
// number and types of the enemy's attacking pieces, the number of
// attacked and undefended squares around our king and the quality of
// the pawn shelter (current 'score' value).
var attackUnits = Math.Min(72, ei.kingAttackersCount[Them] *ei.kingAttackersWeight[Them])
+ 9*ei.kingAdjacentZoneAttacksCount[Them] + 27*Bitcount.popcount_Max15(undefended)
+ 11*((ulong)ei.pinnedPieces[Us] != 0 ? 1 : 0)
- 64*(pos.count(PieceType.QUEEN, Them) == 0 ? 1 : 0) - Score.mg_value(score)/8;
// Analyse the enemy's safe queen contact checks. Firstly, find the
// undefended squares around the king reachable by the enemy queen...
var b = undefended & ei.attackedBy[Them, PieceType.QUEEN] & ~pos.pieces_Ct(Them);
if (b!=0)
{
// ...and then remove squares not supported by another enemy piece
b &= ei.attackedBy[Them, PieceType.PAWN] | ei.attackedBy[Them, PieceType.KNIGHT]
| ei.attackedBy[Them, PieceType.BISHOP] | ei.attackedBy[Them, PieceType.ROOK];
if (b!=0)
{
attackUnits += QueenContactCheck*Bitcount.popcount_Max15(b);
}
}
// Analyse the enemy's safe distance checks for sliders and knights
var safe = ~(ei.attackedBy[Us, PieceType.ALL_PIECES] | pos.pieces_Ct(Them));
var b1 = pos.attacks_from_PtS(PieceType.ROOK, ksq) & safe;
var b2 = pos.attacks_from_PtS(PieceType.BISHOP, ksq) & safe;
// Enemy queen safe checks
b = (b1 | b2) & ei.attackedBy[Them, PieceType.QUEEN];
if (b!=0)
{
attackUnits += QueenCheck*Bitcount.popcount_Max15(b);
score -= Checked;
}
// Enemy rooks safe checks
b = b1 & ei.attackedBy[Them, PieceType.ROOK];
if (b!=0)
{
attackUnits += RookCheck*Bitcount.popcount_Max15(b);
score -= Checked;
}
// Enemy bishops safe checks
b = b2 & ei.attackedBy[Them, PieceType.BISHOP];
if (b!=0)
{
attackUnits += BishopCheck*Bitcount.popcount_Max15(b);
score -= Checked;
}
// Enemy knights safe checks
b = pos.attacks_from_PtS(PieceType.KNIGHT, ksq) & ei.attackedBy[Them, PieceType.KNIGHT] & safe;
if (b!=0)
{
attackUnits += KnightCheck*Bitcount.popcount_Max15(b);
score -= Checked;
}
// Finally, extract the king danger score from the KingDanger[]
// array and subtract the score from evaluation.
score -= KingDanger[Math.Max(Math.Min(attackUnits, 399), 0)];
}
if (DoTrace)
{
add_IdxCtSt(PieceType.KING, Us, score);
}
return score;
}