summaryrefslogtreecommitdiff
path: root/src/generate.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/generate.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/generate.c')
-rw-r--r--src/generate.c91
1 files changed, 25 insertions, 66 deletions
diff --git a/src/generate.c b/src/generate.c
index 89796b4..fdfdc79 100644
--- a/src/generate.c
+++ b/src/generate.c
@@ -4740,40 +4740,35 @@ Return value:
//
sKillers[0].mv = ctx->mvKiller[uPly][0];
sKillers[0].uBonus = FIRST_KILLER;
+ sKillers[0].uBonus |=
+ (SORT_THESE_FIRST * (IS_KILLERMATE_MOVE(sKillers[0].mv) != 0));
sKillers[1].mv = ctx->mvKiller[uPly][1];
sKillers[1].uBonus = SECOND_KILLER;
+ sKillers[1].uBonus |=
+ (SORT_THESE_FIRST * (IS_KILLERMATE_MOVE(sKillers[1].mv) != 0));
sKillers[2].mv.uMove = sKillers[3].mv.uMove = 0;
if (uPly > 1)
{
sKillers[2].mv = ctx->mvKiller[uPly - 2][0];
sKillers[2].uBonus = THIRD_KILLER;
+ sKillers[2].uBonus |=
+ (SORT_THESE_FIRST * (IS_KILLERMATE_MOVE(sKillers[2].mv) != 0));
sKillers[3].mv = ctx->mvKiller[uPly - 2][1];
sKillers[3].uBonus = FOURTH_KILLER;
- }
- sKillers[0].uBonus |=
- (SORT_THESE_FIRST * (IS_KILLERMATE_MOVE(sKillers[0].mv) != 0));
- sKillers[1].uBonus |=
- (SORT_THESE_FIRST * (IS_KILLERMATE_MOVE(sKillers[1].mv) != 0));
- sKillers[2].uBonus |=
- (SORT_THESE_FIRST * (IS_KILLERMATE_MOVE(sKillers[2].mv) != 0));
- sKillers[3].uBonus |=
- (SORT_THESE_FIRST * (IS_KILLERMATE_MOVE(sKillers[3].mv) != 0));
+ sKillers[3].uBonus |=
+ (SORT_THESE_FIRST * (IS_KILLERMATE_MOVE(sKillers[3].mv) != 0));
- // EXPERIMENT: countermove-match tier. Precompute the previous
- // move's countermove-table index once per node (mirrors killer
- // precompute above) so the per-move loop below is just an
- // IS_SAME_MOVE check, not a recompute.
- fHaveCounterMove = FALSE;
- if ((uPly > 0) && (0 != (ctx->sPlyInfo[uPly - 1]).mv.uMove))
- {
- uCounterMoveIdx = MOVE_TO_INDEX((ctx->sPlyInfo[uPly - 1]).mv);
- uCounterMoveContKey = MOVE_TO_CONT_KEY((ctx->sPlyInfo[uPly - 1]).mv);
- fHaveCounterMove = TRUE;
+ // EXPERIMENT: countermove-match tier. Precompute the previous
+ // move's countermove-table index once per node (mirrors killer
+ // precompute above) so the per-move loop below is just an
+ // IS_SAME_MOVE check, not a recompute.
+ MOVE mvLast = (ctx->sPlyInfo[uPly - 1]).mv;
+ fHaveCounterMove = (0 != mvLast.uMove);
+ uCounterMoveIdx = MOVE_TO_INDEX(mvLast);
+ uCounterMoveContKey = MOVE_TO_CONT_KEY(mvLast);
}
- //
// Score moves
- //
ASSERT(MOVE_COUNT(ctx, uPly) <= MAX_MOVES_PER_PLY);
for (u = pStack->uBegin[uPly];
u < pStack->uEnd[uPly];
@@ -4846,25 +4841,6 @@ Return value:
ASSERT(s > 0);
ASSERT((s & STRIP_OFF_FLAGS) < VALUE_KING);
}
-#ifdef DEBUG
- else
- {
- // 2026-10-04: no longer subtracts VALUE_KING here.
- // That made this capture's stored iValue differ
- // between DEBUG and release builds for no checked
- // reason (the ASSERT it fed was tautological --
- // already true by construction, this being the
- // else of `s >= 0` above) -- a silent landmine:
- // ComputeMoveScore/DecodeMoveValueEstimate's
- // MOVE_SCORING_NORMAL case trusts this value
- // directly for a losing capture (MIN0(iRawValue)),
- // so a DEBUG build fed EstimateHangingMaterialCp a
- // ~VALUE_KING-inflated "hang" estimate for an
- // ordinary losing capture, release builds never
- // saw it. The real check is the bound just above.
- ASSERT((s & STRIP_OFF_FLAGS) > -VALUE_KING);
- }
-#endif
}
//
@@ -5073,8 +5049,8 @@ Return value:
ASSERT(s >= SORT_THESE_FIRST);
ASSERT(s > 0);
ASSERT((s & STRIP_OFF_FLAGS) < VALUE_KING);
- }
- else if (s == 0)
+ }
+ else if (s == 0)
{
// Even capture -- can't be capturing w/ king
ASSERT(!IS_KING(mv.pMoved));
@@ -5083,23 +5059,6 @@ Return value:
s |= FIRST_KILLER;
ASSERT(s > 0);
}
-#ifdef DEBUG
- else
- {
- // Losing capture. No `s -= VALUE_KING` here --
- // same landmine, same fix as _ScoreAllMoves' twin
- // of this block (2026-10-04): currently harmless in
- // practice (DecodeMoveValueEstimate's
- // MOVE_SCORING_ESCAPE case recomputes a capture's
- // value straight from mv.pCaptured/mv.pMoved rather
- // than trusting iValue), but there's no reason for
- // this capture's stored iValue to differ between
- // DEBUG and release builds when nothing checks the
- // difference.
- ASSERT(!IS_KING(mv.pMoved));
- ASSERT((s & STRIP_OFF_FLAGS) > -VALUE_KING);
- }
-#endif
}
//
@@ -5117,7 +5076,7 @@ Return value:
else
{
s = g_iPSQT[mv.pMoved][mv.cTo]; // 0..1000
- if (!IS_KING(mv.pMoved))
+ if (!IS_KING(mv.pMoved))
{
// 0..2400
s += (VALUE_QUEEN - PIECE_VALUE(mv.pMoved)) * 4;
@@ -5128,21 +5087,23 @@ Return value:
s |= THIRD_KILLER;
ASSERT(s >= 0);
}
- else
+ else
{
// Losing block of check
s -= VALUE_KING;
ASSERT(s < 0);
}
- }
+ }
else
{
// If the king is fleeing, encourage a spot next
// to friendly pieces.
+ //
+ // TODO: does this matter enough for how slow it is?
v = 0;
do {
c = mv.cTo + g_iQKDeltas[v++];
- if (IS_ON_BOARD(c))
+ if (IS_ON_BOARD(c))
{
p = pos->rgSquare[c].pPiece;
s += _bonus[OPPOSITE_COLORS(pos->uToMove, p)]
@@ -5150,7 +5111,7 @@ Return value:
ASSERT(_bonus[OPPOSITE_COLORS(pos->uToMove, p)]
[PIECE_TYPE(p)] >= 0);
}
- }
+ }
while(g_iQKDeltas[v] != 0);
}
}
@@ -5264,7 +5225,6 @@ Return value:
// scoring scheme -- that check stays (it's shared with
// _ScoreQSearchMovesNoChecks, which still needs it), it just
// becomes unreachable here, which is harmless.
- {
ULONG uLiveEnd = pStack->uEnd[uPly];
u = pStack->uBegin[uPly];
while (u < uLiveEnd)
@@ -5382,7 +5342,6 @@ Return value:
} // next move
pStack->uEnd[uPly] = uLiveEnd;
- }
}