hardware/piece_tracker.h

Piece identity tracking for storage-based capture disambiguation.

The chess engine doesn’t track individual piece identity — it only knows that “there’s a black knight on d5,” not “the b8-knight is on

d5.” But the physical board has labeled storage slots where each captured piece has a designated home (SLOT_N1, SLOT_P1, etc.). To disambiguate captures using storage slot identity, we need to track which original piece is on which square.

This module maintains a 64-entry map: for each board square, the StartingSlot of the piece currently sitting there (or SLOT_NONE if empty). It’s initialized from the starting position and updated on every move.

Example:

  • Game starts: square b8 (index 1) → SLOT_N1

  • Black plays Nf6: square b8 → SLOT_NONE, square f6 → SLOT_N1

  • White captures Nxf6: square f6 → SLOT_NONE, piece goes to SLOT_N1 in black’s storage zone

When the human captures a piece and places it in a storage slot, the scanner sees which slot gained a piece. The PieceTracker tells us which square that piece is currently on, so we can match it to the correct capture move.

Variables

constexpr int SLOT_NONE = -1
constexpr int SLOT_UNKNOWN = -2
class PieceTracker
#include <piece_tracker.h>

Public Functions

inline PieceTracker()
inline void clear()

Clear all tracking (all squares empty, all pieces unplaced).

inline void initStartingPosition()

Initialize for the standard starting position. White pieces on ranks 1-2 (rows 6-7, squares 48-63). Black pieces on ranks 7-8 (rows 0-1, squares 0-15).

inline void initFromReverseMap(const int squareForSlot[2][16])

Seed the tracker from a reverse map (per side, per slot -> square, or -1 for a piece in storage). This is how a review or “play from here” sets identity to a known past snapshot rather than the standard start (review-docs §6.5).

inline void applyMove(int from, int to, bool isWhite, bool isCapture, int capturedSquare = -1, bool capturedIsWhite = false)

Update tracking after a move.

Parameters:
  • from – Source square (0-63)

  • to – Target square (0-63)

  • isWhite – True if the moving piece is white

  • isCapture – True if this move captures a piece

  • capturedSquare – The square where the captured piece was (usually == to, except for en passant)

  • capturedIsWhite – True if the captured piece is white

inline void applyRookCastle(int rookFrom, int rookTo, bool isWhite)

Update tracking for castling rook movement. Call this in addition to applyMove for the king.

Parameters:
  • rookFrom – Rook’s source square

  • rookTo – Rook’s destination square

  • isWhite – True if white is castling

inline void undoMove(int from, int to, bool isWhite, bool isCapture, int capturedSquare, bool capturedIsWhite, int capturedSlot)

Update tracking for pawn promotion. The piece identity stays the same — a promoted pawn is still tracked as SLOT_Px. The physical piece doesn’t change (the system uses the same magnet), and when captured, the promoted piece goes back to its pawn slot in storage.

No special handling needed — applyMove already preserves the slot identity through the move. This method exists only for documentation clarity. Reverse a previously-applied move (physical review, review-docs PLAN §6.2). The exact inverse of applyMove: the moving piece goes back to->from, and a captured piece is restored to its square from the storage slot it occupies.

The captured slot cannot be recovered from the post-move tracker (the piece is no longer on any square), so the caller — the ReviewSession replaying the game — supplies it. capturedSlot is SLOT_NONE for a non-capture.

Parameters:
  • capturedSquare – Where the captured piece was (==to, except en passant)

  • capturedSlot – The StartingSlot the captured piece was standing in

inline void undoRookCastle(int rookFrom, int rookTo, bool isWhite)

Reverse a castling rook movement (call alongside undoMove for the king).

inline int getSlotAt(int square) const

Get the StartingSlot of the piece on a given square.

Returns:

StartingSlot (0-15), SLOT_NONE if empty, SLOT_UNKNOWN if unknown

inline int getSquareForSlot(bool isWhite, int slot) const

Get the current square of a piece identified by its starting slot.

Parameters:
  • isWhite – True for white pieces, false for black

  • slot – The StartingSlot (0-15)

Returns:

Square index (0-63), or -1 if the piece has been captured

inline bool isPieceAlive(bool isWhite, int slot) const

Check if a piece (by starting slot) is still on the board.

inline void print() const

Print the current piece identity map (for debugging).

Private Members

int squareToSlot[64]
int slotToSquare[2][16]