summaryrefslogtreecommitdiff
path: root/src/chess.h
diff options
context:
space:
mode:
authorScott Gasch <[email protected]>2026-09-05 10:23:28 -0700
committerScott Gasch <[email protected]>2026-09-05 10:23:28 -0700
commitaad154a5a07d2793e52a71415cc5c59276a8f629 (patch)
tree2bcfd67989bb123e13a449080e316ee0d5ecb05e /src/chess.h
parent1216f4e159af037a32323aa7c942e64fcecafb05 (diff)
King attack-table population: bitboard rewrite, fixes a real bug and a real asymmetry
_EvalKing was the last piece type contributing to the old bvAttacks/ ATTACK_BITV mechanism -- both write sites (the low-enemy-material early-exit path and the main king-safety loop) replaced with a single pos->bbKingAttacks[uColor] |= g_KingAttacksBB[c], plus a new _IsSquareAttackedByKing transitional helper (DEBUG-cross-checked, no x-ray companion needed since a king can't move through a blocker) for _WhoControlsSquareFast and _EvalKing's own bvDefend to read. Two real, intentional behavior changes land with this conversion, both discussed and confirmed before coding rather than assumed: 1. The main king-safety loop's old per-square write used KingSafetyDeltas (11 entries: the 8 real king-move squares plus -2/ +2, two squares away on the same rank, present only for that loop's own file-distance bookkeeping) instead of the real 8-square king move pattern -- a bug, confirmed by direct instruction, not a design choice worth preserving. Fixed by writing the real g_KingAttacksBB[c] pattern once, before the loop, instead of whatever KingSafetyDeltas happened to visit per-square. 2. _EvalKing's own bvAttack computation (does the *enemy* king attack a square near this king?) is now symmetric where it used to be an accidental artifact of evaluation order: kings are evaluated black-then-white, so the old mailbox code let white's computation see black's already-written king bit while black's could never see white's (white hadn't run yet). Rather than preserve or upgrade that asymmetry now that both colors go through an explicit helper either way, neither side sees the enemy king as a threat here, matching the side that already couldn't -- by direct instruction. This is narrow in practice (two kings can never be legally adjacent, so it only ever fires at king-vs-king distance 2) but real. _WhoControlsSquareFast's own king contribution is unaffected by either change and stays fully symmetric: it's only ever called after *both* kings finish evaluating (the passed-pawn re-check and trapped-piece/ danger passes all run after Eval()'s king-eval block), so pos->bbKingAttacks is always fully populated for both colors by the time it runs -- confirmed by checking call-site ordering directly, not assumed from bvAttack's own (different) situation. CountKingSafetyDefects is untouched by this change (confirmed by reading it again): it's pure CHECK_VECTOR geometry over piece locations, computed before any bbXAttacks accumulator exists this Eval() call, and reads none of them. Its correlation with _EvalKing's score is therefore preserved by construction, not something requiring separate re-tuning. Verification: since this bundles three attributable behavior changes (the bitboard rewrite itself, the KingSafetyDeltas bug fix, and the dropped bvAttack asymmetry), used the ringers-suite-plus-bounded-delta bar from bishop's conversion rather than expecting exact node-count equality: precommit_check.sh (self-test + DEBUG smoke test, plus several hand-built king-adjacency/king-proximity positions run directly against a DEBUG binary to exercise the new cross-check) all pass; whole-engine tests/ecm_ringers.ep_ at sd10 vs. the immediately preceding commit holds exact solve parity (10/11 both), with per-position node-count deltas (-50% to +76%) all attributable to the three documented changes above, no unexplained outliers. ATTACK_BITV/bvAttacks itself is intentionally left in place -- nothing writes it any more (king was the last writer), but the struct deletion and the resulting simplification of the transitional _IsSquareAttackedByX/_IsSquareXrayedByX helpers (which collapse to plain bitboard reads once nothing can ever populate the old structure) is staged as a deliberate follow-up commit, not bundled here. Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01XxmVi2sTMwpPp4i6WYFjan
Diffstat (limited to 'src/chess.h')
-rwxr-xr-xsrc/chess.h23
1 files changed, 23 insertions, 0 deletions
diff --git a/src/chess.h b/src/chess.h
index 6b09840..aababc0 100755
--- a/src/chess.h
+++ b/src/chess.h
@@ -614,6 +614,10 @@ ATTACK_BITV;
#define ROOK_XRAY_BIT 0x20000000UL
#define QUEEN_BIT 0x00000010UL
#define QUEEN_XRAY_BIT 0x10000000UL
+// King never x-rays (it can't move through a blocker), so there's no
+// KING_XRAY_BIT to go with this -- matches struct _ATTACK_BITV's
+// .small.uKing bit position (byte 0, bit 3).
+#define KING_BIT 0x00000008UL
#define INVALID_PIECE_INDEX (17)
#define IS_VALID_PIECE_INDEX(x) ((x) < INVALID_PIECE_INDEX)
@@ -770,6 +774,25 @@ typedef struct _POSITION
BITBOARD bbQueenAttacks[2];
BITBOARD bbQueenXrayAttacks[2];
+ // King's turn to convert (board_representation/EVAL.md section 9,
+ // 2026-09-05) -- the last piece type contributing to the old
+ // bvAttacks/ATTACK_BITV mechanism. Just g_KingAttacksBB[c]
+ // (generate.c's precomputed table, already used by move
+ // generation), no mobility computation involved and no x-ray
+ // (a king can't move through a blocker). Same Eval()-scoped/
+ // cleared-per-call lifetime as every other bbXAttacks accumulator
+ // above -- this also reproduces, for free, an existing
+ // order-dependent asymmetry _EvalKing's mailbox version already
+ // had: kings are evaluated black-then-white (Eval()'s fixed
+ // order), so white's king-safety computation can see black's
+ // already-written attack bits but not vice versa. Once this
+ // lands, nothing writes bvAttacks/ATTACK_BITV any more -- see
+ // EVAL.md section 9 for the planned follow-up that deletes the
+ // whole mechanism and simplifies the transitional
+ // _IsSquareAttackedByX/_IsSquareXrayedByX helpers into plain
+ // bitboard reads.
+ BITBOARD bbKingAttacks[2];
+
ULONG uWhiteSqBishopCount[2]; // num bishops on white squares
SCORE iMaterialBalance[2]; // material balance