# 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
``` ### Step 4.2: Implement PieceView.js **File**: `js/views/PieceView.js` **Key Methods**: ```javascript renderPiece(piece, square) // Create piece element and add to square // Use Unicode symbols or images removePiece(position) movePiece(from, to, animate = true) // Animate piece movement enableDragDrop(pieceElement, callbacks) // Setup drag and drop handlers ``` **Piece Representation**: ```javascript const PIECE_SYMBOLS = { 'white-king': '♔', 'white-queen': '♕', 'white-rook': '♖', // ... or use images }; ``` ### Step 4.3: Implement UIManager.js **File**: `js/views/UIManager.js` **UI Elements**: ```javascript showMessage(text, type = 'info') // Display status message showCheckIndicator(color) showPromotionDialog(callback) // Show piece selection for pawn promotion updateTurnIndicator(color) updateCapturedPieces(pieces) enableControls() / disableControls() ``` ## Phase 5: Controllers (Days 8-9) ### Step 5.1: Implement MoveController.js **File**: `js/controllers/MoveController.js` **Workflow**: ```javascript handleMoveAttempt(piece, from, to) { // 1. Validate move if (!this.validator.isValidMove(piece, from, to, board)) { return { success: false, reason: 'Invalid move' }; } // 2. Execute move const capturedPiece = this.executeMove(piece, from, to); // 3. Check for special rules if (piece.type === 'pawn' && this._isPromotionRow(to)) { this._handlePromotion(piece); } // 4. Update game state this.gameState.addMove({piece, from, to, captured: capturedPiece}); // 5. Check for check/checkmate this._checkGameStatus(); // 6. Switch turn this.gameState.switchTurn(); return { success: true, captured: capturedPiece }; } ``` ### Step 5.2: Implement GameController.js **File**: `js/controllers/GameController.js` **Main Loop**: ```javascript class GameController { constructor(board, gameState, moveController, uiManager) { // Initialize dependencies this._setupEventListeners(); } startNewGame() { // Reset board and state // Render initial position // Start player's turn } _setupEventListeners() { // Listen for square clicks // Handle piece selection // Handle move attempts } _handleSquareClick(row, col) { if (!this.selectedPiece) { // Try to select piece this._selectPiece(row, col); } else { // Try to move selected piece this._attemptMove(row, col); } } } ``` ### Step 5.3: Implement AIController.js **File**: `js/controllers/AIController.js` **AI Strategy** (Start Simple): ```javascript // Level 1: Random valid move getRandomMove(color, board) { const validMoves = this.moveGen.getAllValidMoves(color, board); return validMoves[Math.floor(Math.random() * validMoves.length)]; } // Level 2: Material evaluation getBestMove(color, board, depth = 2) { // Minimax algorithm // Evaluate position based on piece values // Return best move } ``` **Piece Values**: - Pawn: 1 - Knight: 3 - Bishop: 3 - Rook: 5 - Queen: 9 - King: ∞ ## Phase 6: Integration (Day 10) ### Step 6.1: Create main.js **File**: `js/main.js` ```javascript import Board from './models/Board.js'; import GameState from './models/GameState.js'; import GameController from './controllers/GameController.js'; // ... import all dependencies // Wait for DOM document.addEventListener('DOMContentLoaded', () => { // Initialize models const board = new Board(); const gameState = new GameState(); // Initialize views const boardView = new BoardView(document.querySelector('.board')); const uiManager = new UIManager(); // Initialize controllers const moveController = new MoveController(/* dependencies */); const gameController = new GameController(/* dependencies */); // Start game gameController.startNewGame(); }); ``` ### Step 6.2: Create index.html **File**: `index.html` ```html Chess Game

Chess Game

White's Turn
``` ## Critical Implementation Notes ### Common Pitfalls 1. **Check Validation Loop** - Don't call `isKingInCheck()` inside `getValidMoves()` - Use two-pass validation: piece moves → filter exposing king 2. **Deep Cloning** - Board cloning must deep clone all pieces - Use JSON or manual clone, not shallow copy 3. **Event Listeners** - Remove old listeners before adding new ones - Use event delegation for dynamically created elements 4. **State Management** - Keep single source of truth (GameState) - Don't duplicate state in multiple places 5. **Performance** - Cache valid moves when position hasn't changed - Use early returns in validation - Avoid re-rendering entire board on each move ### Testing Strategy 1. **Unit Tests First** - Test each piece movement in isolation - Test board operations - Test validation logic 2. **Integration Tests** - Test complete move flow - Test check/checkmate scenarios - Test special moves (castling, en passant) 3. **Manual Testing Scenarios** - Scholar's mate (4-move checkmate) - Fool's mate (2-move checkmate) - Castling (both sides) - Pawn promotion - Stalemate positions ## Dependencies Between Components ``` Phase 1 (Utils) → Phase 2 (Models) → Phase 3 (Engine) → Phase 4 (Views) → Phase 5 (Controllers) → Phase 6 (Integration) ``` **Parallel Development**: - Views can be developed alongside Engine - AI can be developed after basic game works - Tests can be written alongside implementation ## Success Criteria ### Minimum Viable Product (MVP) - [ ] All pieces move according to chess rules - [ ] Can detect check - [ ] Can detect checkmate - [ ] Player vs player works - [ ] Can start new game ### Full Feature Set - [ ] Player vs computer AI - [ ] Pawn promotion - [ ] Castling (both sides) - [ ] En passant - [ ] Stalemate detection - [ ] Move history - [ ] Undo move - [ ] Highlight valid moves - [ ] Capture display - [ ] Animated moves ## Estimated Timeline - **Phase 1**: 4 hours - **Phase 2**: 8 hours - **Phase 3**: 8 hours - **Phase 4**: 6 hours - **Phase 5**: 8 hours - **Phase 6**: 4 hours - **Testing & Polish**: 8 hours **Total**: ~45 hours (1-2 weeks for one developer) ## Next Steps 1. Review this guide with the team 2. Set up development environment 3. Start with Phase 1 (Foundation) 4. Implement in order, testing as you go 5. Use the code templates as starting points 6. Reference coding standards for style 7. Coordinate via memory for swarm work