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

218 lines
5.0 KiB
JavaScript

/**
* @file Piece.js
* @description Base class for all chess pieces
* @author Implementation Team
*/
import { PIECE_TYPES } from '../utils/Constants.js';
/**
* @class Piece
* @description Abstract base class for chess pieces
* All specific piece classes (Pawn, Rook, etc.) inherit from this
*
* @example
* // Don't instantiate directly, use subclasses
* const pawn = new Pawn('white', {row: 6, col: 4});
*/
class Piece {
/**
* @param {string} color - Piece color ('white' or 'black')
* @param {Object} position - Initial position {row, col}
* @param {string} type - Piece type (from PIECE_TYPES)
*/
constructor(color, position, type) {
/**
* @property {string} color - Piece color
*/
this.color = color;
/**
* @property {Object} position - Current position {row, col}
*/
this.position = position;
/**
* @property {string} type - Piece type
*/
this.type = type;
/**
* @property {boolean} hasMoved - Whether piece has moved (for castling, pawn two-square)
*/
this.hasMoved = false;
/**
* @property {string} id - Unique identifier for the piece
*/
this.id = `${color}-${type}-${Date.now()}`;
}
/**
* Moves the piece to a new position
*
* @param {Object} newPosition - Target position {row, col}
*
* @example
* piece.move({row: 4, col: 4});
*/
move(newPosition) {
// TODO: Implement move
// 1. Update position
// 2. Set hasMoved to true
}
/**
* Gets all valid moves for this piece
* Must be implemented by subclasses
*
* @abstract
* @param {Board} board - Current board state
* @returns {Array<Object>} Array of valid positions {row, col}
*
* @example
* const validMoves = piece.getValidMoves(board);
*/
getValidMoves(board) {
// TODO: Override in subclasses
throw new Error('getValidMoves must be implemented by subclass');
}
/**
* Checks if this piece can move to a specific position
*
* @param {Object} position - Target position {row, col}
* @param {Board} board - Current board state
* @returns {boolean} True if move is valid
*
* @example
* if (piece.canMoveTo({row: 4, col: 4}, board)) {
* // Move is valid
* }
*/
canMoveTo(position, board) {
// TODO: Implement can move to
// Get valid moves and check if position is in the list
return false;
}
/**
* Creates a copy of this piece
*
* @returns {Piece} Cloned piece
*
* @example
* const pieceCopy = piece.clone();
*/
clone() {
// TODO: Implement clone
// Create new instance of same class with same properties
// Note: This is tricky because we need to know the actual subclass
return null;
}
/**
* Gets the piece's symbol for display
*
* @returns {string} Unicode symbol for the piece
*
* @example
* console.log(piece.getSymbol()); // → '♙'
*/
getSymbol() {
// TODO: Implement get symbol
// Use PIECE_SYMBOLS from Constants
return '';
}
/**
* Gets the piece's value for AI evaluation
*
* @returns {number} Piece value
*
* @example
* const value = piece.getValue(); // → 3 for knight
*/
getValue() {
// TODO: Implement get value
// Use PIECE_VALUES from Constants
return 0;
}
/**
* Checks if this piece is white
*
* @returns {boolean} True if piece is white
*/
get isWhite() {
// TODO: Implement is white
return false;
}
/**
* Checks if this piece is black
*
* @returns {boolean} True if piece is black
*/
get isBlack() {
// TODO: Implement is black
return false;
}
/**
* Gets a string representation of the piece
*
* @returns {string} String representation
*
* @example
* console.log(piece.toString()); // → "White Pawn at e2"
*/
toString() {
// TODO: Implement toString
// Format: "[Color] [Type] at [algebraic notation]"
return '';
}
/**
* Helper method to check if a position is occupied by an enemy
*
* @protected
* @param {Object} position - Position to check {row, col}
* @param {Board} board - Current board state
* @returns {boolean} True if position has enemy piece
*/
_isEnemyAt(position, board) {
// TODO: Implement enemy check
// Get piece at position and compare colors
return false;
}
/**
* Helper method to check if a position is occupied by friendly piece
*
* @protected
* @param {Object} position - Position to check {row, col}
* @param {Board} board - Current board state
* @returns {boolean} True if position has friendly piece
*/
_isFriendlyAt(position, board) {
// TODO: Implement friendly check
return false;
}
/**
* Helper method to check if a position is empty
*
* @protected
* @param {Object} position - Position to check {row, col}
* @param {Board} board - Current board state
* @returns {boolean} True if position is empty
*/
_isEmptyAt(position, board) {
// TODO: Implement empty check
return false;
}
}
export default Piece;