board:Array,currentPlayer:'white'|'black',moveHistory:Array,enPassantTarget:{x,y}|null,// Updates each turn
halfMoveClock:number,// For 50-move rule
capturedPieces:Array}
3. Move Validation System
Separate move generation into layers:
Layer 1: Basic Move Patterns
getPseudoLegalMoves(piece, position)
- Returns all squares the piece could move to
- Ignores check/pin considerations
- Each piece type has its own logic
Layer 2: Board-Aware Filtering
getLegalMoves(piece, position, gameState)
- Filters pseudoLegal moves
- Checks if king would be in check after move
- Handles special moves (castling, en passant)
Handling Special Cases
En Passant
After any pawn moves 2 squares forward, set enPassantTarget to the square it passed through
Clear it at the start of the next turn
When validating pawn captures, check if target matches enPassantTarget
Castling
Track hasMoved flag on kings and rooks
Check: king/rook haven’t moved, squares between are empty, king doesn’t pass through/end in check
For arbitrary boards: castle king 2 squares toward rook, place rook on opposite side
Pawn Promotion
Detect when pawn reaches opposite end (rank 0 or rank N-1)
Pause game, show promotion UI
Replace pawn with chosen piece
Key Functions
isSquareAttacked(x, y, byColor, gameState)
- Critical for check detection
- Generate all opponent moves, see if any target this square
isKingInCheck(color, gameState)
- Find king position
- Use isSquareAttacked
makeMove(from, to, gameState)
- Validate move is legal
- Update board
- Handle captures
- Update en passant state
- Toggle current player
- Add to move history (for undo)
getGameStatus()
- Returns: 'playing', 'check', 'checkmate', 'stalemate', 'draw'