---
title: Plans for a chess/taikyoku shogi/what have you engine
date: 2025-02-18
---

```js
  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'
