# Implementation Guide - Chess Game ## Overview Step-by-step guide for implementing the HTML chess game with single-player functionality. ## Phase 1: Foundation (Day 1) ### Step 1.1: Create Project Structure ```bash mkdir chess-game cd chess-game mkdir -p css js/{models,controllers,views,engine,utils} assets/{pieces,sounds} tests touch index.html css/{main,board,pieces,game-controls,animations}.css ``` ### Step 1.2: Implement Constants.js **File**: `js/utils/Constants.js` **Key Elements**: - Board dimensions (8x8) - Piece types and colors - Initial piece positions - Game status constants **Test Criteria**: - All constants are immutable (use `Object.freeze()`) - Initial positions are valid board coordinates - No duplicate piece positions ### Step 1.3: Implement Helpers.js **File**: `js/utils/Helpers.js` **Key Functions**: ```javascript // Position validation isValidPosition(row, col) // Position comparison positionsEqual(pos1, pos2) // Coordinate conversion algebraicToPosition('e4') // → {row: 4, col: 4} positionToAlgebraic({row: 4, col: 4}) // → 'e4' // Array utilities deepClone(obj) ``` **Test Criteria**: - Boundary testing (row/col 0-7) - Invalid input handling - Correct algebraic notation conversion ### Step 1.4: Implement EventBus.js **File**: `js/utils/EventBus.js` **Key Features**: - Subscribe to events - Publish events - Unsubscribe from events **Events to Support**: - `piece:selected` - `piece:moved` - `piece:captured` - `game:check` - `game:checkmate` - `game:over` - `turn:changed` ## Phase 2: Data Models (Days 2-3) ### Step 2.1: Implement Board.js **File**: `js/models/Board.js` **Key Methods**: ```javascript constructor() // Initialize 8x8 grid getPieceAt(position) // Get piece at position setPieceAt(position, piece) // Place piece removePieceAt(position) // Remove piece movePiece(from, to) // Move piece (update positions) getAllPieces() // Get all pieces on board getPiecesByColor(color) // Get pieces of one color clone() // Deep copy board state reset() // Reset to initial state ``` **Data Structure**: ```javascript // Use 2D array this._squares = Array(8).fill(null).map(() => Array(8).fill(null)); // Or use Map for sparse storage this._pieces = new Map(); // key: 'row-col', value: Piece ``` **Test Criteria**: - Initial setup has 32 pieces - Can get/set pieces correctly - Clone creates independent copy - Moving piece updates both positions ### Step 2.2: Implement Piece.js (Base Class) **File**: `js/models/Piece.js` **Properties**: ```javascript constructor(color, position, type) { this.color = color; // 'white' or 'black' this.position = position; // {row, col} this.type = type; // 'pawn', 'rook', etc. this.hasMoved = false; // For castling/pawn moves } ``` **Methods**: ```javascript move(newPosition) // Update position getValidMoves(board) // Abstract - override in subclasses canMoveTo(position, board) // Check if specific move is valid clone() // Create copy ``` ### Step 2.3: Implement Individual Pieces **Files**: `js/models/pieces/*.js` #### Implementation Order: 1. **Rook.js** (simplest - straight lines) 2. **Bishop.js** (diagonal lines) 3. **Queen.js** (combines rook + bishop) 4. **Knight.js** (L-shapes, no blocking) 5. **King.js** (one square, castling) 6. **Pawn.js** (most complex - promotion, en passant) #### Example: Pawn.js Template ```javascript import Piece from '../Piece.js'; class Pawn extends Piece { constructor(color, position) { super(color, position, 'pawn'); } getValidMoves(board) { const moves = []; const direction = this.color === 'white' ? -1 : 1; const startRow = this.color === 'white' ? 6 : 1; // One square forward // Two squares forward (if on start row) // Diagonal captures // En passant (if applicable) return moves; } } export default Pawn; ``` **Test Each Piece**: - Starting position moves - Capture moves - Blocked moves - Edge of board - Special moves (castling, en passant, promotion) ### Step 2.4: Implement GameState.js **File**: `js/models/GameState.js` **Properties**: ```javascript constructor() { this.currentPlayer = 'white'; this.moveHistory = []; this.capturedPieces = []; this.isCheck = false; this.isCheckmate = false; this.isStalemate = false; this.enPassantTarget = null; // For en passant validation } ``` **Methods**: ```javascript switchTurn() addMove(move) // {piece, from, to, captured} getLastMove() isGameOver() reset() ``` ## Phase 3: Game Engine (Days 4-5) ### Step 3.1: Implement MoveValidator.js **File**: `js/engine/MoveValidator.js` **Key Methods**: ```javascript isValidMove(piece, from, to, board) // 1. Check if move is in piece's valid moves // 2. Check if move doesn't expose king to check // 3. Return true/false wouldExposeKing(piece, from, to, board) // Simulate move and check if king is in check isPiecePinned(piece, board) // Check if piece is pinned to king ``` ### Step 3.2: Implement MoveGenerator.js **File**: `js/engine/MoveGenerator.js` **Key Methods**: ```javascript getAllValidMoves(color, board) // Get all legal moves for a color // Used for: check detection, AI, stalemate hasValidMoves(color, board) // Quick check if player can move ``` ### Step 3.3: Implement CheckDetector.js **File**: `js/engine/CheckDetector.js` **Key Methods**: ```javascript isKingInCheck(color, board) // Check if king is under attack isCheckmate(color, board) // Check if in check AND no valid moves isStalemate(color, board) // Check if NOT in check AND no valid moves getAttackingPieces(color, board) // Get pieces attacking the king ``` ### Step 3.4: Implement RuleEngine.js **File**: `js/engine/RuleEngine.js` **Special Rules**: ```javascript canCastle(king, rook, board) // Kingside or queenside castling isEnPassantValid(pawn, target, board, gameState) // Check en passant conditions handlePawnPromotion(pawn, choice = 'queen') // Promote pawn to chosen piece ``` ## Phase 4: Views (Days 6-7) ### Step 4.1: Implement BoardView.js **File**: `js/views/BoardView.js` **Key Methods**: ```javascript render(board) // Create 64 squares with alternating colors // Add coordinate labels (a-h, 1-8) highlightSquare(position, className) // Highlight selected piece or valid moves clearHighlights() getSquareElement(position) // Get DOM element for position ``` **HTML Structure**: ```html