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

226 lines
6.1 KiB
JavaScript

/**
* @file Helpers.js
* @description Utility functions for the chess game
* @author Implementation Team
*/
import { BOARD_BOUNDS, FILES, RANKS } from './Constants.js';
/**
* Checks if a position is within the board boundaries
*
* @param {number} row - Row index (0-7)
* @param {number} col - Column index (0-7)
* @returns {boolean} True if position is valid
*
* @example
* isValidPosition(3, 4) // → true
* isValidPosition(8, 0) // → false
*/
export function isValidPosition(row, col) {
// TODO: Implement validation
// Check if row and col are within BOARD_BOUNDS
return false; // Replace with actual logic
}
/**
* Checks if an object is a valid position object
*
* @param {Object} position - Position object to validate
* @returns {boolean} True if position object is valid
*
* @example
* isValidPositionObject({row: 3, col: 4}) // → true
* isValidPositionObject({x: 3, y: 4}) // → false
*/
export function isValidPositionObject(position) {
// TODO: Implement validation
// Check if position has row and col properties
// Check if both are valid
return false; // Replace with actual logic
}
/**
* Compares two positions for equality
*
* @param {Object} pos1 - First position {row, col}
* @param {Object} pos2 - Second position {row, col}
* @returns {boolean} True if positions are equal
*
* @example
* positionsEqual({row: 3, col: 4}, {row: 3, col: 4}) // → true
*/
export function positionsEqual(pos1, pos2) {
// TODO: Implement comparison
return false; // Replace with actual logic
}
/**
* Converts algebraic notation to position coordinates
*
* @param {string} algebraic - Algebraic notation (e.g., 'e4')
* @returns {Object|null} Position {row, col} or null if invalid
*
* @example
* algebraicToPosition('e4') // → {row: 4, col: 4}
* algebraicToPosition('a1') // → {row: 7, col: 0}
*/
export function algebraicToPosition(algebraic) {
// TODO: Implement conversion
// Parse file (letter) and rank (number)
// Use FILES and RANKS mappings
// Validate input
return null; // Replace with actual logic
}
/**
* Converts position coordinates to algebraic notation
*
* @param {Object} position - Position {row, col}
* @returns {string|null} Algebraic notation or null if invalid
*
* @example
* positionToAlgebraic({row: 4, col: 4}) // → 'e4'
* positionToAlgebraic({row: 7, col: 0}) // → 'a1'
*/
export function positionToAlgebraic(position) {
// TODO: Implement conversion
// Convert col to file letter (a-h)
// Convert row to rank number (1-8)
return null; // Replace with actual logic
}
/**
* Creates a deep clone of an object
*
* @param {*} obj - Object to clone
* @returns {*} Deep copy of the object
*
* @example
* const copy = deepClone({a: {b: 1}});
*/
export function deepClone(obj) {
// TODO: Implement deep cloning
// Handle arrays, objects, and primitives
// Consider using JSON.parse(JSON.stringify()) or custom logic
return null; // Replace with actual logic
}
/**
* Calculates the distance between two positions
*
* @param {Object} pos1 - First position {row, col}
* @param {Object} pos2 - Second position {row, col}
* @returns {Object} Distance {rows: number, cols: number}
*
* @example
* getDistance({row: 0, col: 0}, {row: 3, col: 4})
* // → {rows: 3, cols: 4}
*/
export function getDistance(pos1, pos2) {
// TODO: Implement distance calculation
return { rows: 0, cols: 0 }; // Replace with actual logic
}
/**
* Gets all positions in a line between two positions
* Does not include the start and end positions
*
* @param {Object} from - Starting position {row, col}
* @param {Object} to - Ending position {row, col}
* @returns {Array<Object>} Array of positions between from and to
*
* @example
* getPositionsBetween({row: 0, col: 0}, {row: 3, col: 0})
* // → [{row: 1, col: 0}, {row: 2, col: 0}]
*/
export function getPositionsBetween(from, to) {
// TODO: Implement path calculation
// Only works for straight lines (orthogonal or diagonal)
// Returns empty array if not a straight line
return []; // Replace with actual logic
}
/**
* Checks if a path between two positions is clear (no pieces blocking)
*
* @param {Object} from - Starting position {row, col}
* @param {Object} to - Ending position {row, col}
* @param {Board} board - Board instance
* @returns {boolean} True if path is clear
*
* @example
* isPathClear({row: 0, col: 0}, {row: 3, col: 0}, board)
*/
export function isPathClear(from, to, board) {
// TODO: Implement path checking
// Get positions between from and to
// Check if any position has a piece
return false; // Replace with actual logic
}
/**
* Gets the opposite color
*
* @param {string} color - Current color ('white' or 'black')
* @returns {string} Opposite color
*
* @example
* getOppositeColor('white') // → 'black'
*/
export function getOppositeColor(color) {
// TODO: Implement color toggle
return null; // Replace with actual logic
}
/**
* Formats a move for display
*
* @param {Object} move - Move object {piece, from, to, captured}
* @returns {string} Formatted move string
*
* @example
* formatMove({piece: pawn, from: {row: 6, col: 4}, to: {row: 4, col: 4}})
* // → "e2-e4"
*/
export function formatMove(move) {
// TODO: Implement move formatting
// Use algebraic notation
// Include piece type, capture notation, etc.
return ''; // Replace with actual logic
}
/**
* Generates a unique ID
*
* @returns {string} Unique identifier
*
* @example
* const id = generateId(); // → "1234567890-abcdef"
*/
export function generateId() {
// TODO: Implement ID generation
// Use timestamp + random string
return ''; // Replace with actual logic
}
/**
* Debounces a function call
*
* @param {Function} func - Function to debounce
* @param {number} wait - Wait time in milliseconds
* @returns {Function} Debounced function
*
* @example
* const debouncedSave = debounce(saveGame, 500);
*/
export function debounce(func, wait) {
// TODO: Implement debounce
let timeout;
return function executedFunction(...args) {
// Clear existing timeout
// Set new timeout
// Execute function after wait time
};
}