本文整理汇总了C#中Portfish.Position.non_pawn_material方法的典型用法代码示例。如果您正苦于以下问题:C# Position.non_pawn_material方法的具体用法?C# Position.non_pawn_material怎么用?C# Position.non_pawn_material使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Portfish.Position
的用法示例。
在下文中一共展示了Position.non_pawn_material方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: 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;
}
示例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_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;
}
示例4: 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;
}
示例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: evaluate_unstoppable_pawns
// evaluate_unstoppable_pawns() evaluates the unstoppable passed pawns for both sides, this is quite
// conservative and returns a winning score only when we are very sure that the pawn is winning.
private static int evaluate_unstoppable_pawns(Position pos, EvalInfo ei)
{
ulong b, b2, blockers, supporters, queeningPath, candidates;
int s, blockSq, queeningSquare;
int c, winnerSide, loserSide;
bool pathDefended, opposed;
int pliesToGo = 0, movesToGo, oppMovesToGo = 0, sacptg, blockersCount, minKingDist, kingptg, d;
int pliesToQueenWHITE = 256, pliesToQueenBLACK = 256, pliesToQueenWinner = 256;
// Step 1. Hunt for unstoppable passed pawns. If we find at least one,
// record how many plies are required for promotion.
for (c = ColorC.WHITE; c <= ColorC.BLACK; c++)
{
// Skip if other side has non-pawn pieces
if (pos.non_pawn_material(Utils.flip_C(c)) != 0)
{
continue;
}
b = ei.pi.passed_pawns(c);
while (b != 0)
{
s = Utils.pop_lsb(ref b);
queeningSquare = Utils.relative_square(c, Utils.make_square(Utils.file_of(s), RankC.RANK_8));
queeningPath = Utils.forward_bb(c, s);
// Compute plies to queening and check direct advancement
movesToGo = Utils.rank_distance(s, queeningSquare)
- (Utils.relative_rank_CS(c, s) == RankC.RANK_2 ? 1 : 0);
oppMovesToGo = Utils.square_distance(pos.king_square(Utils.flip_C(c)), queeningSquare)
- ((c != pos.sideToMove) ? 1 : 0);
pathDefended = ((ei.attackedBy[c][0] & queeningPath) == queeningPath);
if (movesToGo >= oppMovesToGo && !pathDefended)
{
continue;
}
// Opponent king cannot block because path is defended and position
// is not in check. So only friendly pieces can be blockers.
Debug.Assert(!pos.in_check());
Debug.Assert((queeningPath & pos.occupied_squares) == (queeningPath & pos.pieces_C(c)));
// Add moves needed to free the path from friendly pieces and retest condition
movesToGo += Bitcount.popcount_1s_Max15(queeningPath & pos.pieces_C(c));
if (movesToGo >= oppMovesToGo && !pathDefended)
{
continue;
}
pliesToGo = 2 * movesToGo - ((c == pos.sideToMove) ? 1 : 0);
if (c == ColorC.WHITE)
{
pliesToQueenWHITE = Math.Min(pliesToQueenWHITE, pliesToGo);
}
else
{
pliesToQueenBLACK = Math.Min(pliesToQueenBLACK, pliesToGo);
}
}
}
// Step 2. If either side cannot promote at least three plies before the other side then situation
// becomes too complex and we give up. Otherwise we determine the possibly "winning side"
if (Math.Abs(pliesToQueenWHITE - pliesToQueenBLACK) < 3)
{
return ScoreC.SCORE_ZERO;
}
winnerSide = (pliesToQueenWHITE < pliesToQueenBLACK ? ColorC.WHITE : ColorC.BLACK);
pliesToQueenWinner = (winnerSide == ColorC.WHITE) ? pliesToQueenWHITE : pliesToQueenBLACK;
loserSide = Utils.flip_C(winnerSide);
// Step 3. Can the losing side possibly create a new passed pawn and thus prevent the loss?
b = candidates = pos.pieces_PTC(PieceTypeC.PAWN, loserSide);
while (b != 0)
{
s = Utils.pop_lsb(ref b);
// Compute plies from queening
queeningSquare = Utils.relative_square(loserSide, Utils.make_square(Utils.file_of(s), RankC.RANK_8));
movesToGo = Utils.rank_distance(s, queeningSquare)
- ((Utils.relative_rank_CS(loserSide, s) == RankC.RANK_2) ? 1 : 0);
pliesToGo = 2 * movesToGo - ((loserSide == pos.sideToMove) ? 1 : 0);
// Check if (without even considering any obstacles) we're too far away or doubled
if ((pliesToQueenWinner + 3 <= pliesToGo)
|| ((Utils.forward_bb(loserSide, s) & pos.pieces_PTC(PieceTypeC.PAWN, loserSide)) != 0))
{
Utils.xor_bit(ref candidates, s);
}
}
// If any candidate is already a passed pawn it _may_ promote in time. We give up.
//.........这里部分代码省略.........
示例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: search
//.........这里部分代码省略.........
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))
{
ss[ssPos].currentMove = MoveC.MOVE_NULL;
// Null move dynamic reduction based on depth
Depth R = 3 * DepthC.ONE_PLY + depth / 4;
// Null move dynamic reduction based on value
if (eval - Constants.PawnValueMidgame > beta)
{
R += DepthC.ONE_PLY;
}
if (st == null)
{
st = StateInfoBroker.GetObject();
}
pos.do_null_move(st);
ss[ssPos + 1].skipNullMove = 1;
nullValue = depth - R < DepthC.ONE_PLY ? -qsearch(NodeTypeC.NonPV, false, pos, ss, ssPos + 1, -beta, -alpha, DepthC.DEPTH_ZERO)
: -search(NodeTypeC.NonPV, pos, ss, ssPos + 1, -beta, -alpha, depth - R);
ss[ssPos + 1].skipNullMove = 0;
pos.undo_null_move(st);
示例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;
}