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>
14 KiB
14 KiB
API Interfaces and Component Contracts
Public API Interfaces
1. IChessBoard Interface
interface IChessBoard {
// Properties
readonly squares: Square[];
readonly activePiece: ChessPiece | null;
// Square operations
getSquare(file: number, rank: number): Square;
getSquareByNotation(notation: string): Square;
setPiece(square: Square, piece: ChessPiece): void;
removePiece(square: Square): ChessPiece | null;
getPiece(square: Square): ChessPiece | null;
// Board queries
isSquareOccupied(square: Square): boolean;
isSquareEmpty(square: Square): boolean;
getSquareColor(square: Square): 'light' | 'dark';
findKing(color: 'white' | 'black'): Square | null;
getAllPieces(color?: 'white' | 'black'): ChessPiece[];
// Visual operations
highlightSquares(squares: Square[]): void;
clearHighlights(): void;
// State management
clone(): IChessBoard;
reset(): void;
toFEN(): string;
fromFEN(fen: string): void;
}
2. IChessPiece Interface
interface IChessPiece {
// Properties
readonly type: PieceType;
readonly color: 'white' | 'black';
position: Square | null;
hasMoved: boolean;
// Move generation
getPossibleMoves(board: IChessBoard): Square[];
getLegalMoves(board: IChessBoard, gameState: IGameState): Square[];
canMoveTo(square: Square, board: IChessBoard): boolean;
getAttackingSquares(board: IChessBoard): Square[];
// Piece information
getValue(): number;
getNotation(): string;
getImagePath(theme?: string): string;
// Utilities
clone(): IChessPiece;
equals(other: IChessPiece): boolean;
}
3. IGameEngine Interface
interface IGameEngine {
// Properties
readonly gameState: IGameState;
readonly currentPlayer: 'white' | 'black';
readonly moveHistory: IMove[];
readonly status: GameStatus;
// Game lifecycle
initializeGame(config?: GameConfig): void;
reset(): void;
// Move execution
executeMove(from: Square, to: Square, promotion?: PieceType): IMove | null;
undoMove(): IMove | null;
redoMove(): IMove | null;
// Game state queries
isCheck(color: 'white' | 'black'): boolean;
isCheckmate(color: 'white' | 'black'): boolean;
isStalemate(): boolean;
isDraw(): boolean;
isGameOver(): boolean;
getWinner(): 'white' | 'black' | 'draw' | null;
// Turn management
switchTurn(): void;
getCurrentPlayer(): 'white' | 'black';
// State management
getGameState(): IGameState;
loadGameState(state: IGameState): void;
saveGame(): string;
loadGame(saveData: string): void;
// Events
on(event: string, handler: Function): void;
off(event: string, handler: Function): void;
emit(event: string, data?: any): void;
}
4. IMoveValidator Interface
interface IMoveValidator {
// Primary validation
isMoveLegal(from: Square, to: Square, gameState: IGameState): boolean;
validateMove(move: IMove, gameState: IGameState): ValidationResult;
// Specific validations
isPseudoLegal(from: Square, to: Square, board: IChessBoard): boolean;
wouldExposeKing(move: IMove, gameState: IGameState): boolean;
validateCastling(king: Square, rook: Square, gameState: IGameState): boolean;
validateEnPassant(from: Square, to: Square, gameState: IGameState): boolean;
validatePromotion(move: IMove): boolean;
// Threat detection
isSquareAttacked(square: Square, byColor: 'white' | 'black', gameState: IGameState): boolean;
getAttackingPieces(square: Square, byColor: 'white' | 'black', gameState: IGameState): IChessPiece[];
isKingInCheck(color: 'white' | 'black', gameState: IGameState): boolean;
// Cache management
clearCache(): void;
}
interface ValidationResult {
valid: boolean;
reason?: string;
code?: string;
}
5. IGameController Interface
interface IGameController {
// Initialization
initialize(config: GameConfig): void;
startNewGame(config?: GameConfig): void;
// User interaction
handleSquareClick(square: Square): void;
handlePieceDrag(piece: IChessPiece, fromSquare: Square): void;
handlePieceDrop(toSquare: Square): void;
selectSquare(square: Square): void;
deselectSquare(): void;
// Game actions
makeMove(from: Square, to: Square, promotion?: PieceType): boolean;
offerDraw(): void;
acceptDraw(): void;
resign(color: 'white' | 'black'): void;
requestUndo(): void;
// Game management
pauseGame(): void;
resumeGame(): void;
saveGame(): string;
loadGame(saveData: string): void;
exportPGN(): string;
// Configuration
setGameMode(mode: 'pvp' | 'pva' | 'ava'): void;
setAIDifficulty(level: number): void;
updateSettings(settings: Partial<GameConfig>): void;
// Queries
getGameState(): IGameState;
getCurrentPlayer(): 'white' | 'black';
getGameStatus(): GameStatus;
getLegalMovesFor(square: Square): Square[];
}
6. IMoveGenerator Interface
interface IMoveGenerator {
// Move generation
generateAllMoves(gameState: IGameState, color: 'white' | 'black'): IMove[];
generatePieceMoves(piece: IChessPiece, gameState: IGameState): IMove[];
generateCaptures(gameState: IGameState, color: 'white' | 'black'): IMove[];
generateQuietMoves(gameState: IGameState, color: 'white' | 'black'): IMove[];
// Special moves
generateCastlingMoves(color: 'white' | 'black', gameState: IGameState): IMove[];
generateEnPassantMoves(color: 'white' | 'black', gameState: IGameState): IMove[];
generatePromotionMoves(pawn: IChessPiece, gameState: IGameState): IMove[];
// Move ordering
orderMoves(moves: IMove[], gameState: IGameState): IMove[];
// Performance testing
perft(depth: number, gameState: IGameState): number;
// Cache
clearCache(): void;
}
7. IGameHistory Interface
interface IGameHistory {
// Properties
readonly moves: IMove[];
readonly currentIndex: number;
readonly canUndo: boolean;
readonly canRedo: boolean;
// History operations
addMove(move: IMove, position: string): void;
getMove(index: number): IMove | null;
getAllMoves(): IMove[];
clear(): void;
// Navigation
undo(): IMove | null;
redo(): IMove | null;
goToMove(index: number): IMove | null;
// Queries
getMoveCount(): number;
getLastMove(): IMove | null;
isThreefoldRepetition(): boolean;
getFiftyMoveCount(): number;
// Export
toPGN(metadata?: PGNMetadata): string;
toJSON(): string;
exportMoves(): string[];
// Import
fromPGN(pgn: string): void;
fromJSON(json: string): void;
importMoves(moves: string[]): void;
}
8. IUIController Interface
interface IUIController {
// Rendering
renderBoard(board: IChessBoard): void;
renderPiece(piece: IChessPiece, square: Square): void;
renderGameStatus(status: GameStatus): void;
updateCapturedPieces(pieces: { white: PieceType[], black: PieceType[] }): void;
// Animations
animateMove(from: Square, to: Square, duration?: number): Promise<void>;
animateCapture(square: Square): Promise<void>;
animatePromotion(square: Square, newPiece: PieceType): Promise<void>;
// Visual feedback
highlightSquare(square: Square, type: HighlightType): void;
clearHighlights(): void;
showLegalMoves(moves: Square[]): void;
hideLegalMoves(): void;
showCheck(color: 'white' | 'black'): void;
// Dialogs
showPromotionDialog(color: 'white' | 'black'): Promise<PieceType>;
showGameOverDialog(result: GameResult): void;
showSettingsDialog(): void;
// Interactions
enableDragAndDrop(): void;
disableDragAndDrop(): void;
enableClickToMove(): void;
disableClickToMove(): void;
// Sound
playSound(soundType: SoundType): void;
// Theme
setTheme(theme: string): void;
}
enum HighlightType {
SELECTED = 'selected',
LEGAL_MOVE = 'legal-move',
LAST_MOVE = 'last-move',
CHECK = 'check',
ATTACKED = 'attacked'
}
enum SoundType {
MOVE = 'move',
CAPTURE = 'capture',
CASTLE = 'castle',
CHECK = 'check',
CHECKMATE = 'checkmate',
DRAW = 'draw',
ILLEGAL = 'illegal'
}
9. IAIPlayer Interface
interface IAIPlayer {
// Configuration
setDifficulty(level: number): void;
setThinkingTime(ms: number): void;
setSearchDepth(depth: number): void;
// Move calculation
calculateMove(gameState: IGameState): Promise<IMove>;
evaluatePosition(gameState: IGameState): number;
// Search
search(gameState: IGameState, depth: number): SearchResult;
minimax(depth: number, alpha: number, beta: number, gameState: IGameState): number;
// Opening book
hasOpeningMove(gameState: IGameState): boolean;
getOpeningMove(gameState: IGameState): IMove | null;
// Status
isThinking(): boolean;
cancelCalculation(): void;
// Events
on(event: 'move-ready' | 'thinking' | 'evaluation-update', handler: Function): void;
off(event: string, handler: Function): void;
}
interface SearchResult {
bestMove: IMove;
score: number;
depth: number;
nodesSearched: number;
timeElapsed: number;
principalVariation: IMove[];
}
10. IThemeManager Interface
interface IThemeManager {
// Theme management
setTheme(themeName: string): void;
getTheme(): Theme;
getAvailableThemes(): string[];
// Custom themes
registerTheme(theme: Theme): void;
unregisterTheme(themeName: string): void;
// Import/Export
loadTheme(themeData: string): void;
exportTheme(themeName: string): string;
// Apply styles
applyColors(): void;
applyPieceSet(): void;
}
interface Theme {
name: string;
lightSquares: string;
darkSquares: string;
highlightColor: string;
legalMoveColor: string;
selectedColor: string;
checkColor: string;
pieceSet: string;
borderStyle?: string;
coordinatesColor?: string;
}
Event System API
Event Emitter Base
interface IEventEmitter {
on(event: string, handler: Function): void;
off(event: string, handler: Function): void;
once(event: string, handler: Function): void;
emit(event: string, data?: any): void;
removeAllListeners(event?: string): void;
}
Game Events
// Event payloads
interface MoveExecutedEvent {
move: IMove;
gameState: IGameState;
isCheck: boolean;
isCheckmate: boolean;
}
interface PieceSelectedEvent {
piece: IChessPiece;
square: Square;
legalMoves: Square[];
}
interface GameOverEvent {
status: GameStatus;
winner: 'white' | 'black' | 'draw' | null;
reason: string;
}
interface TurnChangedEvent {
player: 'white' | 'black';
moveNumber: number;
}
interface CheckDetectedEvent {
color: 'white' | 'black';
attackingPieces: IChessPiece[];
}
Factory Interfaces
Piece Factory
interface IPieceFactory {
createPiece(type: PieceType, color: 'white' | 'black', position?: Square): IChessPiece;
createPawn(color: 'white' | 'black', position?: Square): IChessPiece;
createKnight(color: 'white' | 'black', position?: Square): IChessPiece;
createBishop(color: 'white' | 'black', position?: Square): IChessPiece;
createRook(color: 'white' | 'black', position?: Square): IChessPiece;
createQueen(color: 'white' | 'black', position?: Square): IChessPiece;
createKing(color: 'white' | 'black', position?: Square): IChessPiece;
}
Game Factory
interface IGameFactory {
createGame(config?: GameConfig): IGameEngine;
createGameFromFEN(fen: string, config?: GameConfig): IGameEngine;
createGameFromPGN(pgn: string, config?: GameConfig): IGameEngine;
}
Utility Interfaces
Notation Converter
interface INotationConverter {
moveToSAN(move: IMove, gameState: IGameState): string;
moveToLAN(move: IMove): string;
moveToUCI(move: IMove): string;
sanToMove(san: string, gameState: IGameState): IMove | null;
uciToMove(uci: string, gameState: IGameState): IMove | null;
}
FEN Parser
interface IFENParser {
parse(fen: string): IGameState;
generate(gameState: IGameState): string;
validate(fen: string): boolean;
}
PGN Parser
interface IPGNParser {
parse(pgn: string): PGNGame;
generate(game: IGameEngine): string;
validate(pgn: string): boolean;
}
interface PGNGame {
metadata: PGNMetadata;
moves: string[];
result: string;
}
interface PGNMetadata {
event?: string;
site?: string;
date?: string;
round?: string;
white?: string;
black?: string;
result?: string;
[key: string]: string | undefined;
}
Plugin Interface
interface IChessPlugin {
name: string;
version: string;
// Lifecycle hooks
initialize(game: IGameEngine): void;
destroy(): void;
// Optional hooks
onMoveExecuted?(move: IMove, gameState: IGameState): void;
onGameStart?(config: GameConfig): void;
onGameEnd?(result: GameResult): void;
onTurnChange?(player: 'white' | 'black'): void;
// Custom functionality
getAPI?(): any;
}
Service Interfaces
Storage Service
interface IStorageService {
saveGame(key: string, game: IGameEngine): void;
loadGame(key: string): IGameEngine | null;
deleteGame(key: string): void;
listSavedGames(): string[];
saveSetting(key: string, value: any): void;
loadSetting(key: string): any;
clearAll(): void;
}
Network Service (Future)
interface INetworkService {
connect(gameId: string): Promise<void>;
disconnect(): void;
sendMove(move: IMove): void;
onMoveReceived(handler: (move: IMove) => void): void;
syncGameState(gameState: IGameState): void;
requestSync(): void;
chat(message: string): void;
onChatMessage(handler: (message: ChatMessage) => void): void;
}
Usage Example
// Initialize game
const gameFactory = new GameFactory();
const game = gameFactory.createGame({
mode: 'pvp',
theme: 'classic',
soundEnabled: true
});
// Set up UI
const uiController = new UIController('#board-container');
uiController.renderBoard(game.getBoard());
// Handle moves
game.on('move-executed', (event: MoveExecutedEvent) => {
uiController.animateMove(event.move.from, event.move.to);
uiController.renderGameStatus(event.gameState.status);
});
// User interaction
uiController.on('square-clicked', (square: Square) => {
const legalMoves = game.getLegalMovesFor(square);
uiController.showLegalMoves(legalMoves);
});
// Execute move
game.executeMove(fromSquare, toSquare);
This API design ensures loose coupling, clear contracts, and easy testing while providing flexibility for future extensions.