A lightweight chess engine written in TypeScript with a clear separation between move validation and move execution.
Current implementation supports full piece movement rules for all standard piece types and a standard board setup.
- 8x8 board model with bounds-safe access (
Board) - Standard starting position setup (
Setup.standard) - Piece movement rules implemented for:
- pawn
- rook
- knight
- bishop
- queen
- king
- Turn-based move validation pipeline (
MoveValidator)- source square contains a piece
- piece color matches current player
- destination is in the piece's legal move list
- move cannot leave own king in check
- Atomic move execution service (
MoveService)- updates board squares
- updates moved piece position
- supports basic capture handling
- Full special-move support
- castling
- en passant
- promotion (defaults to queen if omitted)
- Game state checks
- check detection
- checkmate detection
- stalemate detection
- game end reason (
checkmateorstalemate)
- Algebraic square parsing and formatting (
algebraicToPosition,positionToAlgebraic) - Move history logging in game flow (
from->tostring format) - Terminal-friendly ASCII board rendering (
Board.toAscii/Board.print)
Game: orchestrates game flow (start, move, turn switching, history)Setup: places all pieces on initial squaresMoveValidator: owns legality checksMoveService: owns state mutation for execute/undoBoard: owns grid storage and square accessPiecesubclasses: own movement generation for each piece typeutils: position and square conversion helpers
src/
index.ts
board/
Board.ts
game/
Game.ts
Setup.ts
move/
Move.ts
MoveService.ts
MoveValidator.ts
pieces/
Bishop.ts
King.ts
Knight.ts
Pawn.ts
Piece.ts
Queen.ts
Rook.ts
types/
grid.ts
pieceType.ts
utils/
positionUtils.ts
square.ts
tests/
game/
SpecialRules.test.ts
pieces/
Bishop.test.ts
Pawn.test.ts
RookKnight.test.ts
utils/
positionUtils.test.ts
square.test.ts
- Node.js 18+
- npm
npm installnpm run devnpm testnpm run test:watchnpm run buildnpm startFrom src/index.ts:
import { Game } from "./game/Game";
const game = new Game();
game.start();
game.move("e2", "e4");
game.move("e7", "e5");
game.move("g1", "f3");
game.move("b8", "c6");
game.move("f1", "c4");
console.log("Game History:");
console.log(game.moveHistory);
console.log("Board State:");
game.board.print();- No FEN/PGN import-export
- Move history is a simple
from->tolist (not full algebraic notation)
This project is licensed under the ISC License. See LICENSE for details.