summaryrefslogtreecommitdiff
path: root/src/move.c
diff options
context:
space:
mode:
authorScott Gasch <[email protected]>2026-09-05 00:19:59 -0700
committerScott Gasch <[email protected]>2026-09-05 00:19:59 -0700
commit2ce3570dc6aa67f82dd6f02fc4e518be3e33aabf (patch)
tree111f28a4b9587be62e3252aebc4c64b7d8350f4f /src/move.c
parent5883f5a64f4f464b877b7637b8e13c25f7d208fc (diff)
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 <[email protected]> Claude-Session: https://claude.ai/code/session_01P6g6iF6mD1Hau6nCZCzwYj
Diffstat (limited to 'src/move.c')
-rwxr-xr-xsrc/move.c32
1 files changed, 22 insertions, 10 deletions
diff --git a/src/move.c b/src/move.c
index 44e7073..27d86df 100755
--- a/src/move.c
+++ b/src/move.c
@@ -64,6 +64,8 @@ Return value:
pos->cNonPawns[c][uIndex] = cTo;
pos->bbPieces[c][PIECE_TYPE(p)] &= ~COOR_TO_BB(cFrom);
pos->bbPieces[c][PIECE_TYPE(p)] |= COOR_TO_BB(cTo);
+ pos->bbOccupied &= ~COOR_TO_BB(cFrom);
+ pos->bbOccupied |= COOR_TO_BB(cTo);
pos->u64NonPawnSig ^= g_u64SigSeeds[cFrom][PIECE_TYPE(p)][c];
pos->u64NonPawnSig ^= g_u64SigSeeds[cTo][PIECE_TYPE(p)][c];
#ifdef DEBUG
@@ -123,6 +125,8 @@ Return value:
pos->cPawns[c][uIndex] = cTo;
pos->bbPawns[c] &= ~COOR_TO_BB(cFrom);
pos->bbPawns[c] |= COOR_TO_BB(cTo);
+ pos->bbOccupied &= ~COOR_TO_BB(cFrom);
+ pos->bbOccupied |= COOR_TO_BB(cTo);
pos->u64PawnSig ^= g_u64PawnSigSeeds[cFrom][c];
pos->u64PawnSig ^= g_u64PawnSigSeeds[cTo][c];
pos->rgSquare[cTo].pPiece = p;
@@ -177,6 +181,8 @@ Return value:
pos->cNonPawns[c][uIndex] = cTo;
pos->bbPieces[c][PIECE_TYPE(p)] &= ~COOR_TO_BB(cFrom);
pos->bbPieces[c][PIECE_TYPE(p)] |= COOR_TO_BB(cTo);
+ pos->bbOccupied &= ~COOR_TO_BB(cFrom);
+ pos->bbOccupied |= COOR_TO_BB(cTo);
pos->rgSquare[cTo].pPiece = p;
pos->rgSquare[cTo].uIndex = uIndex;
#ifdef DEBUG
@@ -185,7 +191,7 @@ Return value:
}
-void
+void
SlidePawnWithoutSigs(POSITION *pos, COOR cFrom, COOR cTo)
/**
@@ -228,6 +234,8 @@ Return value:
pos->cPawns[c][uIndex] = cTo;
pos->bbPawns[c] &= ~COOR_TO_BB(cFrom);
pos->bbPawns[c] |= COOR_TO_BB(cTo);
+ pos->bbOccupied &= ~COOR_TO_BB(cFrom);
+ pos->bbOccupied |= COOR_TO_BB(cTo);
pos->rgSquare[cTo].pPiece = p;
pos->rgSquare[cTo].uIndex = uIndex;
#ifdef DEBUG
@@ -275,6 +283,7 @@ Return value:
pos->rgSquare[cSquare].pPiece = EMPTY;
ASSERT(IS_VALID_PIECE(pLifted));
ASSERT(!IS_KING(pLifted));
+ pos->bbOccupied &= ~COOR_TO_BB(cSquare);
uIndex = pos->rgSquare[cSquare].uIndex;
#ifdef DEBUG
ASSERT(IS_VALID_PIECE_INDEX(uIndex));
@@ -287,12 +296,12 @@ Return value:
pos->iMaterialBalance[color] -= pv;
pos->iMaterialBalance[FLIP(color)] += pv;
ASSERT(pos->iMaterialBalance[WHITE] * -1 == pos->iMaterialBalance[BLACK]);
-
+
if (IS_PAWN(pLifted))
{
ASSERT(pos->cPawns[color][uIndex] == cSquare);
ASSERT(pv == VALUE_PAWN);
-
+
pos->uPawnMaterial[color] -= pv;
ASSERT(pos->uPawnMaterial[color] <= (7 * VALUE_PAWN));
@@ -410,7 +419,8 @@ Return value:
pos->rgSquare[cSquare].pPiece = EMPTY;
ASSERT(IS_VALID_PIECE(pLifted));
ASSERT(!IS_KING(pLifted));
-
+ pos->bbOccupied &= ~COOR_TO_BB(cSquare);
+
uIndex = pos->rgSquare[cSquare].uIndex;
#ifdef DEBUG
ASSERT(IS_VALID_PIECE_INDEX(uIndex));
@@ -423,12 +433,12 @@ Return value:
pos->iMaterialBalance[color] -= pv;
pos->iMaterialBalance[FLIP(color)] += pv;
ASSERT(pos->iMaterialBalance[WHITE] * -1 == pos->iMaterialBalance[BLACK]);
-
+
if (IS_PAWN(pLifted))
{
ASSERT(pos->cPawns[color][uIndex] == cSquare);
ASSERT(pv == VALUE_PAWN);
-
+
pos->uPawnMaterial[color] -= pv;
ASSERT(pos->uPawnMaterial[color] <= (7 * VALUE_PAWN));
pos->bbPawns[color] &= ~COOR_TO_BB(cSquare);
@@ -533,7 +543,8 @@ Return value:
pos->iMaterialBalance[color] += pv;
pos->iMaterialBalance[FLIP(color)] -= pv;
ASSERT(pos->iMaterialBalance[WHITE] * -1 == pos->iMaterialBalance[BLACK]);
-
+ pos->bbOccupied |= COOR_TO_BB(cSquare);
+
if (IS_PAWN(pPiece))
{
//
@@ -542,7 +553,7 @@ Return value:
ASSERT(pv == VALUE_PAWN);
pos->uPawnMaterial[color] += pv;
ASSERT(pos->uPawnMaterial[color] <= (8 * VALUE_PAWN));
-
+
uIndex = pos->uPawnCount[color];
ASSERT((uIndex >= 0) && (uIndex <= 7));
pos->uPawnCount[color]++;
@@ -626,7 +637,8 @@ Return value:
pos->iMaterialBalance[color] += pv;
pos->iMaterialBalance[FLIP(color)] -= pv;
ASSERT(pos->iMaterialBalance[WHITE] * -1 == pos->iMaterialBalance[BLACK]);
-
+ pos->bbOccupied |= COOR_TO_BB(cSquare);
+
if (IS_PAWN(pPiece))
{
//
@@ -635,7 +647,7 @@ Return value:
ASSERT(pv == VALUE_PAWN);
pos->uPawnMaterial[color] += pv;
ASSERT(pos->uPawnMaterial[color] <= (8 * VALUE_PAWN));
-
+
uIndex = pos->uPawnCount[color];
ASSERT((uIndex >= 0) && (uIndex <= 7));
pos->uPawnCount[color]++;