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>
437 lines
8.3 KiB
Markdown
437 lines
8.3 KiB
Markdown
# Coding Standards - Chess Game
|
|
|
|
## JavaScript Standards (ES6+)
|
|
|
|
### 1. Module Structure
|
|
|
|
```javascript
|
|
/**
|
|
* @file ClassName.js
|
|
* @description Brief description of the file's purpose
|
|
* @author Implementation Team
|
|
*/
|
|
|
|
// Imports
|
|
import Dependency from './Dependency.js';
|
|
import { CONSTANT } from './Constants.js';
|
|
|
|
// Constants (file-level)
|
|
const PRIVATE_CONSTANT = 'value';
|
|
|
|
/**
|
|
* @class ClassName
|
|
* @description Detailed class description
|
|
*/
|
|
class ClassName {
|
|
// Class implementation
|
|
}
|
|
|
|
// Export
|
|
export default ClassName;
|
|
```
|
|
|
|
### 2. Class Structure
|
|
|
|
```javascript
|
|
class ChessPiece {
|
|
// Static properties
|
|
static TYPE = 'piece';
|
|
|
|
// Instance properties (declare in constructor)
|
|
constructor(color, position) {
|
|
this.color = color;
|
|
this.position = position;
|
|
this.hasMoved = false;
|
|
this._privateProperty = null;
|
|
}
|
|
|
|
// Public methods
|
|
move(newPosition) {
|
|
// Implementation
|
|
}
|
|
|
|
// Private methods (prefix with _)
|
|
_calculateMoves() {
|
|
// Implementation
|
|
}
|
|
|
|
// Getters/Setters
|
|
get isWhite() {
|
|
return this.color === 'white';
|
|
}
|
|
}
|
|
```
|
|
|
|
### 3. Naming Conventions
|
|
|
|
#### Variables and Functions
|
|
```javascript
|
|
// camelCase for variables and functions
|
|
let playerTurn = 'white';
|
|
const selectedPiece = null;
|
|
|
|
function calculateValidMoves(piece) {
|
|
// Implementation
|
|
}
|
|
```
|
|
|
|
#### Classes and Constructors
|
|
```javascript
|
|
// PascalCase for classes
|
|
class GameController { }
|
|
class MoveValidator { }
|
|
```
|
|
|
|
#### Constants
|
|
```javascript
|
|
// UPPER_SNAKE_CASE for constants
|
|
const BOARD_SIZE = 8;
|
|
const PIECE_TYPES = {
|
|
PAWN: 'pawn',
|
|
ROOK: 'rook',
|
|
KNIGHT: 'knight'
|
|
};
|
|
```
|
|
|
|
#### Private Members
|
|
```javascript
|
|
class Board {
|
|
constructor() {
|
|
this._squares = []; // Private property
|
|
}
|
|
|
|
_initializeBoard() { // Private method
|
|
// Implementation
|
|
}
|
|
}
|
|
```
|
|
|
|
### 4. Documentation (JSDoc)
|
|
|
|
#### Class Documentation
|
|
```javascript
|
|
/**
|
|
* @class GameController
|
|
* @description Manages the overall game flow and coordinates between components
|
|
*
|
|
* @example
|
|
* const controller = new GameController();
|
|
* controller.startNewGame();
|
|
*/
|
|
class GameController {
|
|
// Implementation
|
|
}
|
|
```
|
|
|
|
#### Method Documentation
|
|
```javascript
|
|
/**
|
|
* Validates whether a move is legal according to chess rules
|
|
*
|
|
* @param {Piece} piece - The piece to move
|
|
* @param {Position} from - Starting position {row, col}
|
|
* @param {Position} to - Target position {row, col}
|
|
* @returns {boolean} True if the move is legal
|
|
* @throws {Error} If piece is null or positions are invalid
|
|
*
|
|
* @example
|
|
* const isValid = validator.isValidMove(pawn, {row: 1, col: 0}, {row: 2, col: 0});
|
|
*/
|
|
isValidMove(piece, from, to) {
|
|
// Implementation
|
|
}
|
|
```
|
|
|
|
#### Property Documentation
|
|
```javascript
|
|
class GameState {
|
|
/**
|
|
* @property {string} currentPlayer - Current player's color ('white' or 'black')
|
|
*/
|
|
currentPlayer = 'white';
|
|
|
|
/**
|
|
* @property {Array<Piece>} capturedPieces - Array of captured pieces
|
|
*/
|
|
capturedPieces = [];
|
|
}
|
|
```
|
|
|
|
### 5. Error Handling
|
|
|
|
```javascript
|
|
// Use descriptive error messages
|
|
function movePiece(piece, position) {
|
|
if (!piece) {
|
|
throw new Error('movePiece: piece cannot be null');
|
|
}
|
|
|
|
if (!this._isValidPosition(position)) {
|
|
throw new Error(`movePiece: invalid position (${position.row}, ${position.col})`);
|
|
}
|
|
|
|
try {
|
|
// Risky operation
|
|
this._executMove(piece, position);
|
|
} catch (error) {
|
|
console.error('Failed to execute move:', error);
|
|
throw new Error(`Move execution failed: ${error.message}`);
|
|
}
|
|
}
|
|
```
|
|
|
|
### 6. Code Organization
|
|
|
|
#### Method Order
|
|
```javascript
|
|
class Example {
|
|
// 1. Constructor
|
|
constructor() { }
|
|
|
|
// 2. Static methods
|
|
static createDefault() { }
|
|
|
|
// 3. Public methods (alphabetical)
|
|
executeMove() { }
|
|
getValidMoves() { }
|
|
reset() { }
|
|
|
|
// 4. Private methods (alphabetical)
|
|
_calculateScore() { }
|
|
_validateInput() { }
|
|
|
|
// 5. Getters/Setters
|
|
get score() { }
|
|
set score(value) { }
|
|
}
|
|
```
|
|
|
|
#### File Length
|
|
- **Target**: 150-300 lines per file
|
|
- **Maximum**: 500 lines
|
|
- **If exceeding**: Split into smaller modules
|
|
|
|
### 7. Best Practices
|
|
|
|
#### Use Const/Let (Never Var)
|
|
```javascript
|
|
// Good
|
|
const BOARD_SIZE = 8;
|
|
let currentPlayer = 'white';
|
|
|
|
// Bad
|
|
var boardSize = 8;
|
|
```
|
|
|
|
#### Arrow Functions for Callbacks
|
|
```javascript
|
|
// Good
|
|
squares.forEach(square => {
|
|
square.addEventListener('click', this._handleClick.bind(this));
|
|
});
|
|
|
|
// Also good for simple returns
|
|
const getColor = piece => piece.color;
|
|
```
|
|
|
|
#### Destructuring
|
|
```javascript
|
|
// Good
|
|
const { row, col } = position;
|
|
const [first, second, ...rest] = moves;
|
|
|
|
// Object shorthand
|
|
const piece = { color, position, type };
|
|
```
|
|
|
|
#### Template Literals
|
|
```javascript
|
|
// Good
|
|
const message = `Move ${piece.type} from ${from} to ${to}`;
|
|
|
|
// Bad
|
|
const message = 'Move ' + piece.type + ' from ' + from + ' to ' + to;
|
|
```
|
|
|
|
#### Default Parameters
|
|
```javascript
|
|
function createPiece(type, color = 'white', position = {row: 0, col: 0}) {
|
|
// Implementation
|
|
}
|
|
```
|
|
|
|
#### Array Methods Over Loops
|
|
```javascript
|
|
// Good
|
|
const whitePieces = pieces.filter(p => p.color === 'white');
|
|
const positions = pieces.map(p => p.position);
|
|
const hasPawn = pieces.some(p => p.type === 'pawn');
|
|
|
|
// Avoid when possible
|
|
let whitePieces = [];
|
|
for (let i = 0; i < pieces.length; i++) {
|
|
if (pieces[i].color === 'white') {
|
|
whitePieces.push(pieces[i]);
|
|
}
|
|
}
|
|
```
|
|
|
|
### 8. Comments
|
|
|
|
#### When to Comment
|
|
```javascript
|
|
// Comment complex algorithms
|
|
// Minimax algorithm with alpha-beta pruning
|
|
function evaluatePosition(depth, alpha, beta) {
|
|
// Implementation
|
|
}
|
|
|
|
// Comment non-obvious business logic
|
|
// En passant is only valid immediately after opponent's two-square pawn move
|
|
if (this._isEnPassantValid(move)) {
|
|
// Implementation
|
|
}
|
|
|
|
// Comment TODO items
|
|
// TODO: Implement pawn promotion UI
|
|
// TODO: Add sound effects
|
|
```
|
|
|
|
#### When NOT to Comment
|
|
```javascript
|
|
// Bad - obvious comment
|
|
let currentPlayer = 'white'; // Set current player to white
|
|
|
|
// Good - self-documenting code
|
|
let currentPlayer = 'white';
|
|
```
|
|
|
|
### 9. Magic Numbers
|
|
|
|
```javascript
|
|
// Bad
|
|
if (piece.position.row === 7) { }
|
|
|
|
// Good
|
|
const LAST_ROW = 7;
|
|
if (piece.position.row === LAST_ROW) { }
|
|
|
|
// Better - in Constants.js
|
|
import { BOARD_BOUNDS } from './Constants.js';
|
|
if (piece.position.row === BOARD_BOUNDS.MAX_ROW) { }
|
|
```
|
|
|
|
### 10. Testing Requirements
|
|
|
|
```javascript
|
|
/**
|
|
* Every public method should have:
|
|
* - Happy path test
|
|
* - Edge case tests
|
|
* - Error case tests
|
|
*/
|
|
|
|
// Example test structure
|
|
describe('MoveValidator', () => {
|
|
describe('isValidMove', () => {
|
|
it('should allow valid pawn moves', () => {
|
|
// Test implementation
|
|
});
|
|
|
|
it('should reject moves off the board', () => {
|
|
// Test implementation
|
|
});
|
|
|
|
it('should throw error for null piece', () => {
|
|
// Test implementation
|
|
});
|
|
});
|
|
});
|
|
```
|
|
|
|
## CSS Standards
|
|
|
|
### 1. Organization
|
|
```css
|
|
/* Use BEM naming convention */
|
|
.board { }
|
|
.board__square { }
|
|
.board__square--light { }
|
|
.board__square--dark { }
|
|
.board__square--selected { }
|
|
|
|
/* Group related styles */
|
|
/* === LAYOUT === */
|
|
/* === TYPOGRAPHY === */
|
|
/* === COLORS === */
|
|
/* === ANIMATIONS === */
|
|
```
|
|
|
|
### 2. Naming
|
|
```css
|
|
/* Use kebab-case */
|
|
.chess-board { }
|
|
.game-controls { }
|
|
.piece-white-pawn { }
|
|
```
|
|
|
|
### 3. Values
|
|
```css
|
|
/* Use CSS variables for reusability */
|
|
:root {
|
|
--board-size: 600px;
|
|
--square-size: 75px;
|
|
--light-square: #f0d9b5;
|
|
--dark-square: #b58863;
|
|
}
|
|
```
|
|
|
|
## HTML Standards
|
|
|
|
### 1. Structure
|
|
```html
|
|
<!-- Semantic HTML5 -->
|
|
<main class="game-container">
|
|
<section class="board-section">
|
|
<!-- Board -->
|
|
</section>
|
|
<aside class="controls-section">
|
|
<!-- Controls -->
|
|
</aside>
|
|
</main>
|
|
```
|
|
|
|
### 2. Attributes
|
|
```html
|
|
<!-- Use data attributes for JS hooks -->
|
|
<div class="square" data-row="0" data-col="0"></div>
|
|
|
|
<!-- Accessibility -->
|
|
<button aria-label="Start new game">New Game</button>
|
|
```
|
|
|
|
## Git Commit Standards
|
|
|
|
```
|
|
feat: Add pawn movement validation
|
|
fix: Correct checkmate detection logic
|
|
docs: Update API documentation
|
|
style: Format code according to standards
|
|
refactor: Simplify move validation
|
|
test: Add tests for castling
|
|
chore: Update dependencies
|
|
```
|
|
|
|
## Code Review Checklist
|
|
|
|
- [ ] Follows naming conventions
|
|
- [ ] Includes JSDoc documentation
|
|
- [ ] Has error handling
|
|
- [ ] No magic numbers
|
|
- [ ] Uses ES6+ features appropriately
|
|
- [ ] Has corresponding tests
|
|
- [ ] No console.log statements (use proper logging)
|
|
- [ ] Follows single responsibility principle
|
|
- [ ] Code is DRY (Don't Repeat Yourself)
|
|
- [ ] Passes ESLint (if configured)
|