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>
This commit is contained in:
co-authored by
Claude
parent
1fd28d10b4
commit
5ad0700b41
@@ -0,0 +1,274 @@
|
||||
/**
|
||||
* @file Board.js
|
||||
* @description Represents the chess board and manages piece positions
|
||||
* @author Implementation Team
|
||||
*/
|
||||
|
||||
import { BOARD_SIZE, COLORS, INITIAL_POSITIONS } from '../utils/Constants.js';
|
||||
import { isValidPosition, algebraicToPosition } from '../utils/Helpers.js';
|
||||
import Pawn from './pieces/Pawn.js';
|
||||
import Rook from './pieces/Rook.js';
|
||||
import Knight from './pieces/Knight.js';
|
||||
import Bishop from './pieces/Bishop.js';
|
||||
import Queen from './pieces/Queen.js';
|
||||
import King from './pieces/King.js';
|
||||
|
||||
/**
|
||||
* @class Board
|
||||
* @description Manages the 8x8 chess board and piece positions
|
||||
*
|
||||
* @example
|
||||
* const board = new Board();
|
||||
* board.reset(); // Setup initial position
|
||||
* const piece = board.getPieceAt({row: 0, col: 0});
|
||||
*/
|
||||
class Board {
|
||||
constructor() {
|
||||
/**
|
||||
* @property {Array<Array<Piece|null>>} _squares - 2D array representing the board
|
||||
*/
|
||||
this._squares = this._createEmptyBoard();
|
||||
|
||||
/**
|
||||
* @property {Map<string, Piece>} _pieces - Map of all pieces (for quick lookup)
|
||||
* Key format: "color-type-index" (e.g., "white-pawn-0")
|
||||
*/
|
||||
this._pieces = new Map();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an empty 8x8 board
|
||||
*
|
||||
* @private
|
||||
* @returns {Array<Array<null>>} Empty board array
|
||||
*/
|
||||
_createEmptyBoard() {
|
||||
// TODO: Implement empty board creation
|
||||
// Create 8x8 array filled with null
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the piece at a specific position
|
||||
*
|
||||
* @param {Object} position - Position {row, col}
|
||||
* @returns {Piece|null} Piece at position or null if empty
|
||||
* @throws {Error} If position is invalid
|
||||
*
|
||||
* @example
|
||||
* const piece = board.getPieceAt({row: 0, col: 0});
|
||||
*/
|
||||
getPieceAt(position) {
|
||||
// TODO: Implement get piece
|
||||
// 1. Validate position
|
||||
// 2. Return piece at position or null
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a piece at a specific position
|
||||
*
|
||||
* @param {Object} position - Position {row, col}
|
||||
* @param {Piece|null} piece - Piece to place or null to clear
|
||||
* @throws {Error} If position is invalid
|
||||
*
|
||||
* @example
|
||||
* board.setPieceAt({row: 4, col: 4}, new Pawn('white', {row: 4, col: 4}));
|
||||
*/
|
||||
setPieceAt(position, piece) {
|
||||
// TODO: Implement set piece
|
||||
// 1. Validate position
|
||||
// 2. Update _squares array
|
||||
// 3. Update piece's position property
|
||||
// 4. Update _pieces map if needed
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a piece from a specific position
|
||||
*
|
||||
* @param {Object} position - Position {row, col}
|
||||
* @returns {Piece|null} Removed piece or null if position was empty
|
||||
*
|
||||
* @example
|
||||
* const captured = board.removePieceAt({row: 4, col: 4});
|
||||
*/
|
||||
removePieceAt(position) {
|
||||
// TODO: Implement remove piece
|
||||
// 1. Get piece at position
|
||||
// 2. Set position to null
|
||||
// 3. Update _pieces map
|
||||
// 4. Return removed piece
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves a piece from one position to another
|
||||
*
|
||||
* @param {Object} from - Starting position {row, col}
|
||||
* @param {Object} to - Target position {row, col}
|
||||
* @returns {Piece|null} Captured piece or null
|
||||
* @throws {Error} If no piece at 'from' position
|
||||
*
|
||||
* @example
|
||||
* const captured = board.movePiece({row: 6, col: 4}, {row: 4, col: 4});
|
||||
*/
|
||||
movePiece(from, to) {
|
||||
// TODO: Implement move piece
|
||||
// 1. Get piece at 'from'
|
||||
// 2. Throw error if no piece
|
||||
// 3. Get piece at 'to' (captured piece)
|
||||
// 4. Remove piece from 'from'
|
||||
// 5. Place piece at 'to'
|
||||
// 6. Update piece's position
|
||||
// 7. Return captured piece
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all pieces on the board
|
||||
*
|
||||
* @returns {Array<Piece>} Array of all pieces
|
||||
*
|
||||
* @example
|
||||
* const allPieces = board.getAllPieces();
|
||||
* console.log(allPieces.length); // Should be 32 at game start
|
||||
*/
|
||||
getAllPieces() {
|
||||
// TODO: Implement get all pieces
|
||||
// Iterate through _squares and collect all non-null pieces
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all pieces of a specific color
|
||||
*
|
||||
* @param {string} color - Color to filter by ('white' or 'black')
|
||||
* @returns {Array<Piece>} Array of pieces of the specified color
|
||||
*
|
||||
* @example
|
||||
* const whitePieces = board.getPiecesByColor('white');
|
||||
*/
|
||||
getPiecesByColor(color) {
|
||||
// TODO: Implement get pieces by color
|
||||
// Filter all pieces by color
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the king of a specific color
|
||||
*
|
||||
* @param {string} color - Color of the king ('white' or 'black')
|
||||
* @returns {Piece|null} King piece or null if not found
|
||||
*
|
||||
* @example
|
||||
* const whiteKing = board.getKing('white');
|
||||
*/
|
||||
getKing(color) {
|
||||
// TODO: Implement get king
|
||||
// Find piece with type 'king' and matching color
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a deep copy of the board
|
||||
*
|
||||
* @returns {Board} Cloned board
|
||||
*
|
||||
* @example
|
||||
* const boardCopy = board.clone();
|
||||
*/
|
||||
clone() {
|
||||
// TODO: Implement clone
|
||||
// 1. Create new Board instance
|
||||
// 2. Deep copy all pieces
|
||||
// 3. Maintain position references
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the board to initial chess position
|
||||
*
|
||||
* @example
|
||||
* board.reset();
|
||||
*/
|
||||
reset() {
|
||||
// TODO: Implement reset
|
||||
// 1. Clear the board
|
||||
// 2. Use INITIAL_POSITIONS to create pieces
|
||||
// 3. Place each piece on the board
|
||||
|
||||
// Helper: Create piece based on type
|
||||
const createPiece = (type, color, position) => {
|
||||
// TODO: Implement piece factory
|
||||
// Use switch/case or object map to create appropriate piece class
|
||||
return null;
|
||||
};
|
||||
|
||||
// TODO: Iterate through INITIAL_POSITIONS for both colors
|
||||
// Create and place each piece
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the entire board
|
||||
*
|
||||
* @example
|
||||
* board.clear();
|
||||
*/
|
||||
clear() {
|
||||
// TODO: Implement clear
|
||||
this._squares = this._createEmptyBoard();
|
||||
this._pieces.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a position is occupied
|
||||
*
|
||||
* @param {Object} position - Position {row, col}
|
||||
* @returns {boolean} True if position has a piece
|
||||
*
|
||||
* @example
|
||||
* if (board.isOccupied({row: 4, col: 4})) {
|
||||
* console.log('Square is occupied');
|
||||
* }
|
||||
*/
|
||||
isOccupied(position) {
|
||||
// TODO: Implement is occupied
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a position is occupied by an enemy piece
|
||||
*
|
||||
* @param {Object} position - Position {row, col}
|
||||
* @param {string} playerColor - Color of the current player
|
||||
* @returns {boolean} True if occupied by enemy piece
|
||||
*
|
||||
* @example
|
||||
* if (board.isOccupiedByEnemy({row: 4, col: 4}, 'white')) {
|
||||
* console.log('Can capture');
|
||||
* }
|
||||
*/
|
||||
isOccupiedByEnemy(position, playerColor) {
|
||||
// TODO: Implement is occupied by enemy
|
||||
// 1. Check if occupied
|
||||
// 2. Check if piece color is different from playerColor
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts board to string representation (for debugging)
|
||||
*
|
||||
* @returns {string} String representation of the board
|
||||
*
|
||||
* @example
|
||||
* console.log(board.toString());
|
||||
*/
|
||||
toString() {
|
||||
// TODO: Implement toString
|
||||
// Create ASCII representation of the board
|
||||
// Use piece symbols or letters
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
export default Board;
|
||||
@@ -0,0 +1,217 @@
|
||||
/**
|
||||
* @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;
|
||||
Reference in New Issue
Block a user