本文整理汇总了C#中Portfish.Position.piece_count方法的典型用法代码示例。如果您正苦于以下问题:C# Position.piece_count方法的具体用法?C# Position.piece_count怎么用?C# Position.piece_count使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Portfish.Position
的用法示例。
在下文中一共展示了Position.piece_count方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: Endgame_KQKR
/// KQ vs KR. This is almost identical to KX vs K: We give the attacking
/// king a bonus for having the kings close together, and for forcing the
/// defending king towards the edge. If we also take care to avoid null move
/// for the defending side in the search, this is usually sufficient to be
/// able to win KQ vs KR.
internal static Value Endgame_KQKR(Color strongerSide, Position pos)
{
Color weakerSide = strongerSide ^ 1;
Debug.Assert(pos.non_pawn_material(strongerSide) == Constants.QueenValueMidgame);
Debug.Assert(pos.piece_count(strongerSide, PieceTypeC.PAWN) == 0);
Debug.Assert(pos.non_pawn_material(weakerSide) == Constants.RookValueMidgame);
Debug.Assert(pos.piece_count(weakerSide, PieceTypeC.PAWN) == 0);
Square winnerKSq = pos.king_square(strongerSide);
Square loserKSq = pos.king_square(weakerSide);
Value result = Constants.QueenValueEndgame
- Constants.RookValueEndgame
+ MateTable[loserKSq]
+ DistanceBonus[Utils.square_distance(winnerKSq, loserKSq)];
return strongerSide == pos.sideToMove ? result : -result;
}
示例2: 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;
}
示例3: is_KQKRPs
internal static bool is_KQKRPs(int Us, Position pos)
{
var Them = (Us == ColorC.WHITE ? ColorC.BLACK : ColorC.WHITE);
return pos.piece_count(Us, PieceTypeC.PAWN) == 0 && pos.non_pawn_material(Us) == Constants.QueenValueMidgame
&& pos.piece_count(Us, PieceTypeC.QUEEN) == 1 && pos.piece_count(Them, PieceTypeC.ROOK) == 1
&& pos.piece_count(Them, PieceTypeC.PAWN) >= 1;
}
示例4: Endgame_KQKP
/// KQ vs KP. In general, a win for the stronger side, however, there are a few
/// important exceptions. Pawn on 7th rank, A,C,F or H file, with king next can
/// be a draw, so we scale down to distance between kings only.
internal static int Endgame_KQKP(int strongerSide, Position pos)
{
var weakerSide = strongerSide ^ 1;
Debug.Assert(pos.non_pawn_material(strongerSide) == Constants.QueenValueMidgame);
Debug.Assert(pos.piece_count(strongerSide, PieceTypeC.PAWN) == 0);
Debug.Assert(pos.non_pawn_material(weakerSide) == 0);
Debug.Assert(pos.piece_count(weakerSide, PieceTypeC.PAWN) == 1);
Square winnerKSq = pos.king_square(strongerSide);
Square loserKSq = pos.king_square(weakerSide);
Square pawnSq = pos.pieceList[weakerSide][PieceTypeC.PAWN][0];
var result = Constants.QueenValueEndgame - Constants.PawnValueEndgame + DistanceBonus[Utils.square_distance(winnerKSq, loserKSq)];
if ( Utils.square_distance(loserKSq, pawnSq) == 1
&& Utils.relative_rank_CS(weakerSide, pawnSq) == RankC.RANK_7)
{
File f = Utils.file_of(pawnSq);
if (f == FileC.FILE_A || f == FileC.FILE_C || f == FileC.FILE_F || f == FileC.FILE_H)
{
result = DistanceBonus[Utils.square_distance(winnerKSq, loserKSq)];
}
}
return strongerSide == pos.sideToMove ? result : -result;
}
示例5: Endgame_KRPPKRP
/// K, rook and two pawns vs K, rook and one pawn. There is only a single
/// pattern: If the stronger side has no passed pawns and the defending king
/// is actively placed, the position is drawish.
internal static ScaleFactor Endgame_KRPPKRP(Color strongerSide, Position pos)
{
Color weakerSide = strongerSide ^ 1;
Debug.Assert(pos.non_pawn_material(strongerSide) == Constants.RookValueMidgame);
Debug.Assert(pos.piece_count(strongerSide, PieceTypeC.PAWN) == 2);
Debug.Assert(pos.non_pawn_material(weakerSide) == Constants.RookValueMidgame);
Debug.Assert(pos.piece_count(weakerSide, PieceTypeC.PAWN) == 1);
Square wpsq1 = pos.pieceList[strongerSide][PieceTypeC.PAWN][0];
Square wpsq2 = pos.pieceList[strongerSide][PieceTypeC.PAWN][1];
Square bksq = pos.king_square(weakerSide);
// Does the stronger side have a passed pawn?
if (pos.pawn_is_passed(strongerSide, wpsq1)
|| pos.pawn_is_passed(strongerSide, wpsq2))
return ScaleFactorC.SCALE_FACTOR_NONE;
Rank r = Math.Max(Utils.relative_rank_CS(strongerSide, wpsq1), Utils.relative_rank_CS(strongerSide, wpsq2));
if (Utils.file_distance(bksq, wpsq1) <= 1
&& Utils.file_distance(bksq, wpsq2) <= 1
&& Utils.relative_rank_CS(strongerSide, bksq) > r)
{
switch (r)
{
case RankC.RANK_2: return (10);
case RankC.RANK_3: return (10);
case RankC.RANK_4: return (15);
case RankC.RANK_5: return (20);
case RankC.RANK_6: return (40);
default: Debug.Assert(false); break;
}
}
return ScaleFactorC.SCALE_FACTOR_NONE;
}
示例6: is_KXK
internal static bool is_KXK(int Us, Position pos)
{
var Them = (Us == ColorC.WHITE ? ColorC.BLACK : ColorC.WHITE);
return pos.non_pawn_material(Them) == ValueC.VALUE_ZERO && pos.piece_count(Them, PieceTypeC.PAWN) == 0
&& pos.non_pawn_material(Us) >= Constants.RookValueMidgame;
}
示例7: 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;
}
}
示例8: Endgame_KRKP
/// KR vs KP. This is a somewhat tricky endgame to evaluate precisely without
/// a bitbase. The function below returns drawish scores when the pawn is
/// far advanced with support of the king, while the attacking king is far
/// away.
internal static Value Endgame_KRKP(Color strongerSide, Position pos)
{
Color weakerSide = strongerSide ^ 1;
Debug.Assert(pos.non_pawn_material(strongerSide) == Constants.RookValueMidgame);
Debug.Assert(pos.piece_count(strongerSide, PieceTypeC.PAWN) == 0);
Debug.Assert(pos.non_pawn_material(weakerSide) == 0);
Debug.Assert(pos.piece_count(weakerSide, PieceTypeC.PAWN) == 1);
Square wksq, wrsq, bksq, bpsq;
int tempo = (pos.sideToMove == strongerSide ? 1 : 0);
wksq = pos.king_square(strongerSide);
wrsq = pos.pieceList[strongerSide][PieceTypeC.ROOK][0];
bksq = pos.king_square(weakerSide);
bpsq = pos.pieceList[weakerSide][PieceTypeC.PAWN][0];
if (strongerSide == ColorC.BLACK)
{
wksq = Utils.flip_S(wksq);
wrsq = Utils.flip_S(wrsq);
bksq = Utils.flip_S(bksq);
bpsq = Utils.flip_S(bpsq);
}
Square queeningSq = Utils.make_square(Utils.file_of(bpsq), RankC.RANK_1);
Value result;
// If the stronger side's king is in front of the pawn, it's a win
if (wksq < bpsq && Utils.file_of(wksq) == Utils.file_of(bpsq))
result = Constants.RookValueEndgame - (Utils.square_distance(wksq, bpsq));
// If the weaker side's king is too far from the pawn and the rook,
// it's a win
else if (Utils.square_distance(bksq, bpsq) - (tempo ^ 1) >= 3
&& Utils.square_distance(bksq, wrsq) >= 3)
result = Constants.RookValueEndgame - (Utils.square_distance(wksq, bpsq));
// If the pawn is far advanced and supported by the defending king,
// the position is drawish
else if (Utils.rank_of(bksq) <= RankC.RANK_3
&& Utils.square_distance(bksq, bpsq) == 1
&& Utils.rank_of(wksq) >= RankC.RANK_4
&& Utils.square_distance(wksq, bpsq) - tempo > 2)
result = (80 - Utils.square_distance(wksq, bpsq) * 8);
else
result = (200)
- (Utils.square_distance(wksq, bpsq + SquareC.DELTA_S) * 8)
+ (Utils.square_distance(bksq, bpsq + SquareC.DELTA_S) * 8)
+ (Utils.square_distance(bpsq, queeningSq) * 8);
return strongerSide == pos.sideToMove ? result : -result;
}
示例9: 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;
}
示例10: Endgame_KBPKN
/// K, bishop and a pawn vs K and knight. There is a single rule: 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.
internal static ScaleFactor Endgame_KBPKN(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.KnightValueMidgame);
Debug.Assert(pos.piece_count(weakerSide, PieceTypeC.KNIGHT) == 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 weakerKingSq = pos.king_square(weakerSide);
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;
return ScaleFactorC.SCALE_FACTOR_NONE;
}
示例11: Endgame_KBNK
/// Mate with KBN vs K. This is similar to KX vs K, but we have to drive the
/// defending king towards a corner square of the right color.
internal static Value Endgame_KBNK(Color strongerSide, Position pos)
{
Color weakerSide = strongerSide ^ 1;
Debug.Assert(pos.non_pawn_material(weakerSide) == ValueC.VALUE_ZERO);
Debug.Assert(pos.piece_count(weakerSide, PieceTypeC.PAWN) == ValueC.VALUE_ZERO);
Debug.Assert(pos.non_pawn_material(strongerSide) == Constants.KnightValueMidgame + Constants.BishopValueMidgame);
Debug.Assert(pos.piece_count(strongerSide, PieceTypeC.BISHOP) == 1);
Debug.Assert(pos.piece_count(strongerSide, PieceTypeC.KNIGHT) == 1);
Debug.Assert(pos.piece_count(strongerSide, PieceTypeC.PAWN) == 0);
Square winnerKSq = pos.king_square(strongerSide);
Square loserKSq = pos.king_square(weakerSide);
Square bishopSquare = pos.pieceList[strongerSide][PieceTypeC.BISHOP][0];
// kbnk_mate_table() tries to drive toward corners A1 or H8,
// if we have a bishop that cannot reach the above squares we
// mirror the kings so to drive enemy toward corners A8 or H1.
if (Utils.opposite_colors(bishopSquare, SquareC.SQ_A1))
{
winnerKSq = Utils.mirror(winnerKSq);
loserKSq = Utils.mirror(loserKSq);
}
Value result = ValueC.VALUE_KNOWN_WIN
+ DistanceBonus[Utils.square_distance(winnerKSq, loserKSq)]
+ KBNKMateTable[loserKSq];
return strongerSide == pos.sideToMove ? result : -result;
}
示例12: Endgame_KBBKN
internal static Value Endgame_KBBKN(Color strongerSide, Position pos)
{
Color weakerSide = strongerSide ^ 1;
Debug.Assert(pos.piece_count(strongerSide, PieceTypeC.BISHOP) == 2);
Debug.Assert(pos.non_pawn_material(strongerSide) == 2 * Constants.BishopValueMidgame);
Debug.Assert(pos.piece_count(weakerSide, PieceTypeC.KNIGHT) == 1);
Debug.Assert(pos.non_pawn_material(weakerSide) == Constants.KnightValueMidgame);
Debug.Assert(pos.pieces_PT(PieceTypeC.PAWN) == 0);
Value result = Constants.BishopValueEndgame;
Square wksq = pos.king_square(strongerSide);
Square bksq = pos.king_square(weakerSide);
Square nsq = pos.pieceList[weakerSide][PieceTypeC.KNIGHT][0];
// Bonus for attacking king close to defending king
result += (DistanceBonus[Utils.square_distance(wksq, bksq)]);
// Bonus for driving the defending king and knight apart
result += (Utils.square_distance(bksq, nsq) * 32);
// Bonus for restricting the knight's mobility
result += ((8 - Bitcount.popcount_1s_Max15(Position.attacks_from_KNIGHT(nsq))) * 8);
return strongerSide == pos.sideToMove ? result : -result;
}
示例13: update_safety_BLACK
internal int update_safety_BLACK(Position pos, int ksq)
{
this.kingSquaresBLACK = ksq;
this.castleRightsBLACK = pos.st.castleRights & CastleRightC.BLACK_ANY;
ulong pawns = (ulong)pos.piece_count(ColorC.BLACK, PieceTypeC.PAWN);
if (pawns > 0)
{
var minDist = this.minKPdistanceBLACK;
while ((Utils.DistanceRingsBB[ksq][minDist++] & pawns) != pawns)
{
}
}
if (((ksq >> 3) ^ (ColorC.BLACK * 7)) > RankC.RANK_4)
{
return this.kingSafetyBLACK = Utils.make_score(0, -16 * this.minKPdistanceBLACK);
}
var bonus = shelter_storm(ColorC.BLACK, pos, ksq);
// If we can castle use the bonus after the castle if is bigger
if ((pos.st.castleRights & CastleRightC.BLACK_OO) != 0)
{
bonus = Math.Max(bonus, shelter_storm(ColorC.BLACK, pos, (SquareC.SQ_G1 ^ (ColorC.BLACK * 56))));
}
if ((pos.st.castleRights & CastleRightC.BLACK_OOO) != 0)
{
bonus = Math.Max(bonus, shelter_storm(ColorC.BLACK, pos, (SquareC.SQ_C1 ^ (ColorC.BLACK * 56))));
}
return this.kingSafetyBLACK = Utils.make_score(bonus, -16 * this.minKPdistanceBLACK);
}
示例14: Endgame_KRKB
/// KR vs KB. This is very simple, and always returns drawish scores. The
/// score is slightly bigger when the defending king is close to the edge.
internal static Value Endgame_KRKB(Color strongerSide, Position pos)
{
Color weakerSide = strongerSide ^ 1;
Debug.Assert(pos.non_pawn_material(strongerSide) == Constants.RookValueMidgame);
Debug.Assert(pos.piece_count(strongerSide, PieceTypeC.PAWN) == 0);
Debug.Assert(pos.non_pawn_material(weakerSide) == Constants.BishopValueMidgame);
Debug.Assert(pos.piece_count(weakerSide, PieceTypeC.PAWN) == 0);
Debug.Assert(pos.piece_count(weakerSide, PieceTypeC.BISHOP) == 1);
Value result = (MateTable[pos.king_square(weakerSide)]);
return strongerSide == pos.sideToMove ? result : -result;
}
示例15: 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;
}