chess/planning/implementation/examples/knight-king-pattern.js
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

185 lines
4.5 KiB
JavaScript

/**
* @file knight-king-pattern.js
* @description Pattern for implementing non-sliding pieces (Knight, King)
* These pieces jump to specific positions
*/
import Piece from '../models/Piece.js';
import { DIRECTIONS } from '../utils/Constants.js';
import { isValidPosition } from '../utils/Helpers.js';
/**
* @class Knight
* @extends Piece
* @description Knight implementation using jump pattern
*
* Knight moves in L-shape: 2 squares in one direction, 1 square perpendicular
* Can jump over other pieces
*/
class Knight extends Piece {
constructor(color, position) {
super(color, position, 'knight');
}
/**
* Gets all valid moves for this knight
*
* @param {Board} board - Current board state
* @returns {Array<Object>} Array of valid positions
*/
getValidMoves(board) {
const moves = [];
const { row, col } = this.position;
// Knight has 8 possible L-shaped moves
const knightMoves = DIRECTIONS.KNIGHT;
// Check each possible move
for (const move of knightMoves) {
const newPos = {
row: row + move.row,
col: col + move.col
};
// Check if position is valid (on board)
if (!isValidPosition(newPos.row, newPos.col)) {
continue;
}
const piece = board.getPieceAt(newPos);
// Can move to empty square or capture enemy
if (!piece || piece.color !== this.color) {
moves.push(newPos);
}
}
return moves;
}
clone() {
const clone = new Knight(this.color, { ...this.position });
clone.hasMoved = this.hasMoved;
return clone;
}
}
/**
* @class King
* @extends Piece
* @description King implementation using adjacent square pattern
*
* King moves one square in any direction
* Special move: Castling (handled separately)
*/
class King extends Piece {
constructor(color, position) {
super(color, position, 'king');
}
/**
* Gets all valid moves for this king
*
* @param {Board} board - Current board state
* @returns {Array<Object>} Array of valid positions
*/
getValidMoves(board) {
const moves = [];
const { row, col } = this.position;
// King can move one square in 8 directions
const directions = [...DIRECTIONS.ORTHOGONAL, ...DIRECTIONS.DIAGONAL];
// Check each adjacent square
for (const direction of directions) {
const newPos = {
row: row + direction.row,
col: col + direction.col
};
// Check if position is valid
if (!isValidPosition(newPos.row, newPos.col)) {
continue;
}
const piece = board.getPieceAt(newPos);
// Can move to empty square or capture enemy
if (!piece || piece.color !== this.color) {
moves.push(newPos);
}
}
// TODO: Add castling moves
// Only if king hasn't moved
// Only if rook hasn't moved
// Only if squares between are empty
// Only if king is not in check
// Only if king doesn't pass through check
// See castling example in special-moves.js
return moves;
}
/**
* Checks if king can castle kingside
*
* @param {Board} board - Current board state
* @returns {boolean} True if kingside castling is legal
*/
canCastleKingside(board) {
// TODO: Implement castling validation
// This is complex and often handled in RuleEngine
return false;
}
/**
* Checks if king can castle queenside
*
* @param {Board} board - Current board state
* @returns {boolean} True if queenside castling is legal
*/
canCastleQueenside(board) {
// TODO: Implement castling validation
return false;
}
clone() {
const clone = new King(this.color, { ...this.position });
clone.hasMoved = this.hasMoved;
return clone;
}
}
/**
* PATTERN SUMMARY - NON-SLIDING PIECES:
*
* Unlike sliding pieces, these pieces:
* 1. Have a fixed set of possible moves (no sliding)
* 2. Can't be blocked (Knight) or move only 1 square (King)
* 3. Check each possible position directly
*
* Algorithm:
* 1. Get all possible move offsets
* 2. For each offset:
* a. Calculate new position
* b. Validate position is on board
* c. Check if square is empty or has enemy
* d. Add to moves if valid
*
* DIFFERENCE FROM SLIDING:
* - Sliding: Loop until blocked
* - Non-sliding: Check each position once
*
* KNIGHT SPECIAL:
* - Only piece that can jump over others
* - Don't need to check path, only destination
*
* KING SPECIAL:
* - Must not move into check (validated elsewhere)
* - Castling is complex special move
* - Usually limited to 8 moves, but critical to protect
*/
export { Knight, King };