From d184a2ea4314d6bd4b8933482c0c1e7a420f2872 Mon Sep 17 00:00:00 2001 From: Scott Gasch Date: Sat, 5 Sep 2026 09:35:19 -0700 Subject: Rook attack/mobility: bitboard rewrite; backport bounded x-ray chaining to bishop _EvalRook's mobility ray-walk and RMobCaseTable switch replaced with _RookAttacksBB(c, pos->bbOccupied) plus bitboard masks, same technique as knight/bishop. Adds pos->bbRookAttacks[2]/bbRookXrayAttacks[2], first contributors alongside bbMinorAttacks/bbMinorXrayAttacks. Connected-rook bonus and x-ray population derived from the attack bitboard instead of a per-square dispatch. Unlike bishop's single-hop x-ray simplification, rook's x-ray population uses a bounded chain-following loop (recompute with the newly-found blocker excluded, repeat until no new x-ray-worthy terminal appears): checked frequency first (board_representation/ EVAL.md), and 14% of the curated-suite positions have a genuine 2+-deep rook/queen battery on some ray, far more common than bishop's ~1% -- a one-hop approximation here would be a real fidelity loss, not a negligible one. The stashed first bitboard-eval attempt (git stash@{1}) had already solved this correctly by walking blocker-to- blocker via bit-scan; this reproduces the same unbounded behavior via repeated magic-lookup recomputation, cheap because the loop only iterates again when an actual chained battery exists. Backported the same bounded-chain fix to bishop's x-ray population (previously single-hop only) for consistency, now that it's known cheap and mechanically identical -- bishop's own battery rate is much lower (~1%) so this mostly just removes an intentional divergence rather than fixing an active problem. Also fixes two real correctness gaps this conversion would otherwise have introduced silently (same failure mode as pawn's earlier conversion, EVAL.md's progress log): rook no longer writes ROOK_BIT/ ROOK_XRAY_BIT into the old per-square bvAttacks structure, but _WhoControlsSquareFast and queen's mobility unsafe-check both still read those bits directly. Added _IsSquareAttackedByRook/ _IsSquareXrayedByRook (same transitional-helper, DEBUG-cross-checked pattern as the minor-piece helpers) and updated both call sites. Verified via precommit_check.sh (self-test + DEBUG smoke test) after each step. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01XxmVi2sTMwpPp4i6WYFjan --- src/chess.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src/chess.h') diff --git a/src/chess.h b/src/chess.h index 305c681..421667f 100755 --- a/src/chess.h +++ b/src/chess.h @@ -739,6 +739,19 @@ typedef struct _POSITION // see _IsSquareXrayedByMinor. BITBOARD bbMinorXrayAttacks[2]; + // Rook's turn to convert (board_representation/EVAL.md section + // 9, 2026-09-05): "which squares does this side's rook(s) attack," + // ORed in via _RookAttacksBB(c, pos->bbOccupied) straight from + // _EvalRook's mobility computation, same Eval()-scoped/cleared- + // per-call lifetime as bbMinorAttacks. bbRookXrayAttacks mirrors + // bbMinorXrayAttacks: squares seen past a friendly rook/queen + // battery partner or an x-rayable enemy queen/king, single-hop + // only (same deliberate simplification bishop already made, see + // _EvalRook's mobility comment). Queen/king haven't converted yet + // and still write their own bits into the old bvAttacks structure. + BITBOARD bbRookAttacks[2]; + BITBOARD bbRookXrayAttacks[2]; + ULONG uWhiteSqBishopCount[2]; // num bishops on white squares SCORE iMaterialBalance[2]; // material balance -- cgit v1.3