From 2ce3570dc6aa67f82dd6f02fc4e518be3e33aabf Mon Sep 17 00:00:00 2001 From: Scott Gasch Date: Sat, 5 Sep 2026 00:19:59 -0700 Subject: Maintain pos->bbOccupied incrementally, dedupe its two from-scratch builders chess.h: add POSITION::bbOccupied (full-board occupancy, both colors, every piece including kings), maintained incrementally alongside bbPieces/bbPawns rather than rebuilt on demand -- resolves the open question in EVAL.md section 0 about whether this is worth doing given both generate.c and the planned eval.c mobility rewrite need it. move.c: SlidePiece/SlidePawn/LiftPiece/PlacePiece and their WithoutSigs variants now maintain bbOccupied at the same choke points that already maintain bbPieces/bbPawns -- unconditionally, since occupancy doesn't care about piece type or color. Kings only ever move through SlidePiece/SlidePieceWithoutSigs (never Lift/Place), so no separate king-specific update site was needed. fen.c: populate bbOccupied when parsing a FEN. board.c: VerifyPositionConsistency cross-checks pos->bbOccupied against a from-scratch rebuild, same pattern already used for bbPieces/bbPawns. generate.c/movesup.c/see.c: replace call sites that rebuilt full occupancy via _BuildFullOccupiedBB/_BuildOccupiedBB with direct reads of pos->bbOccupied; delete see.c's _BuildOccupiedBB, which was a byte-for-byte duplicate of generate.c's _BuildFullOccupiedBB (kept only as the from-scratch ground truth for the new consistency check and testgenerate.c's benchmark harness). testsup.c: GenerateRandomLegalPosition builds POSITIONs by poking rgSquare/bbPieces/bbPawns directly, bypassing both move.c and fen.c -- a third construction path the above missed. It never set bbOccupied, so the new VerifyPositionConsistency check failed on every generated position, and since generation retries until a position verifies, the self-test suite spun forever (100% CPU, no progress) instead of crashing outright. Fixed by setting bbOccupied at all four placement sites (both kings, pawn, non-pawn piece). Full self-test suite and precommit_check.sh verified clean afterward. board_representation/EVAL.md: record the bbOccupied decision and rationale, resolving section 0's open question. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01P6g6iF6mD1Hau6nCZCzwYj --- src/testsup.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/testsup.c') diff --git a/src/testsup.c b/src/testsup.c index d1b102d..852b6d9 100644 --- a/src/testsup.c +++ b/src/testsup.c @@ -117,7 +117,8 @@ GenerateRandomLegalPosition(POSITION *pos) pos->uNonPawnCount[WHITE][KING] = 1; pos->uNonPawnCount[WHITE][0] = 1; pos->uNonPawnMaterial[WHITE] = VALUE_KING; - + pos->bbOccupied |= COOR_TO_BB(c); + do { c1 = RANDOM_COOR; @@ -130,7 +131,8 @@ GenerateRandomLegalPosition(POSITION *pos) pos->uNonPawnCount[BLACK][KING] = 1; pos->uNonPawnCount[BLACK][0] = 1; pos->uNonPawnMaterial[BLACK] = VALUE_KING; - + pos->bbOccupied |= COOR_TO_BB(c1); + // // Place the rest of the armies // @@ -180,6 +182,7 @@ GenerateRandomLegalPosition(POSITION *pos) pos->uPawnCount[uColor]++; pos->uPawnMaterial[uColor] += VALUE_PAWN; pos->bbPawns[uColor] |= COOR_TO_BB(c); + pos->bbOccupied |= COOR_TO_BB(c); break; } else if (!IS_KING(p) && @@ -193,6 +196,7 @@ GenerateRandomLegalPosition(POSITION *pos) pos->rgSquare[c].uIndex = uIndex; pos->uNonPawnMaterial[uColor] += PIECE_VALUE(p); pos->bbPieces[uColor][PIECE_TYPE(p)] |= COOR_TO_BB(c); + pos->bbOccupied |= COOR_TO_BB(c); if (IS_BISHOP(p)) { if (IS_WHITE_SQUARE_COOR(c)) -- cgit v1.3