# Chess Rules Reference

## Table of Contents

1. [Game Objective](#game-objective)
2. [Board Setup](#board-setup)
3. [Piece Movement](#piece-movement)
4. [Special Moves](#special-moves)
5. [Check and Checkmate](#check-and-checkmate)
6. [Draw Conditions](#draw-conditions)
7. [Chess Notation](#chess-notation)
8. [Rule Edge Cases](#rule-edge-cases)

---

## Game Objective

Chess is a two-player strategy game where the objective is to **checkmate** the opponent's king.

- **Checkmate**: The king is under attack (in check) and cannot escape
- **Win Conditions**: Checkmate or opponent resignation
- **Draw Conditions**: Stalemate, insufficient material, threefold repetition, fifty-move rule, or agreement

---

## Board Setup

### Board Orientation

- 8x8 grid with alternating light and dark squares
- Bottom-right square from each player's perspective is a light square
- Ranks (rows) numbered 1-8, files (columns) labeled a-h
- White pieces start on ranks 1-2, black on ranks 7-8

### Initial Position

```
  a b c d e f g h
8 ♜ ♞ ♝ ♛ ♚ ♝ ♞ ♜  8
7 ♟ ♟ ♟ ♟ ♟ ♟ ♟ ♟  7
6 · · · · · · · ·  6
5 · · · · · · · ·  5
4 · · · · · · · ·  4
3 · · · · · · · ·  3
2 ♙ ♙ ♙ ♙ ♙ ♙ ♙ ♙  2
1 ♖ ♘ ♗ ♕ ♔ ♗ ♘ ♖  1
  a b c d e f g h
```

**FEN Notation:** `rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1`

### Piece Placement

**White (bottom):**
- a1, h1: Rooks (♖)
- b1, g1: Knights (♘)
- c1, f1: Bishops (♗)
- d1: Queen (♕)
- e1: King (♔)
- a2-h2: Pawns (♙)

**Black (top):**
- a8, h8: Rooks (♜)
- b8, g8: Knights (♞)
- c8, f8: Bishops (♝)
- d8: Queen (♛)
- e8: King (♚)
- a7-h7: Pawns (♟)

**Mnemonic:** "Queen on her own color" (white queen on light square, black queen on dark square)

---

## Piece Movement

### Pawn (♙ ♟)

**Basic Movement:**
- Moves forward one square
- From starting position, can move forward two squares
- Captures diagonally forward one square
- Cannot move backward

**Special Rules:**
- Can only capture diagonally (not straight ahead)
- Blocked if square directly ahead is occupied
- See [En Passant](#en-passant) and [Promotion](#pawn-promotion)

**Diagram:**
```
· · · · · · · ·
· · ♟ · ♟ · · ·  ← Can capture here
· · · ♙ · · · ·  ← Pawn position
· · · ↑ · · · ·  ← Can move here
· · · ↑ · · · ·  ← Can move here (if first move)
```

**Implementation Note:**
- White pawns move up (decreasing row), black pawns move down (increasing row)
- Starting rank: white on row 6, black on row 1
- Promotion rank: white on row 0, black on row 7

---

### Knight (♘ ♞)

**Movement Pattern:**
- L-shaped: 2 squares in one direction, 1 square perpendicular
- Can jump over other pieces
- 8 possible moves maximum (if not blocked)

**Movement Offsets:**
```
(-2, -1)  (-2, +1)
   ↖  ↗
(-1,-2) ♘ (-1,+2)
   ↙  ↘
(+1,-2)   (+1,+2)
   ↖  ↗
(+2, -1)  (+2, +1)
```

**Diagram:**
```
· · X · X · · ·
· X · · · X · ·
· · · ♘ · · · ·
· X · · · X · ·
· · X · X · · ·
```

**Implementation:**
```javascript
const knightMoves = [
    [-2, -1], [-2, 1], [-1, -2], [-1, 2],
    [1, -2], [1, 2], [2, -1], [2, 1]
];
```

---

### Bishop (♗ ♝)

**Movement Pattern:**
- Any number of squares diagonally
- Cannot jump over pieces
- Stays on same color squares entire game

**Diagram:**
```
X · · · · · · ·
· X · · · · · X
· · X · · · X ·
· · · ♗ · X · ·
· · · · X · · ·
· · · X · · · ·
```

**Implementation:**
```javascript
const bishopDirections = [
    [-1, -1], // up-left
    [-1, +1], // up-right
    [+1, -1], // down-left
    [+1, +1]  // down-right
];
```

---

### Rook (♖ ♜)

**Movement Pattern:**
- Any number of squares horizontally or vertically
- Cannot jump over pieces
- Involved in castling (see [Castling](#castling))

**Diagram:**
```
· · · X · · · ·
· · · X · · · ·
· · · X · · · ·
X X X ♖ X X X X
· · · X · · · ·
· · · X · · · ·
```

**Implementation:**
```javascript
const rookDirections = [
    [-1, 0], // up
    [+1, 0], // down
    [0, -1], // left
    [0, +1]  // right
];
```

---

### Queen (♕ ♛)

**Movement Pattern:**
- Combines rook and bishop movement
- Any number of squares in any direction
- Cannot jump over pieces
- Most powerful piece

**Diagram:**
```
X · · X · · · X
· X · X · · X ·
· · X X · X · ·
X X X ♕ X X X X
· · X X · X · ·
· X · X · · X ·
```

**Implementation:**
```javascript
const queenDirections = [
    [-1, -1], [-1, 0], [-1, +1],
    [0, -1],           [0, +1],
    [+1, -1], [+1, 0], [+1, +1]
];
```

---

### King (♔ ♚)

**Movement Pattern:**
- One square in any direction
- Cannot move into check
- Involved in castling (see [Castling](#castling))

**Diagram:**
```
· · · · · · · ·
· · X X X · · ·
· · X ♔ X · · ·
· · X X X · · ·
```

**Implementation:**
```javascript
const kingMoves = [
    [-1, -1], [-1, 0], [-1, +1],
    [0, -1],           [0, +1],
    [+1, -1], [+1, 0], [+1, +1]
];
```

**Critical Rules:**
- Cannot move into check (square attacked by opponent)
- Cannot castle out of, through, or into check
- Most important piece (game ends if checkmated)

---

## Special Moves

### Castling

**Purpose:** Protect king and activate rook

**Types:**
1. **Kingside Castling (O-O)**: King moves two squares toward h-file rook
2. **Queenside Castling (O-O-O)**: King moves two squares toward a-file rook

**Conditions (ALL must be met):**
1. Neither king nor rook has moved previously
2. No pieces between king and rook
3. King is not in check
4. King does not pass through check
5. King does not end up in check

**Kingside Castling (White):**
```
Before:  · · · · ♔ · · ♖
After:   · · · · · ♖ ♔ ·
         e1 → g1, h1 → f1
```

**Queenside Castling (White):**
```
Before:  ♖ · · · ♔ · · ·
After:   · · ♔ ♖ · · · ·
         e1 → c1, a1 → d1
```

**Implementation Logic:**
```javascript
function canCastle(king, rook, board) {
    // 1. Check if pieces have moved
    if (king.hasMoved || rook.hasMoved) return false;

    // 2. Check if path is clear
    const [minCol, maxCol] = [
        Math.min(king.col, rook.col),
        Math.max(king.col, rook.col)
    ];
    for (let col = minCol + 1; col < maxCol; col++) {
        if (board.getPiece(king.row, col)) return false;
    }

    // 3. Check if king is in check
    if (isKingInCheck(board, king.color)) return false;

    // 4. Check if king passes through check
    const direction = rook.col > king.col ? 1 : -1;
    for (let i = 1; i <= 2; i++) {
        const testCol = king.col + (direction * i);
        if (isSquareUnderAttack(board, king.row, testCol, opponentColor)) {
            return false;
        }
    }

    return true;
}
```

---

### En Passant

**Purpose:** Prevent pawns from avoiding capture by double-stepping

**Condition:**
- Opponent pawn moves two squares from starting position
- Lands beside your pawn (same rank)
- You can capture it as if it moved only one square
- **Must be done immediately (next move only)**

**Diagram:**
```
Before:           After capture:
· · · · · · · ·   · · · · · · · ·
♟ · ♟ · · · · ·   · · ♟ · · · · ·
· ♙ · · · · · ·   · · ♙ · · · · ·  ← White pawn captures
♙ · · · · · · ·   · · · · · · · ·
```

**FEN Notation:**
- En passant target square recorded in FEN
- Example: `...w KQkq e6...` (e6 is en passant target)

**Implementation:**
```javascript
function canEnPassant(pawn, targetCol, gameState) {
    // Must be on correct rank
    const correctRank = pawn.color === 'white' ? 3 : 4;
    if (pawn.row !== correctRank) return false;

    // Check last move
    const lastMove = gameState.getLastMove();
    if (!lastMove || lastMove.piece.type !== 'pawn') return false;

    // Must have moved two squares
    const moveDistance = Math.abs(lastMove.to.row - lastMove.from.row);
    if (moveDistance !== 2) return false;

    // Must be adjacent
    return Math.abs(pawn.col - targetCol) === 1 &&
           lastMove.to.col === targetCol &&
           lastMove.to.row === pawn.row;
}

function executeEnPassant(board, pawn, targetRow, targetCol) {
    // Remove captured pawn
    const capturedPawn = board.getPiece(pawn.row, targetCol);
    board.setPiece(pawn.row, targetCol, null);

    // Move attacking pawn
    board.movePiece(pawn.row, pawn.col, targetRow, targetCol);

    return capturedPawn;
}
```

---

### Pawn Promotion

**Condition:** Pawn reaches the opposite end of the board (rank 8 for white, rank 1 for black)

**Options:** Can promote to:
- Queen (most common)
- Rook
- Bishop
- Knight
- **Cannot promote to King or Pawn**

**Notation:**
- `e8=Q` - Pawn to e8, promotes to queen
- `axb8=N+` - Pawn captures on b8, promotes to knight with check

**Diagram:**
```
♟ · · · · · · ·  ← Black pawn about to promote
· · · · · · · ·
...
♙ · · · · · · ·  ← White pawn about to promote
```

**Implementation:**
```javascript
function canPromote(pawn) {
    const promotionRank = pawn.color === 'white' ? 0 : 7;
    return pawn.row === promotionRank;
}

function promote(board, pawn, pieceType) {
    // pieceType: 'queen', 'rook', 'bishop', 'knight'
    const PieceClass = getPieceClass(pieceType);
    const newPiece = new PieceClass(pawn.color, pawn.position);
    board.setPiece(pawn.row, pawn.col, newPiece);
    return newPiece;
}
```

**UI Consideration:** Show dialog for player to choose promotion piece

---

## Check and Checkmate

### Check

**Definition:** King is under direct attack by opponent piece

**Rules:**
- Player in check **must** get out of check
- Cannot make any move that leaves king in check
- Must respond with one of three options:
  1. Move king to safe square
  2. Block the attack
  3. Capture the attacking piece

**Notation:** Add `+` to move notation (e.g., `Qh5+`)

**Implementation:**
```javascript
function isKingInCheck(board, color) {
    // Find king position
    const kingPos = findKing(board, color);
    if (!kingPos) return false; // Should never happen

    // Check if any opponent piece attacks king square
    for (let row = 0; row < 8; row++) {
        for (let col = 0; col < 8; col++) {
            const piece = board.getPiece(row, col);
            if (piece && piece.color !== color) {
                const moves = piece.getValidMoves(board);
                if (moves.some(m => m.row === kingPos.row && m.col === kingPos.col)) {
                    return true;
                }
            }
        }
    }

    return false;
}
```

---

### Checkmate

**Definition:** King is in check and cannot escape

**Conditions:**
1. King is in check
2. King cannot move to safe square
3. No piece can block the attack
4. Attacking piece cannot be captured

**Notation:** Add `#` to move notation (e.g., `Qf7#`)

**Result:** Game ends, attacking player wins

**Famous Checkmate Patterns:**

**Scholar's Mate (4 moves):**
```
1. e4 e5
2. Bc4 Nc6
3. Qh5 Nf6??
4. Qxf7# (checkmate)
```

**Back Rank Mate:**
```
  a b c d e f g h
8 · · · · · ♜ ♚ ·  8  ← King trapped by own pawns
7 · · · · · ♟ ♟ ♟  7
```

**Implementation:**
```javascript
function isCheckmate(board, color) {
    // Must be in check
    if (!isKingInCheck(board, color)) {
        return false;
    }

    // Check if any legal move exists
    for (let row = 0; row < 8; row++) {
        for (let col = 0; col < 8; col++) {
            const piece = board.getPiece(row, col);
            if (piece && piece.color === color) {
                const moves = piece.getValidMoves(board);

                for (const move of moves) {
                    // Simulate move
                    const testBoard = board.clone();
                    testBoard.movePiece(row, col, move.row, move.col);

                    // If king no longer in check, not checkmate
                    if (!isKingInCheck(testBoard, color)) {
                        return false;
                    }
                }
            }
        }
    }

    // No legal moves available
    return true;
}
```

---

## Draw Conditions

### Stalemate

**Definition:** Player has no legal moves but is NOT in check

**Result:** Game is a draw

**Diagram:**
```
  a b c d e f g h
8 · · · · · · ♔ ·  8
7 · · · · · ♕ · ·  7
6 · · · · · · · ♚  6  ← Black king, not in check
```
Black to move has no legal moves → **Stalemate**

**Implementation:**
```javascript
function isStalemate(board, color) {
    // Must NOT be in check
    if (isKingInCheck(board, color)) {
        return false;
    }

    // But has no legal moves
    return !hasAnyLegalMove(board, color);
}
```

---

### Insufficient Material

**Definition:** Neither player has enough pieces to force checkmate

**Automatic Draw Conditions:**
- King vs King
- King + Bishop vs King
- King + Knight vs King
- King + Bishop vs King + Bishop (same color squares)

**Not Automatic Draw (checkmate still possible):**
- King + Rook vs King
- King + Queen vs King
- King + Pawn vs King
- King + 2 Knights vs King (very rare, but possible)

**Implementation:**
```javascript
function isInsufficientMaterial(board) {
    const pieces = getAllPieces(board);

    // King vs King
    if (pieces.length === 2) return true;

    // King + Minor piece vs King
    if (pieces.length === 3) {
        return pieces.some(p => p.type === 'bishop' || p.type === 'knight');
    }

    // King + Bishop vs King + Bishop (same color)
    if (pieces.length === 4) {
        const bishops = pieces.filter(p => p.type === 'bishop');
        if (bishops.length === 2) {
            return (bishops[0].position.row + bishops[0].position.col) % 2 ===
                   (bishops[1].position.row + bishops[1].position.col) % 2;
        }
    }

    return false;
}
```

---

### Threefold Repetition

**Definition:** Same position occurs three times (not necessarily consecutive)

**Criteria for "same position":**
- Same pieces on same squares
- Same player to move
- Same castling rights
- Same en passant availability

**Claim:** Player can claim draw when position repeats third time

**Implementation:**
```javascript
function isThreefoldRepetition(gameState) {
    const currentFEN = gameState.toFEN();
    const fenHistory = gameState.moveHistory.map(m => m.fen);

    let count = 0;
    for (const fen of fenHistory) {
        if (fen === currentFEN) {
            count++;
            if (count >= 3) return true;
        }
    }

    return false;
}
```

---

### Fifty-Move Rule

**Definition:** 50 consecutive moves by each player with no pawn move or capture

**Counter:** Reset to 0 when:
- Any pawn moves
- Any piece is captured

**Claim:** Player can claim draw after 50 moves

**Implementation:**
```javascript
function isFiftyMoveRule(gameState) {
    return gameState.halfMoveClock >= 100; // 50 moves per player
}
```

---

### Draw by Agreement

**Process:**
1. Player offers draw
2. Opponent can accept or decline
3. If accepted, game ends in draw

**Notation:** `½-½` in PGN

---

## Chess Notation

### Algebraic Notation (Standard)

**Format:** `[Piece][From Square][Capture][To Square][Promotion][Check/Checkmate]`

**Pieces:**
- K = King
- Q = Queen
- R = Rook
- B = Bishop
- N = Knight
- (no letter) = Pawn

**Examples:**
- `e4` - Pawn to e4
- `Nf3` - Knight to f3
- `Bxc6` - Bishop captures on c6
- `Qh5+` - Queen to h5, check
- `e8=Q#` - Pawn to e8, promotes to queen, checkmate
- `O-O` - Kingside castling
- `O-O-O` - Queenside castling
- `Nbd7` - Knight from b-file to d7 (disambiguation)

**Disambiguation:**
When two pieces of same type can move to same square:
- Add file letter: `Nbd7` (knight from b-file)
- Add rank number: `R1e2` (rook from rank 1)
- Add both if needed: `Qh4e1`

---

### FEN (Forsyth-Edwards Notation)

**Purpose:** Represent board position in single string

**Format:** `[Position] [Turn] [Castling] [En Passant] [Halfmove] [Fullmove]`

**Example:**
```
rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1
```

**Components:**

1. **Position** (ranks 8-1, separated by `/`):
   - Lowercase = black pieces
   - Uppercase = white pieces
   - Numbers = empty squares
   - `/` = next rank

2. **Turn**:
   - `w` = white to move
   - `b` = black to move

3. **Castling Rights**:
   - `K` = white kingside
   - `Q` = white queenside
   - `k` = black kingside
   - `q` = black queenside
   - `-` = no castling available

4. **En Passant**:
   - Target square (e.g., `e3`)
   - `-` if not available

5. **Halfmove Clock**:
   - Moves since last capture/pawn move

6. **Fullmove Number**:
   - Increments after black's move

**Implementation:**
```javascript
function toFEN(board, gameState, currentTurn) {
    let fen = '';

    // Position
    for (let row = 0; row < 8; row++) {
        let emptyCount = 0;
        for (let col = 0; col < 8; col++) {
            const piece = board.getPiece(row, col);
            if (piece) {
                if (emptyCount > 0) {
                    fen += emptyCount;
                    emptyCount = 0;
                }
                fen += piece.toFENChar();
            } else {
                emptyCount++;
            }
        }
        if (emptyCount > 0) fen += emptyCount;
        if (row < 7) fen += '/';
    }

    // Turn
    fen += ` ${currentTurn[0]}`;

    // Castling
    fen += ` ${gameState.castlingRights || '-'}`;

    // En passant
    fen += ` ${gameState.enPassantTarget || '-'}`;

    // Clocks
    fen += ` ${gameState.halfMoveClock} ${gameState.fullMoveNumber}`;

    return fen;
}
```

---

### PGN (Portable Game Notation)

**Purpose:** Record complete game with metadata

**Format:**
```
[Event "Casual Game"]
[Site "Online"]
[Date "2025.01.22"]
[Round "1"]
[White "Player 1"]
[Black "Player 2"]
[Result "1-0"]

1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7
6. Re1 b5 7. Bb3 d6 8. c3 O-O 9. h3 Nb8 1-0
```

**Results:**
- `1-0` - White wins
- `0-1` - Black wins
- `1/2-1/2` - Draw
- `*` - Game in progress

---

## Rule Edge Cases

### Illegal Positions

**Positions that cannot occur:**
- Both kings in check simultaneously
- Pawn on rank 1 or 8 (must have promoted)
- More than 8 pawns of one color
- More than 16 pieces of one color total
- Castling when king/rook has moved

### Ambiguous Captures

When multiple pieces can capture same square:
```
Raxe1  // Rook from a-file captures
R1xe1  // Rook from rank 1 captures
Qh4e1  // Queen from h4 captures (needs both)
```

### Pawn Captures and Files

Pawn captures include file letter:
```
exd5   // Pawn from e-file captures on d5
e4     // Pawn moves to e4 (no capture)
```

### Check and Illegal Moves

**Invalid moves:**
- Moving into check
- Not responding to check
- Exposing own king to check

All must be prevented in implementation!

---

## Implementation Checklist

Use this checklist to validate your chess implementation:

### Basic Movement
- [ ] All pieces move according to rules
- [ ] Pieces cannot move through others (except knight)
- [ ] Pieces cannot capture own color
- [ ] Pawns move forward only
- [ ] Pawns capture diagonally

### Special Moves
- [ ] Pawn double-move from start
- [ ] En passant capture
- [ ] En passant expires after one turn
- [ ] Castling kingside
- [ ] Castling queenside
- [ ] Castling prevented by moved pieces
- [ ] Cannot castle through check
- [ ] Cannot castle in/out of check
- [ ] Pawn promotion
- [ ] Pawn promotion piece selection

### Check/Checkmate
- [ ] Detect when king is in check
- [ ] Prevent moves that leave king in check
- [ ] Force response to check
- [ ] Detect checkmate
- [ ] Detect stalemate

### Draw Conditions
- [ ] Insufficient material
- [ ] Threefold repetition
- [ ] Fifty-move rule
- [ ] Draw by agreement

### Notation
- [ ] FEN export
- [ ] FEN import
- [ ] PGN export
- [ ] Algebraic notation for moves
- [ ] Move disambiguation

---

**For implementation details, see [IMPLEMENTATION_GUIDE.md](IMPLEMENTATION_GUIDE.md)**

**For API reference, see [API_REFERENCE.md](API_REFERENCE.md)**
