summaryrefslogtreecommitdiff
path: root/src/eval.c
diff options
context:
space:
mode:
authorScott Gasch <[email protected]>2026-10-09 14:18:52 -0700
committerScott Gasch <[email protected]>2026-10-09 14:18:52 -0700
commitfbdcb9d76dd2444d8bc631331eaeb9435cc247f8 (patch)
tree602ab360462d6f23188ba51f962c4abb2dc6c7e5 /src/eval.c
parent73b4afb12abf7cc442831dea42b41b63a2ce07be (diff)
* Grab bag of eval.c changes.
* Don't bother not hashing when moves are pruned. * Prune moves move librerally with LMP. Inexplicably, this is slightly shallower than HEAD (despite pruning MORE). It may be because it is slightly slower. It consistently beats HEAD in match_play.py though (3x now).
Diffstat (limited to 'src/eval.c')
-rw-r--r--src/eval.c298
1 files changed, 131 insertions, 167 deletions
diff --git a/src/eval.c b/src/eval.c
index e102daa..50a5e6f 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -95,7 +95,7 @@ static ULONG REDUCED_MATERIAL_DOWN_SCALER[32] =
0, 0, 0, 0, 0, 0, 0, 0,
// Rm 3m/Q 2R R2m 4m/Qm 2Rm R3m/QR Q2m
- 0, 1, 1, 1, 1, 1, 2, 3,
+ 0, 1, 1, 1, 2, 2, 2, 3,
// 2R2m R4m/QRm Q3m 2R3m/ QR2m Q4m 2R4m/ QR3m
// Q2R Q2Rm
@@ -385,14 +385,13 @@ SCORE RACER_WINS_RACE = +300;
static SCORE UNDEVELOPED_MINORS_IN_OPENING[5] =
{// 0 1 2 3 4
- 0, -8, -14, -20, -23
+ 0, -14, -18, -24, -30
};
//
// Bishop eval terms
// ---------------------------------------------------------------------------
//
-static SCORE BISHOP_OVER_KNIGHT_IN_ENDGAME = +33;
//
// "The bishop pair has an average value of half a pawn (more when the
@@ -527,6 +526,7 @@ static SCORE KNIGHT_IN_CLOSED_POSITION[33] =
static SCORE ROOK_ON_FULL_OPEN = 18;
static SCORE ROOK_ON_HALF_OPEN_WITH_ENEMY = 9;
static SCORE ROOK_ON_HALF_OPEN_WITH_FRIEND = 10;
+
// Cache of the three constants above, indexed [friend pawn on file?]
// [enemy pawn on file?] so _EvalRook's hot path is a single array read
// instead of rebuilding a local array every call. Not `static const`
@@ -553,18 +553,6 @@ static SCORE ROOK_WITH_FRIEND_PASSER = 10;
static const BITBOARD BBROOK_7TH_RANK[2] = { BBRANK22, BBRANK77 }; // [BLACK], [WHITE]
static SCORE ROOK_ON_SEVENTH_BONUS = 9;
-static SCORE ROOK_BEHIND_PASSER_BY_PASSER_RANK[2][9] =
-{// 0 1 2 3 4 5 6 7 8
- { +0, +0, +25, +17, +12, +6, +1, +0, +0 }, // black
- { +0, +0, +0, +1, +6, +12, +17, +25, +0 } // white
-};
-
-static SCORE ROOK_LEADS_PASSER_BY_PASSER_RANK[2][9] =
-{// 0 1 2 3 4 5 6 7 8
- { +0, +0, -22, -16, -13, -9, -5, -3, +0 }, // black
- { +0, +0, -3, -5, -9, -13, -16, -22, +0 } // white
-};
-
static SCORE ROOK_VALUE_AS_PAWNS_COME_OFF[17] =
{// 0 1 2 3 4 5 6 7 8
+55, +51, +44, +38, +33, +27, +22, +16, +7,
@@ -598,7 +586,6 @@ static SCORE ROOK_MOBILITY_BY_SQUARES[15] =
// ---------------------------------------------------------------------------
//
-
//
// A queen can move to between 0..27 squares
// -----------------------------------------
@@ -733,7 +720,7 @@ static SCORE KING_TO_CENTER[128] =
// the stay-home bonus now uses this same threshold, so "safety scored"
// and "stay-home bonus applies" are exactly the same condition.
#define DO_KING_SAFETY_THRESHOLD \
- (VALUE_ROOK + VALUE_BISHOP + VALUE_KING + 1)
+ (VALUE_ROOK + VALUE_BISHOP + VALUE_BISHOP + VALUE_KING)
static ULONG KING_COUNTER_BY_ATTACK_PATTERN[32] =
{
@@ -798,7 +785,7 @@ static SCORE KING_SAFETY_BY_COUNTER[42] =
// another ~33% to -14/count.
static SCORE KING_QUEEN_PROXIMITY_DANGER[7] =
{// 0 1 2 3 4 5 6
- +0, -14, -28, -42, -56, -70, -84
+ +0, -10, -18, -25, -32, -39, -55
};
static SCORE KING_MISSING_ONE_CASTLE_OPTION = -23;
@@ -942,7 +929,6 @@ static DNA_BASE_SIZE g_EvalDNA[] = {
DNA_ARRAY(PASSER_BONUS_AS_MATERIAL_COMES_OFF),
DNA_VAR(RACER_WINS_RACE),
DNA_ARRAY(UNDEVELOPED_MINORS_IN_OPENING),
- DNA_VAR(BISHOP_OVER_KNIGHT_IN_ENDGAME),
DNA_VAR(BISHOP_PAIR_BONUS),
DNA_ARRAY(STATIONARY_PAWN_ON_BISHOP_COLOR),
DNA_ARRAY(TRANSIENT_PAWN_ON_BISHOP_COLOR),
@@ -961,8 +947,6 @@ static DNA_BASE_SIZE g_EvalDNA[] = {
DNA_VAR(ROOK_WITH_ENEMY_PASSER),
DNA_VAR(ROOK_WITH_FRIEND_PASSER),
DNA_VAR(ROOK_ON_SEVENTH_BONUS),
- DNA_MATRIX(ROOK_BEHIND_PASSER_BY_PASSER_RANK),
- DNA_MATRIX(ROOK_LEADS_PASSER_BY_PASSER_RANK),
DNA_ARRAY(ROOK_VALUE_AS_PAWNS_COME_OFF),
DNA_VAR(ROOK_CONNECTED_VERT),
DNA_VAR(ROOK_CONNECTED_HORIZ),
@@ -2773,9 +2757,19 @@ Return value:
{
+0, +6, +3, +1, 0, 0, 0, 0
};
- static SCORE KingFileDefects[3] =
+ // Indexed by (fOwn << 1) | fEnemy: 0=open (neither side has a pawn
+ // here), 1=half-open toward the enemy only (their pawn gone, ours
+ // still there), 2=half-open toward us only (ours gone, theirs still
+ // there), 3=closed (both present). Previously collapsed 1 and 2
+ // into a single "half-open" bucket (uCountPerFile[WHITE][u]>0) +
+ // (uCountPerFile[BLACK][u]>0) summed to 1 either way) -- split
+ // 2026-10-08 since the two cases aren't symmetric (an enemy pawn
+ // left behind is a real storming threat already priced by
+ // KingStormingPawnDefects below, whereas our own pawn being the
+ // only one left is comparatively mild).
+ static SCORE KingFileDefects[4] =
{
- -10, -5, 0
+ -18, -10, -5, 0
};
// Old code's edge-file (a/h) kicker was a flat +1 counter-unit;
// scaled by the same filestormopenfile-derived factor.
@@ -2796,14 +2790,11 @@ Return value:
continue;
}
u = FILE(cFileSq) + 1;
- v = (pHash->uCountPerFile[WHITE][u] > 0) +
- (pHash->uCountPerFile[BLACK][u] > 0);
- ASSERT((v >= 0) && (v <= 2));
+ v = ((pHash->uCountPerFile[uColor][u] > 0) << 1) |
+ (pHash->uCountPerFile[ufColor][u] > 0);
+ ASSERT(v <= 3);
iScore += KingFileDefects[v];
- if ((v < 2) && ((u == 1) || (u == 8)))
- {
- iScore += KING_FILE_EDGE_KICKER;
- }
+ iScore += ((v != 3) && ((u == 1) || (u == 8))) * KING_FILE_EDGE_KICKER;
bb = pos->bbPawns[ufColor] & BBFILE[u - 1];
if (bb)
{
@@ -5100,19 +5091,6 @@ Return value:
ASSERT(IS_ON_BOARD(cKing));
ASSERT(IS_KING(pos->rgSquare[cKing].pPiece));
- // Encourage enemy king tropism, but not too early.
- if ((TRUE == pos->fCastled[uColor]) || (pos->uMinorsAtHome[uColor] <= 1))
- {
- u = DISTANCE(c, cKing);
- ASSERT((u <= 7) && (u > 0));
- EVAL_TERM(uColor,
- QUEEN,
- c,
- pos->iScore[uColor],
- QUEEN_KING_TROPISM[u],
- "enemy king tropism");
- }
-
//
// Do queen mobility (and update attack tables) -- two-pass
// rook-direction/bishop-direction magic lookups, board_
@@ -5134,85 +5112,82 @@ Return value:
// one case that's a *fewer*-cases asymmetry versus bishop, not
// more), so the enemy side of each pass's continue-set is empty.
//
- {
- BITBOARD bbEnemyOcc = _BuildFriendlySideBB(pos, xColor);
- BITBOARD bbEnemyGE = pos->bbPieces[xColor][QUEEN] |
- COOR_TO_BB(cKing);
- //
- // Enemy king attacks are also unsafe for the queen -- a free
- // O(1) table lookup by king square, independent of eval order
- // (unlike the enemy minor/rook attacks above, which do need
- // both colors' knight/bishop/rook passes to finish first, and
- // already have by queen's turn: see the eval call order in
- // Eval() below). Only unsafe when the queen wouldn't be
- // recaptured by something of our own first -- if a friendly
- // pawn/minor/rook already covers that square, the king can't
- // just take the queen for free. Every one of those tables (ours
- // AND the enemy's) is fully populated by now: pawns, minors,
- // and rooks all run their own eval pass before queen does.
- //
- BITBOARD bbUnsafeForQueen = pos->bbPawnAttacks[xColor] |
- pos->bbMinorAttacks[xColor] |
- pos->bbRookAttacks[xColor] |
- (g_KingAttacksBB[cKing] &
- ~(pos->bbPawnAttacks[uColor] |
- pos->bbMinorAttacks[uColor] |
- pos->bbRookAttacks[uColor]));
- BITBOARD bbAttackTotal = 0;
- BITBOARD bbXrayAccum = 0;
- BITBOARD bbMobility = 0;
- ULONG uPass;
+ BITBOARD bbEnemyOcc = _BuildFriendlySideBB(pos, xColor);
+ BITBOARD bbEnemyGE = pos->bbPieces[xColor][QUEEN] |
+ COOR_TO_BB(cKing);
+ //
+ // Enemy king attacks are also unsafe for the queen -- a free
+ // O(1) table lookup by king square, independent of eval order
+ // (unlike the enemy minor/rook attacks above, which do need
+ // both colors' knight/bishop/rook passes to finish first, and
+ // already have by queen's turn: see the eval call order in
+ // Eval() below). Only unsafe when the queen wouldn't be
+ // recaptured by something of our own first -- if a friendly
+ // pawn/minor/rook already covers that square, the king can't
+ // just take the queen for free. Every one of those tables (ours
+ // AND the enemy's) is fully populated by now: pawns, minors,
+ // and rooks all run their own eval pass before queen does.
+ //
+ BITBOARD bbUnsafeForQueen = pos->bbPawnAttacks[xColor] |
+ pos->bbMinorAttacks[xColor] |
+ pos->bbRookAttacks[xColor] |
+ (g_KingAttacksBB[cKing] &
+ ~(pos->bbPawnAttacks[uColor] |
+ pos->bbMinorAttacks[uColor] |
+ pos->bbRookAttacks[uColor]));
+ BITBOARD bbAttackTotal = 0;
+ BITBOARD bbXrayAccum = 0;
+ BITBOARD bbMobility = 0;
- for (uPass = 0; uPass < 2; uPass++)
- {
- BITBOARD bbFriendContinue = (uPass == 0) ?
- (pos->bbPieces[uColor][ROOK] | pos->bbPieces[uColor][QUEEN]) :
- (pos->bbPieces[uColor][BISHOP] | pos->bbPieces[uColor][QUEEN]);
- BITBOARD bbInitial = (uPass == 0) ?
- _RookAttacksBB(c, pos->bbOccupied) :
- _BishopAttacksBB(c, pos->bbOccupied);
- BITBOARD bbExclude = 0;
- BITBOARD bbSeen = 0;
- BITBOARD bbLayer = bbInitial;
- BITBOARD bbFirstLayerMask = 0;
+ ULONG uPass;
+ for (uPass = 0; uPass < 2; uPass++)
+ {
+ BITBOARD bbFriendContinue = (uPass == 0) ?
+ (pos->bbPieces[uColor][ROOK] | pos->bbPieces[uColor][QUEEN]) :
+ (pos->bbPieces[uColor][BISHOP] | pos->bbPieces[uColor][QUEEN]);
+ BITBOARD bbInitial = (uPass == 0) ?
+ _RookAttacksBB(c, pos->bbOccupied) :
+ _BishopAttacksBB(c, pos->bbOccupied);
+ BITBOARD bbExclude = 0;
+ BITBOARD bbSeen = 0;
+ BITBOARD bbLayer = bbInitial;
+ BITBOARD bbFirstLayerMask = 0;
- bbAttackTotal |= bbInitial;
+ bbAttackTotal |= bbInitial;
- for (;;)
- {
- BITBOARD bbNew = bbLayer & ~bbSeen;
- BITBOARD bbBlockersHere = bbNew & pos->bbOccupied;
- BITBOARD bbEmptyHere = bbNew & ~pos->bbOccupied;
- BITBOARD bbFriendContinueHere = bbBlockersHere &
- bbFriendContinue;
- BITBOARD bbEnemyGEHere = bbBlockersHere & bbEnemyGE;
- BITBOARD bbEnemyLEHere = bbBlockersHere & bbEnemyOcc &
- ~bbEnemyGEHere;
+ for (;;)
+ {
+ BITBOARD bbNew = bbLayer & ~bbSeen;
+ BITBOARD bbBlockersHere = bbNew & pos->bbOccupied;
+ BITBOARD bbEmptyHere = bbNew & ~pos->bbOccupied;
+ BITBOARD bbFriendContinueHere = bbBlockersHere &
+ bbFriendContinue;
+ BITBOARD bbEnemyGEHere = bbBlockersHere & bbEnemyGE;
+ BITBOARD bbEnemyLEHere = bbBlockersHere & bbEnemyOcc &
+ ~bbEnemyGEHere;
- bbSeen |= bbNew;
- bbXrayAccum |= (bbNew & bbFirstLayerMask);
- bbFirstLayerMask = ~(BITBOARD)0;
+ bbSeen |= bbNew;
+ bbXrayAccum |= (bbNew & bbFirstLayerMask);
+ bbFirstLayerMask = ~(BITBOARD)0;
- bbMobility |= (bbEmptyHere & ~bbUnsafeForQueen) |
- bbEnemyGEHere |
- (bbEnemyLEHere & ~bbUnsafeForQueen);
+ bbMobility |= (bbEmptyHere & ~bbUnsafeForQueen) |
+ bbEnemyGEHere |
+ (bbEnemyLEHere & ~bbUnsafeForQueen);
- if (!bbFriendContinueHere)
- {
- break;
- }
- bbExclude |= bbFriendContinueHere;
- bbLayer = (uPass == 0) ?
- _RookAttacksBB(c, pos->bbOccupied & ~bbExclude) :
- _BishopAttacksBB(c, pos->bbOccupied & ~bbExclude);
+ if (!bbFriendContinueHere)
+ {
+ break;
}
+ bbExclude |= bbFriendContinueHere;
+ bbLayer = (uPass == 0) ?
+ _RookAttacksBB(c, pos->bbOccupied & ~bbExclude) :
+ _BishopAttacksBB(c, pos->bbOccupied & ~bbExclude);
}
- pos->bbQueenAttacks[uColor] |= bbAttackTotal;
- pos->bbQueenXrayAttacks[uColor] |= bbXrayAccum;
-
- uTotalMobility = FastCountBits(bbMobility);
}
+ pos->bbQueenAttacks[uColor] |= bbAttackTotal;
+ pos->bbQueenXrayAttacks[uColor] |= bbXrayAccum;
+ uTotalMobility = FastCountBits(bbMobility);
ASSERT(uTotalMobility <= 27);
EVAL_TERM(uColor,
QUEEN,
@@ -5353,6 +5328,8 @@ Return value:
(SCORE)KING_COUNTER_BY_ATTACK_PATTERN[bvPattern];
// Count how many ring squares are attacked by the enemy queen.
+ // Note: we remove queen-king tropism bonus from EvalQueen in
+ // favor of this.
uQueenNearKing = FastCountBits(
bbRing & (pos->bbQueenAttacks[xColor] | pos->bbQueenXrayAttacks[xColor])
);
@@ -5495,12 +5472,7 @@ Return value:
pDump->uFileStormStormingPawn;
#endif
- // Unconditional within this whole function now -- KEEP_KING_AT_HOME_
- // THRESHOLD (a separate, stricter bar than DO_KING_SAFETY_THRESHOLD)
- // used to gate this specifically, leaving a dead band between the
- // two. Retired; see DO_KING_SAFETY_THRESHOLD's comment.
- iSafety += KING_INITIAL_LOCATION_SCALE *
- KING_EVAL_INITIAL_LOCATION[uColor][c];
+ iSafety += KING_INITIAL_LOCATION_SCALE * KING_EVAL_INITIAL_LOCATION[uColor][c];
#ifdef KING_DEFECT_DUMP
pDump->uInitialCounterByLocation =
(ULONG)KING_EVAL_INITIAL_LOCATION[uColor][c];
@@ -5607,8 +5579,7 @@ Return value:
0,
ILLEGAL_COOR,
pos->iScore[uColor],
- (SCORE)(((uRightsRemaining > 0) *
- UNDEVELOPED_MINORS_IN_OPENING[pos->uMinorsAtHome[uColor]] *
+ (SCORE)((UNDEVELOPED_MINORS_IN_OPENING[pos->uMinorsAtHome[uColor]] *
(SCORE)uDevelopmentScaler) / 8),
"development");
@@ -5798,7 +5769,7 @@ Return value:
// this king out.
u = pos->uNonPawnMaterial[xColor];
ASSERT(u >= VALUE_KING);
- if (u >= DO_KING_SAFETY_THRESHOLD)
+ if (u > DO_KING_SAFETY_THRESHOLD)
{
iKingScore = _EvalKingSafety(pos, c, pHash, ctx, uColor, xColor, bbRing);
}
@@ -6379,7 +6350,7 @@ Return value:
// KNB vs KRP - the side with the pawn has the winning chances.
//
ULONG uAheadPawnCount = FastCountBits(pos->bbPawns[uAhead]);
- ULONG uInverseBehindPieceCount = 9 - MINU(9, TotalNonPawnCount(pos, uBehind));
+ ULONG uInverseBehindPieceCount = 11 - MINU(9, TotalNonPawnCount(pos, uBehind));
//
// "No mating material" here means the SAME lone-minor-piece test
// SideHasWinningChances (above) already uses: king + exactly one
@@ -6426,6 +6397,7 @@ Return value:
"don't trade pawns");
}
+#if 0
static void
_EvalLookForDanger(IN OUT SEARCHER_THREAD_CONTEXT *ctx)
/**
@@ -6479,6 +6451,7 @@ Return value:
}
}
}
+#endif
static void
@@ -6704,7 +6677,7 @@ Return value:
FLAG FORCEINLINE
SideHasWinningChances(IN POSITION *pos,
- IN ULONG uSide)
+ IN ULONG uColor)
/**
Routine description:
@@ -6744,20 +6717,13 @@ Return value:
**/
{
- ULONG uEnemy = FLIP(uSide);
+ ULONG xColor = FLIP(uColor);
+ ASSERT(IS_VALID_COLOR(uColor) && IS_VALID_COLOR(xColor));
INT iMajorDiff;
INT iMinorDiff;
- ULONG uSideKnights;
- ULONG uSideBishops;
-
- // uSide's bishop count is needed by the wrong-bishop-fortress check
- // immediately below (which must run BEFORE the "any pawn -> TRUE"
- // early return that follows it) and is reused again later by the
- // lone-minor/iMinorDiff/two-knights checks -- compute it once, up
- // front.
- uSideBishops = FastCountBits(pos->bbPieces[uSide][BISHOP]);
+ ULONG uColorKnights;
+ ULONG uColorBishops = FastCountBits(pos->bbPieces[uColor][BISHOP]);
- //
// Wrong-bishop rook-pawn fortress: a lone bishop + rook-pawn(s) (all
// on the A- or H-file), with the bishop unable to control the
// promotion square, is a known draw once the defending bare king
@@ -6777,43 +6743,42 @@ Return value:
// shrink), never used as a search-terminating bound the way
// recogn.c's tighter dist<=1-only version is, so a wrong FALSE here
// is tolerable in a way it would not be in recogn.c.
- //
- if ((2 == TotalNonPawnCount(pos, uSide)) &&
- (1 == uSideBishops) &&
- (1 == TotalNonPawnCount(pos, uEnemy)) &&
- (0 == FastCountBits(pos->bbPawns[uEnemy])) &&
- (FastCountBits(pos->bbPawns[uSide]) > 0))
+ if ((2 == TotalNonPawnCount(pos, uColor)) &&
+ (1 == uColorBishops) &&
+ (1 == TotalNonPawnCount(pos, xColor)) &&
+ (0 == FastCountBits(pos->bbPawns[xColor])) &&
+ (FastCountBits(pos->bbPawns[uColor]) > 0))
{
- BITBOARD bbPawns = pos->bbPawns[uSide];
+ BITBOARD bbPawns = pos->bbPawns[uColor];
COOR cPromote = ILLEGAL_COOR;
+ ULONG uColorWhiteSquareBishopCount = WhiteSqBishopCount(pos, uColor);
- if (uSide == WHITE)
+ if (uColor == WHITE)
{
- if (!(bbPawns & ~BBFILE[A]) && (WhiteSqBishopCount(pos, WHITE) == 0))
+ if (!(bbPawns & ~BBFILE[A]) && (uColorWhiteSquareBishopCount == 0))
{
cPromote = A8;
}
- else if (!(bbPawns & ~BBFILE[H]) && (WhiteSqBishopCount(pos, WHITE) == 1))
+ else if (!(bbPawns & ~BBFILE[H]) && (uColorWhiteSquareBishopCount == 1))
{
cPromote = H8;
}
}
else
{
- if (!(bbPawns & ~BBFILE[A]) && (WhiteSqBishopCount(pos, BLACK) == 1))
+ if (!(bbPawns & ~BBFILE[A]) && (uColorWhiteSquareBishopCount == 1))
{
cPromote = A1;
}
- else if (!(bbPawns & ~BBFILE[H]) && (WhiteSqBishopCount(pos, BLACK) == 0))
+ else if (!(bbPawns & ~BBFILE[H]) && (uColorWhiteSquareBishopCount == 0))
{
cPromote = H1;
}
}
-
if (IS_ON_BOARD(cPromote))
{
- COOR cWeakKing = KingPosition(pos, uEnemy);
- int iTempo = (pos->uToMove == uEnemy) ? 1 : 0;
+ COOR cWeakKing = KingPosition(pos, xColor);
+ int iTempo = (pos->uToMove == xColor) ? 1 : 0;
if (((int)DISTANCE(cWeakKing, cPromote) - iTempo) < 1)
{
return(FALSE);
@@ -6825,7 +6790,7 @@ Return value:
// A pawn always gives some winning chances (it can always try to
// queen with support) -- nothing below applies.
//
- if (FastCountBits(pos->bbPawns[uSide]) > 0)
+ if (FastCountBits(pos->bbPawns[uColor]) > 0)
{
return(TRUE);
}
@@ -6833,15 +6798,15 @@ Return value:
// uSide's knight count is read twice below (the lone-minor check
// and the two-knights check); uSideBishops was already computed
// above.
- uSideKnights = FastCountBits(pos->bbPieces[uSide][KNIGHT]);
+ uColorKnights = FastCountBits(pos->bbPieces[uColor][KNIGHT]);
//
// No pawns and the only piece besides the king is a single minor:
// never enough material to force mate (K+N or K+B vs anything is
// never a forced win on material alone).
//
- if ((2 == TotalNonPawnCount(pos, uSide)) &&
- (1 == (uSideKnights + uSideBishops)))
+ if ((2 == TotalNonPawnCount(pos, uColor)) &&
+ (1 == (uColorKnights + uColorBishops)))
{
return(FALSE);
}
@@ -6852,15 +6817,15 @@ Return value:
// force a win either -- e.g. KRB vs KR can be held by the
// defender with correct play.
//
- iMajorDiff = (INT)(FastCountBits(pos->bbPieces[uSide][ROOK]) +
- 2 * FastCountBits(pos->bbPieces[uSide][QUEEN])) -
- (INT)(FastCountBits(pos->bbPieces[uEnemy][ROOK]) +
- 2 * FastCountBits(pos->bbPieces[uEnemy][QUEEN]));
+ iMajorDiff = (INT)(FastCountBits(pos->bbPieces[uColor][ROOK]) +
+ 2 * FastCountBits(pos->bbPieces[uColor][QUEEN])) -
+ (INT)(FastCountBits(pos->bbPieces[xColor][ROOK]) +
+ 2 * FastCountBits(pos->bbPieces[xColor][QUEEN]));
if ((1 == iMajorDiff) || (-1 == iMajorDiff))
{
- iMinorDiff = (INT)(FastCountBits(pos->bbPieces[uEnemy][KNIGHT]) +
- FastCountBits(pos->bbPieces[uEnemy][BISHOP])) -
- (INT)(uSideKnights + uSideBishops);
+ iMinorDiff = (INT)(FastCountBits(pos->bbPieces[xColor][KNIGHT]) +
+ FastCountBits(pos->bbPieces[xColor][BISHOP])) -
+ (INT)(uColorKnights + uColorBishops);
if (iMajorDiff == iMinorDiff)
{
return(FALSE);
@@ -6875,16 +6840,15 @@ Return value:
// excluded, since that has one bishop, not zero) -- both are
// genuine, if sometimes technique-heavy, forced wins.
//
- if ((2 == uSideKnights) &&
- (0 == uSideBishops) &&
- (0 == FastCountBits(pos->bbPieces[uSide][ROOK])) &&
- (0 == FastCountBits(pos->bbPieces[uSide][QUEEN])) &&
- (1 == TotalNonPawnCount(pos, uEnemy)) &&
- (0 == FastCountBits(pos->bbPawns[uEnemy])))
+ if ((2 == uColorKnights) &&
+ (0 == uColorBishops) &&
+ (0 == FastCountBits(pos->bbPieces[uColor][ROOK])) &&
+ (0 == FastCountBits(pos->bbPieces[uColor][QUEEN])) &&
+ (1 == TotalNonPawnCount(pos, xColor)) &&
+ (0 == FastCountBits(pos->bbPawns[xColor])))
{
return(FALSE);
}
-
return(TRUE);
}