# Developer Guide - HTML Chess Game

## Table of Contents

1. [Development Environment](#development-environment)
2. [Project Structure](#project-structure)
3. [Development Workflow](#development-workflow)
4. [Testing Strategy](#testing-strategy)
5. [Debugging Guide](#debugging-guide)
6. [Performance Optimization](#performance-optimization)
7. [Code Style Guide](#code-style-guide)
8. [Deployment](#deployment)
9. [Troubleshooting](#troubleshooting)

---

## Development Environment

### Prerequisites

**Required:**
- Modern web browser (Chrome 60+, Firefox 54+, Safari 10.1+, Edge 79+)
- Text editor or IDE (VS Code recommended)
- Git for version control

**Optional:**
- Node.js (for local server and testing)
- Browser dev tools extensions
- Code formatters (Prettier recommended)

### Initial Setup

#### 1. Clone or Create Project

```bash
# Create new project
mkdir chess-game
cd chess-game

# Initialize git (optional)
git init

# Create project structure
mkdir -p {css,js/{game,pieces,moves,ui,utils},assets/pieces,tests/{unit,integration},docs}
```

#### 2. Install Development Tools (Optional)

```bash
# Initialize npm (for testing framework)
npm init -y

# Install dev dependencies (optional)
npm install --save-dev \
    live-server \
    eslint \
    prettier \
    jest
```

#### 3. Set Up Live Server

**Option 1: Using Python**
```bash
python3 -m http.server 8000
```

**Option 2: Using Node.js**
```bash
npx http-server -p 8000
```

**Option 3: Using VS Code Extension**
- Install "Live Server" extension
- Right-click `index.html` → "Open with Live Server"

#### 4. Configure Editor

**VS Code Settings (.vscode/settings.json):**
```json
{
    "editor.formatOnSave": true,
    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "javascript.preferences.quoteStyle": "single",
    "files.eol": "\n",
    "files.insertFinalNewline": true,
    "files.trimTrailingWhitespace": true
}
```

**ESLint Config (.eslintrc.json):**
```json
{
    "env": {
        "browser": true,
        "es2021": true
    },
    "extends": "eslint:recommended",
    "parserOptions": {
        "ecmaVersion": 12,
        "sourceType": "module"
    },
    "rules": {
        "indent": ["error", 4],
        "quotes": ["error", "single"],
        "semi": ["error", "always"]
    }
}
```

**Prettier Config (.prettierrc):**
```json
{
    "singleQuote": true,
    "tabWidth": 4,
    "useTabs": false,
    "semi": true,
    "trailingComma": "es5"
}
```

---

## Project Structure

### Directory Organization

```
chess-game/
├── index.html              # Main entry point
├── package.json            # npm configuration (optional)
├── .gitignore              # Git ignore rules
├── .eslintrc.json          # ESLint configuration
├── .prettierrc             # Prettier configuration
│
├── css/                    # Stylesheets
│   ├── board.css          # Chess board styling
│   ├── pieces.css         # Piece styling
│   └── ui.css             # UI components
│
├── js/                     # JavaScript modules
│   ├── main.js            # Application entry point
│   │
│   ├── game/              # Game logic
│   │   ├── ChessGame.js   # Main game controller
│   │   ├── Board.js       # Board state management
│   │   └── GameState.js   # Game state and history
│   │
│   ├── pieces/            # Piece implementations
│   │   ├── Piece.js       # Base piece class
│   │   ├── Pawn.js        # Pawn logic
│   │   ├── Knight.js      # Knight logic
│   │   ├── Bishop.js      # Bishop logic
│   │   ├── Rook.js        # Rook logic
│   │   ├── Queen.js       # Queen logic
│   │   └── King.js        # King logic
│   │
│   ├── moves/             # Move validation
│   │   ├── MoveValidator.js    # Move validation
│   │   ├── MoveGenerator.js    # Legal move generation
│   │   └── SpecialMoves.js     # Special moves
│   │
│   ├── ui/                # UI components
│   │   ├── BoardRenderer.js    # Board rendering
│   │   ├── DragDropHandler.js  # Drag-and-drop
│   │   └── UIController.js     # UI state management
│   │
│   └── utils/             # Utilities
│       ├── notation.js    # Chess notation
│       ├── storage.js     # localStorage wrapper
│       └── helpers.js     # Helper functions
│
├── assets/                # Static assets
│   └── pieces/            # Piece images (SVG)
│       ├── white-king.svg
│       ├── white-queen.svg
│       └── ...
│
├── tests/                 # Test files
│   ├── unit/              # Unit tests
│   │   ├── Board.test.js
│   │   ├── pieces/
│   │   └── moves/
│   │
│   └── integration/       # Integration tests
│       └── gameplay.test.js
│
└── docs/                  # Documentation
    ├── README.md
    ├── IMPLEMENTATION_GUIDE.md
    ├── API_REFERENCE.md
    └── ...
```

### Module Dependencies

```
main.js
  ├── ChessGame.js
  │   ├── Board.js
  │   ├── GameState.js
  │   └── MoveValidator.js
  │       ├── Piece.js (and subclasses)
  │       └── SpecialMoves.js
  │
  └── UIController.js
      ├── BoardRenderer.js
      └── DragDropHandler.js

Utilities (used everywhere):
  ├── notation.js
  ├── storage.js
  └── helpers.js
```

---

## Development Workflow

### 1. Feature Development Cycle

```bash
# 1. Create feature branch (if using git)
git checkout -b feature/castling-logic

# 2. Write failing test first (TDD)
# Edit tests/unit/moves/SpecialMoves.test.js

# 3. Run tests
npm test

# 4. Implement feature
# Edit js/moves/SpecialMoves.js

# 5. Run tests until passing
npm test

# 6. Refactor if needed
# Clean up code, improve performance

# 7. Commit changes
git add .
git commit -m "feat: implement castling logic"

# 8. Merge to main
git checkout main
git merge feature/castling-logic
```

### 2. Daily Development Routine

**Morning:**
1. Pull latest changes
2. Review open issues
3. Plan tasks for the day
4. Set up development environment

**During Development:**
1. Write test first (TDD)
2. Implement minimal code to pass
3. Refactor for quality
4. Commit frequently
5. Run full test suite periodically

**End of Day:**
1. Run full test suite
2. Commit all changes
3. Push to repository
4. Update task tracker
5. Document any blockers

### 3. Code Review Process

**Before Requesting Review:**
- [ ] All tests passing
- [ ] Code formatted and linted
- [ ] No console errors
- [ ] Documentation updated
- [ ] Self-review completed

**Review Checklist:**
- [ ] Code follows style guide
- [ ] Tests are comprehensive
- [ ] No performance regressions
- [ ] Edge cases handled
- [ ] Documentation accurate

---

## Testing Strategy

### Unit Testing

**Framework:** Jest (or your choice)

**Test Structure:**
```javascript
// tests/unit/pieces/Rook.test.js
import { Rook } from '../../../js/pieces/Rook.js';
import { Board } from '../../../js/game/Board.js';

describe('Rook', () => {
    let board;

    beforeEach(() => {
        board = new Board();
        board.clear(); // Start with empty board
    });

    describe('getValidMoves', () => {
        it('should move vertically', () => {
            const rook = new Rook('white', {row: 4, col: 4});
            board.setPiece(4, 4, rook);

            const moves = rook.getValidMoves(board);
            const verticalMoves = moves.filter(m => m.col === 4);

            expect(verticalMoves.length).toBe(7);
        });

        it('should be blocked by friendly pieces', () => {
            const rook = new Rook('white', {row: 4, col: 4});
            const blockingPawn = new Pawn('white', {row: 4, col: 6});

            board.setPiece(4, 4, rook);
            board.setPiece(4, 6, blockingPawn);

            const moves = rook.getValidMoves(board);
            const rightMoves = moves.filter(m => m.row === 4 && m.col > 4);

            expect(rightMoves.length).toBe(1); // Only to col 5
        });

        it('should capture enemy pieces', () => {
            const rook = new Rook('white', {row: 4, col: 4});
            const enemyPawn = new Pawn('black', {row: 4, col: 6});

            board.setPiece(4, 4, rook);
            board.setPiece(4, 6, enemyPawn);

            const moves = rook.getValidMoves(board);
            const canCaptureEnemy = moves.some(m =>
                m.row === 4 && m.col === 6
            );

            expect(canCaptureEnemy).toBe(true);
        });
    });
});
```

**Run Tests:**
```bash
# Run all tests
npm test

# Run specific file
npm test -- Rook.test.js

# Run with coverage
npm test -- --coverage

# Watch mode
npm test -- --watch
```

### Integration Testing

**Test Complete Scenarios:**
```javascript
// tests/integration/gameplay.test.js
describe('Complete Game Scenarios', () => {
    it('should handle Scholar\'s Mate', () => {
        const game = new ChessGame();

        // Move sequence
        expect(game.makeMove(6, 4, 4, 4).success).toBe(true); // e4
        expect(game.makeMove(1, 4, 3, 4).success).toBe(true); // e5
        expect(game.makeMove(7, 5, 4, 2).success).toBe(true); // Bc4
        expect(game.makeMove(1, 1, 2, 2).success).toBe(true); // Nc6
        expect(game.makeMove(7, 3, 3, 7).success).toBe(true); // Qh5
        expect(game.makeMove(1, 6, 2, 5).success).toBe(true); // Nf6
        expect(game.makeMove(3, 7, 1, 5).success).toBe(true); // Qxf7#

        // Verify checkmate
        expect(game.status).toBe('checkmate');
        expect(game.winner).toBe('white');
    });

    it('should handle stalemate', () => {
        const game = new ChessGame();

        // Set up stalemate position
        game.board.fromFEN('7k/5Q2/6K1/8/8/8/8/8 b - - 0 1');

        expect(game.isStalemate('black')).toBe(true);
        expect(game.status).toBe('stalemate');
    });
});
```

### Manual Testing Checklist

**Before Each Release:**
- [ ] All piece types move correctly
- [ ] Special moves work (castling, en passant, promotion)
- [ ] Check detection accurate
- [ ] Checkmate detection accurate
- [ ] Stalemate detection accurate
- [ ] UI responsive and intuitive
- [ ] Save/load functionality works
- [ ] Undo/redo works correctly
- [ ] No console errors
- [ ] Performance acceptable
- [ ] Works in all target browsers

---

## Debugging Guide

### Browser Developer Tools

**Console Debugging:**
```javascript
// Add debug logging
console.log('Move validation:', {
    piece: piece.type,
    from: {row: fromRow, col: fromCol},
    to: {row: toRow, col: toCol},
    valid: result
});

// Use debugger statement
function makeMove(fromRow, fromCol, toRow, toCol) {
    debugger; // Execution will pause here
    const piece = this.board.getPiece(fromRow, fromCol);
    // ...
}

// Group related logs
console.group('Move Validation');
console.log('Piece:', piece);
console.log('Valid moves:', validMoves);
console.log('Target:', {toRow, toCol});
console.groupEnd();
```

**Breakpoints:**
1. Open DevTools (F12)
2. Go to Sources tab
3. Find your file
4. Click line number to set breakpoint
5. Refresh page to trigger

**Watch Expressions:**
- Add `this.board.grid` to watch
- Add `this.gameState.moveHistory` to watch
- Add `this.currentTurn` to watch

### Common Issues and Solutions

#### Issue: Infinite Recursion in Check Detection

**Problem:**
```javascript
// Bad: Causes infinite loop
function isMoveLegal(board, piece, toRow, toCol) {
    const validMoves = piece.getValidMoves(board); // Calls isMoveLegal again!
    // ...
}
```

**Solution:**
```javascript
// Good: Separate concerns
function getValidMoves(board, piece) {
    // Get moves without check validation
}

function getLegalMoves(board, piece) {
    // Filter valid moves by check constraint
    return getValidMoves(board, piece)
        .filter(move => !leavesKingInCheck(board, piece, move));
}
```

#### Issue: Drag and Drop Not Working

**Checklist:**
- [ ] Element has `draggable="true"`
- [ ] Event listeners attached to correct elements
- [ ] `dataTransfer` used correctly
- [ ] `preventDefault()` called in `dragover`

**Debug:**
```javascript
boardElement.addEventListener('dragstart', (e) => {
    console.log('Drag started:', e.target);
    console.log('Data:', e.dataTransfer.getData('text/plain'));
});

boardElement.addEventListener('dragover', (e) => {
    console.log('Drag over:', e.target);
    e.preventDefault(); // Don't forget this!
});
```

#### Issue: Pieces Not Rendering

**Checklist:**
- [ ] CSS classes applied correctly
- [ ] Grid layout configured
- [ ] Z-index issues
- [ ] Unicode symbols or images loading

**Debug:**
```javascript
// Verify DOM structure
console.log('Board HTML:', boardElement.innerHTML);
console.log('Squares:', boardElement.querySelectorAll('.square').length);
console.log('Pieces:', boardElement.querySelectorAll('.piece').length);
```

### Performance Profiling

**Using Chrome DevTools:**
1. Open DevTools → Performance tab
2. Click Record
3. Perform action (e.g., make move)
4. Stop recording
5. Analyze timeline

**Identify Bottlenecks:**
- Excessive DOM manipulation
- Slow move validation
- Memory leaks
- Unnecessary re-renders

**Solution:**
```javascript
// Before: Slow
function updateBoard() {
    boardElement.innerHTML = ''; // Triggers reflow
    for (let row = 0; row < 8; row++) {
        for (let col = 0; col < 8; col++) {
            // Create and append elements
        }
    }
}

// After: Fast
function updateBoard() {
    const fragment = document.createDocumentFragment();
    for (let row = 0; row < 8; row++) {
        for (let col = 0; col < 8; col++) {
            // Create elements and append to fragment
        }
    }
    boardElement.innerHTML = '';
    boardElement.appendChild(fragment); // Single reflow
}
```

---

## Performance Optimization

### Minimize DOM Manipulation

**Use Document Fragments:**
```javascript
const fragment = document.createDocumentFragment();
// Add all elements to fragment
container.appendChild(fragment); // Single DOM update
```

**Batch Updates:**
```javascript
// Bad: Multiple reflows
element.style.width = '100px';
element.style.height = '100px';
element.style.backgroundColor = 'red';

// Good: Single reflow
element.style.cssText = 'width: 100px; height: 100px; background-color: red;';
```

### Memoize Expensive Calculations

```javascript
class Piece {
    constructor() {
        this._validMovesCache = null;
        this._cacheValidUntil = null;
    }

    getValidMoves(board) {
        const boardHash = board.getHash();

        if (this._cacheValidUntil === boardHash) {
            return this._validMovesCache;
        }

        // Calculate moves
        this._validMovesCache = this.calculateValidMoves(board);
        this._cacheValidUntil = boardHash;

        return this._validMovesCache;
    }

    invalidateCache() {
        this._validMovesCache = null;
        this._cacheValidUntil = null;
    }
}
```

### Debounce UI Updates

```javascript
function debounce(func, wait) {
    let timeout;
    return function executedFunction(...args) {
        const later = () => {
            clearTimeout(timeout);
            func(...args);
        };
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
    };
}

// Usage
const updateUI = debounce(() => {
    renderer.renderBoard(game.board, game.gameState);
}, 100);
```

### Optimize Event Handlers

**Use Event Delegation:**
```javascript
// Bad: Many listeners
squares.forEach(square => {
    square.addEventListener('click', handleClick);
});

// Good: Single listener
boardElement.addEventListener('click', (e) => {
    const square = e.target.closest('.square');
    if (square) {
        handleClick(square);
    }
});
```

---

## Code Style Guide

### Naming Conventions

**Variables:**
```javascript
// camelCase for variables and functions
const currentTurn = 'white';
const isKingInCheck = true;

function makeMove(from, to) { }
```

**Classes:**
```javascript
// PascalCase for classes
class ChessGame { }
class MoveValidator { }
```

**Constants:**
```javascript
// UPPER_SNAKE_CASE for constants
const MAX_MOVES = 500;
const DEFAULT_FEN = 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1';
```

**Private Members:**
```javascript
// Prefix with underscore
class Piece {
    constructor() {
        this._cachedMoves = null;
    }
}
```

### File Organization

**One class per file:**
```javascript
// Good: Rook.js
export class Rook extends Piece {
    // ...
}

// Bad: pieces.js with all pieces
export class Rook { }
export class Bishop { }
export class Knight { }
```

**Related functions can be grouped:**
```javascript
// utils/helpers.js
export function clamp(value, min, max) { }
export function isInBounds(row, col) { }
export function getOppositeColor(color) { }
```

### Documentation

**JSDoc Comments:**
```javascript
/**
 * Validates if a move is legal according to chess rules
 *
 * @param {Board} board - The current board state
 * @param {Piece} piece - The piece to move
 * @param {number} toRow - Target row (0-7)
 * @param {number} toCol - Target column (0-7)
 * @param {GameState} gameState - Current game state
 * @returns {boolean} True if move is legal
 */
static isMoveLegal(board, piece, toRow, toCol, gameState) {
    // ...
}
```

### Error Handling

**Use descriptive errors:**
```javascript
// Good
if (!piece) {
    throw new Error(`No piece found at position (${row}, ${col})`);
}

// Bad
if (!piece) {
    throw new Error('Invalid');
}
```

**Return result objects:**
```javascript
function makeMove(from, to) {
    if (!isValid) {
        return {
            success: false,
            error: 'Invalid move: piece cannot move there'
        };
    }

    return {
        success: true,
        move: executedMove
    };
}
```

---

## Deployment

### Pre-Deployment Checklist

- [ ] All tests passing
- [ ] No console errors
- [ ] Code minified (optional)
- [ ] Assets optimized
- [ ] Browser compatibility tested
- [ ] Performance acceptable
- [ ] Documentation updated

### Build Process (Optional)

If using build tools:

```bash
# Install build tools
npm install --save-dev webpack webpack-cli

# Create webpack.config.js
# Build for production
npm run build
```

### Static Hosting

**GitHub Pages:**
```bash
# Create gh-pages branch
git checkout -b gh-pages

# Push to GitHub
git push origin gh-pages

# Access at: https://username.github.io/chess-game
```

**Netlify:**
1. Connect GitHub repository
2. Set build command (if any)
3. Set publish directory
4. Deploy

**Vercel:**
```bash
npm install -g vercel
vercel deploy
```

### Performance Optimization for Production

**Minify CSS/JS:**
```bash
# CSS
npx cssnano css/board.css > dist/board.min.css

# JS
npx terser js/main.js -o dist/main.min.js
```

**Optimize Images:**
- Use SVG for piece images (scalable)
- Compress PNG/JPG if used
- Use appropriate formats

**Enable Compression:**
```
# .htaccess for Apache
<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/html text/css application/javascript
</IfModule>
```

---

## Troubleshooting

### Common Errors

**"Uncaught TypeError: Cannot read property 'grid' of undefined"**
- Board not initialized
- Check constructor calls
- Verify import statements

**"Maximum call stack size exceeded"**
- Infinite recursion
- Check move validation logic
- Verify event listener cleanup

**Drag and drop not working**
- Check draggable attribute
- Verify event listeners
- Call preventDefault() in dragover

### Getting Help

1. Check documentation
2. Review API reference
3. Search existing issues
4. Ask specific questions with code samples

---

**Next:** See [HANDOFF_CHECKLIST.md](HANDOFF_CHECKLIST.md) for implementation timeline
