chess-movegen-js

Chess Move Generator

JavaScript chess move generator with strictly legal move generation

npm version npm downloads CI JavaScript License

English Espaรฑol

๐ŸŽฏ Key Features

๐Ÿš€ Quick Demo

Try it live!

Or open visualizer/engine.html in your browser locally.

๐Ÿ“ฆ Installation

NPM

npm install chess-movegen-js

Usage

const { Board } = require('chess-movegen-js');

const board = new Board();
board.loadFEN('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1');
board.generateMoves();

console.log(`Legal moves: ${board.moves.length}`); // 20

Chess.js Compatibility (Drop-in Replacement)

If you are already using chess.js, you can use ChessJSAdapter as a high-performance drop-in replacement. It provides the same API (.moves(), .move(), .fen(), .isCheck(), etc.) but uses the x88 engine under the hood, making it ~50x faster.

const { ChessJSAdapter } = require('chess-movegen-js/chessjs');

// Works exactly like chess.js
const chess = new ChessJSAdapter();
chess.move('e4');
console.log(chess.fen());
console.log(chess.moves()); // Standard Algebraic Notation (SAN)

๐Ÿ“Š Performance Comparison (NPS)

Performance measured in Node.js (Depth 4 avg):

Generator NPS (Nodes Per Second) Speedup vs chess.js
chess.js (Original) ~75,000 1x (Base)
ChessJSAdapter (x88) ~3,500,000 47x Faster
JS x88 Generator ~3,500,000 47x Faster
AssemblyScript x88 ~3,800,000 51x Faster
Rust X88 ~10,800,000 145x Faster
Rust Bitboard ~15,800,000 213x Faster

๐Ÿ“– Usage Examples

Basic Initialization

// Create a board
const board = new Board();

// Load a FEN position
board.loadFEN('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1');

// Generate all legal moves
board.generateMoves();

// View the moves
console.log(board.moves);

Move Analysis

Moves include tactical information:

board.generateMoves();

board.moves.forEach(move => {
    const moveStr = board.getMoveStr(move);
    console.log(moveStr);
    
    // Tactical information in move.mask:
    // - mask_check: Gives check
    // - mask_safe: Safe square
    // - mask_hanging: Piece would be hanging
    // - mask_freecapture: Undefended capture
    // - mask_winningcapture: Winning capture
});

Make and Unmake Moves

// Make a move
const move = board.moves[0];
board.makemove(move);

// Unmake
board.undomove();

Perft (Move Generation Testing)

// Count nodes at depth 5
const nodes = board.perft(5);
console.log(`Nodes: ${nodes}`); // 4,865,609 from initial position

// Divide (show nodes per move)
board.divide(4);

๐Ÿ—๏ธ Project Structure

movegen/
โ”œโ”€โ”€ js/
โ”‚   โ”œโ”€โ”€ x88.js           # x88 representation generator (JS)
โ”‚   โ”œโ”€โ”€ bitboard.js      # Bitboard generator (JS)
โ”‚   โ””โ”€โ”€ magic-tables.js  # Magic tables for bitboard
โ”œโ”€โ”€ rust-movegen/        # Rust implementation (x88 & Bitboard, WASM)
โ”œโ”€โ”€ asmovegen/           # AssemblyScript implementation (x88, WASM)
โ”œโ”€โ”€ visualizer/          # Interactive web interface
โ”‚   โ”œโ”€โ”€ engine.html      # Main demo page
โ”‚   โ””โ”€โ”€ js/              # Engine workers and UI logic
โ”œโ”€โ”€ tests/               # Comprehensive Perft test suite
โ”œโ”€โ”€ ANALISIS.md          # Detailed technical analysis
โ””โ”€โ”€ README.md            # This file

๐ŸŽฎ UCI Engine

The project includes a complete UCI engine running in a Web Worker:

// Create engine
const w = new Worker("js/engine.js");

// UCI communication
w.postMessage('uci');
w.postMessage('position fen rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1');
w.postMessage('perft 6');

// Listen for responses
w.onmessage = function(event) {
    console.log(event.data);
};

Supported UCI Commands

โšก Performance

Benchmarks from initial position (Depth 5):

Implementation Platform NPS
Rust Bitboard WASM/Browser ~25.8M
Rust x88 WASM/Browser ~18.0M
AssemblyScript WASM/Browser ~12.5M
JS x88 Node.js / Browser ~5.6M
JS Bitboard Node.js / Browser ~4.2M

Perft from initial position (Node.js v20+, no debug): All versions pass 100% of Perft tests up to depth 6+.

๐ŸŽจ Technical Highlights

1. Pin Detection

Pinned pieces are detected during generation. Illegal moves are never generated:

// pinDirection[side][square] indicates if a piece is pinned
// and in which direction

2. Tactical Enrichment

Each move contains flags indicating:

3. Special Cases

๐Ÿ”ฌ Implementations

Bitboards

๐Ÿ“š Documentation

For a complete technical analysis of the code, see ANALISIS.md.

๐Ÿงช Testing

The project uses Perft to validate move generation:

// From browser console in engine.html
w.postMessage('perft 5');

// Or in code
const board = new Board();
board.loadFEN('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1');
console.log(board.perft(5)); // Should be 4,865,609

๐Ÿงช Running Tests

The project includes a comprehensive Perft test suite to validate move generation correctness and measure performance.

Quick Start

# Run quick test suite (depths 1-4, ~1 minute)
node tests/perft-test.js --quick

# Test specific position
node tests/perft-test.js --position 0 --depth 5

# Test specific generator
node tests/perft-test.js --generator rust-bb --depth 6

Available Options

node tests/perft-test.js [options]

Options:
  --generator <x88|bb|as|rust-x88|rust-bb|all>   Select generator to test (default: all)
  --position <n>              Test only position n (default: all)
  --depth <n>                 Test up to depth n (default: 6)
  --quick                     Quick test mode (depths 1-4)
  --help                      Show help message

Test Positions

The test suite includes 7 standard positions from Chess Programming Wiki:

Position Description Max Depth Tested
0 Initial position 10
1 Kiwipete (complex middle game) 6
2 En passant edge cases 8
3 Promotions 6
4 Promotions (mirrored) 6
5 Complex tactical position 5
6 Symmetrical position 6

Expected Output

Chess Move Generator - Perft Test Suite

Configuration:
  Generator: all
  Positions: 7
  Max depth: 4

โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”
Summary
โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”

Total tests: 140 (5 generators * 7 positions * 4 depths)
Passed: 140
Failed: 0
Pass rate: 100.0%

๐ŸŽฏ Next Steps

โš™๏ธ Continuous Integration (GitHub Actions)

How to launch the full test from GitHub UI:

  1. Go to the Actions tab of the repository.
  2. Select the CI workflow.
  3. Click Run workflow, choose the branch (main or master), and execute.

Using the gh CLI (GitHub CLI):

gh workflow run ci.yml --ref main

Note: The CI workflow includes a matrix of Node versions for quick tests and reserves a manual job (test-bitboard-full) with a longer timeout for intensive testing.

๐Ÿค Contributing

Contributions are welcome. Please:

  1. Fork the project
  2. Create a branch for your feature (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

๐Ÿ“– Resources and References

๐Ÿ“ License

This project is under the MIT License - see the LICENSE file for details.

๐Ÿ‘ค Author

Mario Raรบl Carbonell Martรญnez


โญ If you find this project useful, consider giving it a star on GitHub!