chess/docs/architecture/data-models.md
Christoph Wagner 5ad0700b41 refactor: Consolidate repository structure - flatten from workspace pattern
Restructured project from nested workspace pattern to flat single-repo layout.
This eliminates redundant nesting and consolidates all project files under version control.

## Migration Summary

**Before:**
```
alex/ (workspace, not versioned)
├── chess-game/ (git repo)
│   ├── js/, css/, tests/
│   └── index.html
└── docs/ (planning, not versioned)
```

**After:**
```
alex/ (git repo, everything versioned)
├── js/, css/, tests/
├── index.html
├── docs/ (project documentation)
├── planning/ (historical planning docs)
├── .gitea/ (CI/CD)
└── CLAUDE.md (configuration)
```

## Changes Made

### Structure Consolidation
- Moved all chess-game/ contents to root level
- Removed redundant chess-game/ subdirectory
- Flattened directory structure (eliminated one nesting level)

### Documentation Organization
- Moved chess-game/docs/ → docs/ (project documentation)
- Moved alex/docs/ → planning/ (historical planning documents)
- Added CLAUDE.md (workspace configuration)
- Added IMPLEMENTATION_PROMPT.md (original project prompt)

### Version Control Improvements
- All project files now under version control
- Planning documents preserved in planning/ folder
- Merged .gitignore files (workspace + project)
- Added .claude/ agent configurations

### File Updates
- Updated .gitignore to include both workspace and project excludes
- Moved README.md to root level
- All import paths remain functional (relative paths unchanged)

## Benefits

 **Simpler Structure** - One level of nesting removed
 **Complete Versioning** - All documentation now in git
 **Standard Layout** - Matches open-source project conventions
 **Easier Navigation** - Direct access to all project files
 **CI/CD Compatible** - All workflows still functional

## Technical Validation

-  Node.js environment verified
-  Dependencies installed successfully
-  Dev server starts and responds
-  All core files present and accessible
-  Git repository functional

## Files Preserved

**Implementation Files:**
- js/ (3,517 lines of code)
- css/ (4 stylesheets)
- tests/ (87 test cases)
- index.html
- package.json

**CI/CD Pipeline:**
- .gitea/workflows/ci.yml
- .gitea/workflows/release.yml

**Documentation:**
- docs/ (12+ documentation files)
- planning/ (historical planning materials)
- README.md

**Configuration:**
- jest.config.js, babel.config.cjs, playwright.config.js
- .gitignore (merged)
- CLAUDE.md

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-23 10:05:26 +01:00

528 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Data Models and Structures
## Core Data Structures
### 1. Square
Represents a single square on the chess board.
```javascript
class Square {
file: number; // 0-7 (a-h)
rank: number; // 0-7 (1-8)
color: 'light' | 'dark';
piece: ChessPiece | null;
// Helper methods
toAlgebraic(): string; // "e4"
fromAlgebraic(notation: string): Square;
equals(other: Square): boolean;
clone(): Square;
}
// Examples
{ file: 4, rank: 3, color: 'light', piece: null } // e4
{ file: 0, rank: 0, color: 'dark', piece: WhiteRook } // a1
```
**Algebraic Notation Mapping**:
- Files: a=0, b=1, c=2, d=3, e=4, f=5, g=6, h=7
- Ranks: 1=0, 2=1, 3=2, 4=3, 5=4, 6=5, 7=6, 8=7
---
### 2. BoardState
Represents the complete chess board configuration.
```javascript
class BoardState {
// Array representation (primary)
squares: Square[64];
// Alternative: 2D array
// grid: Square[8][8];
// Bitboard representation (optional, for performance)
bitboards: {
white: {
pawns: BigInt,
knights: BigInt,
bishops: BigInt,
rooks: BigInt,
queens: BigInt,
king: BigInt,
all: BigInt
},
black: { /* same structure */ },
occupied: BigInt,
empty: BigInt
};
// Helper methods
getSquare(file: number, rank: number): Square;
getSquareByIndex(index: number): Square;
getPieceAt(square: Square): ChessPiece | null;
setPieceAt(square: Square, piece: ChessPiece): void;
removePieceAt(square: Square): void;
clone(): BoardState;
toFEN(): string;
fromFEN(fen: string): BoardState;
}
```
**Index Calculation**:
```javascript
// Square to index: rank * 8 + file
// Index to square: { file: index % 8, rank: Math.floor(index / 8) }
```
**Starting Position FEN**:
```
rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1
```
---
### 3. PieceType Enumeration
```javascript
const PieceType = {
PAWN: 'pawn',
KNIGHT: 'knight',
BISHOP: 'bishop',
ROOK: 'rook',
QUEEN: 'queen',
KING: 'king'
};
const PieceValue = {
pawn: 1,
knight: 3,
bishop: 3,
rook: 5,
queen: 9,
king: Infinity
};
const PieceNotation = {
pawn: '', // No letter for pawns
knight: 'N',
bishop: 'B',
rook: 'R',
queen: 'Q',
king: 'K'
};
```
---
### 4. Move
Represents a single chess move with all metadata.
```javascript
class Move {
from: Square;
to: Square;
piece: PieceType;
color: 'white' | 'black';
captured: PieceType | null;
promotion: PieceType | null;
// Special move flags
isCastling: boolean;
isEnPassant: boolean;
isCheck: boolean;
isCheckmate: boolean;
// Metadata
notation: string; // "Nf3", "exd5", "O-O"
algebraicNotation: string; // "e2e4"
timestamp: number;
moveNumber: number;
// Methods
toSAN(): string; // Standard Algebraic Notation
toLAN(): string; // Long Algebraic Notation
toUCI(): string; // Universal Chess Interface
equals(other: Move): boolean;
clone(): Move;
}
```
**Notation Examples**:
- **SAN**: "Nf3", "e4", "O-O", "Qxe5+", "e8=Q#"
- **LAN**: "Ng1-f3", "e2-e4", "Qd1xe5+"
- **UCI**: "e2e4", "e7e5", "e1g1" (castling), "e7e8q" (promotion)
---
### 5. GameState
Complete game state snapshot for state management.
```javascript
class GameState {
board: BoardState;
currentPlayer: 'white' | 'black';
moveNumber: number;
halfMoveClock: number; // For 50-move rule
// Special move tracking
enPassantSquare: Square | null;
castlingRights: {
whiteKingSide: boolean,
whiteQueenSide: boolean,
blackKingSide: boolean,
blackQueenSide: boolean
};
// Game status
status: GameStatus;
lastMove: Move | null;
// Captured pieces
capturedPieces: {
white: PieceType[],
black: PieceType[]
};
// Methods
toFEN(): string;
fromFEN(fen: string): GameState;
clone(): GameState;
hash(): string; // For position repetition
equals(other: GameState): boolean;
}
```
**FEN Format**:
```
rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1
│ │ │ │ │ │
│ │ │ │ │ └─ Full move number
│ │ │ │ └─── Halfmove clock
│ │ │ └───── En passant square
│ │ └────────── Castling rights
│ └──────────── Active player
└──────────────────────────────────────────────────────── Board position
```
---
### 6. GameStatus Enumeration
```javascript
const GameStatus = {
ACTIVE: 'active',
CHECK: 'check',
CHECKMATE: 'checkmate',
STALEMATE: 'stalemate',
DRAW_50_MOVE: 'draw-50-move',
DRAW_REPETITION: 'draw-repetition',
DRAW_INSUFFICIENT: 'draw-insufficient-material',
DRAW_AGREEMENT: 'draw-agreement',
RESIGNATION: 'resignation'
};
```
---
### 7. GameConfiguration
Settings and options for game initialization.
```javascript
class GameConfig {
mode: 'pvp' | 'pva' | 'ava';
timeControl: TimeControl | null;
playerWhite: Player;
playerBlack: Player;
aiDifficulty: number; // 1-10 for AI opponent
theme: string;
soundEnabled: boolean;
animationSpeed: number; // ms for animations
autoSave: boolean;
legalMovesHighlight: boolean;
dragAndDrop: boolean;
}
class TimeControl {
type: 'none' | 'classical' | 'rapid' | 'blitz' | 'bullet';
initialTime: number; // seconds
increment: number; // seconds per move
whiteTime: number;
blackTime: number;
}
class Player {
name: string;
type: 'human' | 'ai';
color: 'white' | 'black';
elo: number | null;
}
```
---
### 8. MoveHistory
Structure for tracking complete game history.
```javascript
class MoveHistory {
moves: Move[];
positions: string[]; // FEN strings for repetition detection
currentIndex: number;
startingPosition: string; // Initial FEN
// PGN metadata
metadata: {
event: string,
site: string,
date: string,
round: string,
white: string,
black: string,
result: string
};
// Methods
addMove(move: Move, position: string): void;
getMove(index: number): Move;
getAllMoves(): Move[];
undo(): Move | null;
redo(): Move | null;
canUndo(): boolean;
canRedo(): boolean;
clear(): void;
toPGN(): string;
fromPGN(pgn: string): MoveHistory;
toJSON(): string;
fromJSON(json: string): MoveHistory;
}
```
**PGN Format Example**:
```
[Event "Casual Game"]
[Site "Chess App"]
[Date "2025.11.22"]
[Round "1"]
[White "Player 1"]
[Black "Player 2"]
[Result "1-0"]
1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 1-0
```
---
### 9. Event System
Event definitions for component communication.
```javascript
class GameEvent {
type: EventType;
payload: any;
timestamp: number;
source: string;
}
const EventType = {
// Board events
SQUARE_CLICKED: 'square-clicked',
PIECE_SELECTED: 'piece-selected',
PIECE_MOVED: 'piece-moved',
PIECE_CAPTURED: 'piece-captured',
PIECE_PROMOTED: 'piece-promoted',
// Game events
GAME_STARTED: 'game-started',
GAME_OVER: 'game-over',
TURN_CHANGED: 'turn-changed',
CHECK_DETECTED: 'check-detected',
MOVE_EXECUTED: 'move-executed',
MOVE_UNDONE: 'move-undone',
MOVE_REDONE: 'move-redone',
// UI events
THEME_CHANGED: 'theme-changed',
SETTINGS_UPDATED: 'settings-updated',
// AI events
AI_THINKING: 'ai-thinking',
AI_MOVE_READY: 'ai-move-ready',
// Error events
INVALID_MOVE: 'invalid-move',
VALIDATION_FAILED: 'validation-failed'
};
```
---
### 10. Bitboard Representation (Advanced)
For performance-critical operations and AI.
```javascript
class Bitboard {
value: BigInt; // 64-bit integer representing board
// Bitwise operations
setBit(square: Square): void;
clearBit(square: Square): void;
toggleBit(square: Square): void;
testBit(square: Square): boolean;
popCount(): number; // Count set bits
// Board operations
and(other: Bitboard): Bitboard;
or(other: Bitboard): Bitboard;
xor(other: Bitboard): Bitboard;
not(): Bitboard;
shift(direction: number): Bitboard;
// Move generation helpers
northOne(): Bitboard;
southOne(): Bitboard;
eastOne(): Bitboard;
westOne(): Bitboard;
getSetSquares(): Square[];
}
```
**Bitboard Example**:
```
Bit 0 = a1, Bit 1 = b1, ..., Bit 7 = h1
Bit 8 = a2, Bit 9 = b2, ..., Bit 63 = h8
White pawns starting position:
0x000000000000FF00 (bits 8-15 set)
Black pawns starting position:
0x00FF000000000000 (bits 48-55 set)
```
---
## Data Flow Diagrams
### Move Execution Flow
```
User Input
UI captures click/drag
GameController validates selection
MoveValidator checks legality
GameEngine executes move
BoardState updated
GameHistory records move
UI renders new state
Turn switches
```
### State Update Flow
```
Move → GameState (immutable) → New GameState
↓ ↓
└─────── History records both ──────┘
```
---
## Serialization Formats
### JSON Save Format
```json
{
"version": "1.0.0",
"timestamp": 1700000000000,
"gameState": {
"fen": "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
"moveHistory": [
{"from": "e2", "to": "e4", "notation": "e4"},
{"from": "e7", "to": "e5", "notation": "e5"}
],
"capturedPieces": {"white": [], "black": []},
"timeControl": {
"whiteTime": 600,
"blackTime": 595
}
},
"config": {
"mode": "pvp",
"theme": "classic"
}
}
```
### Local Storage Keys
```javascript
const StorageKeys = {
CURRENT_GAME: 'chess-current-game',
SAVED_GAMES: 'chess-saved-games',
SETTINGS: 'chess-settings',
THEME: 'chess-theme',
GAME_HISTORY: 'chess-game-history'
};
```
---
## Performance Considerations
### Memory Optimization
- **Board Representation**: Array[64] uses ~2KB per position
- **Move History**: Average game ~80 moves = ~40KB
- **Bitboards**: Enable compact representation (8 bytes per piece type)
### Caching Strategy
```javascript
class CacheManager {
moveValidationCache: Map<string, boolean>;
moveGenerationCache: Map<string, Move[]>;
evaluationCache: Map<string, number>;
maxSize: number = 10000;
set(key: string, value: any): void;
get(key: string): any | null;
clear(): void;
prune(): void; // Remove old entries
}
```
### Position Hashing
```javascript
// Zobrist hashing for position identification
class ZobristHash {
pieceKeys: BigInt[64][12]; // Square × PieceType
castlingKeys: BigInt[4];
enPassantKeys: BigInt[8];
sideToMoveKey: BigInt;
hash(gameState: GameState): BigInt;
updateHash(hash: BigInt, move: Move): BigInt;
}
```
This data model design ensures efficient state management, easy serialization, and optimal performance for both UI rendering and AI computation.