cm-engine-runner 1.2.4 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -15
- package/index.html +1 -1
- package/package.json +3 -3
- package/src/EngineRunner.js +0 -4
- package/src/StockfishRunner.js +9 -4
- package/.claude/settings.local.json +0 -10
- package/CLAUDE.md +0 -57
- package/engines/stockfish-v10-niklasf.js +0 -37
package/README.md
CHANGED
|
@@ -4,28 +4,18 @@ A JavaScript module to act as a framework for running chess engines in the brows
|
|
|
4
4
|
|
|
5
5
|
## Working engines
|
|
6
6
|
|
|
7
|
-
### Stockfish
|
|
7
|
+
### Stockfish 18
|
|
8
8
|
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
- https://github.com/niklasf/stockfish.js
|
|
9
|
+
- npm package: `stockfish` (v18.0.5)
|
|
10
|
+
- File: `node_modules/stockfish/bin/stockfish-18-lite-single.js`
|
|
11
|
+
- Type: WASM (single-threaded lite variant)
|
|
12
|
+
- https://github.com/nmrugg/stockfish.js
|
|
14
13
|
|
|
15
14
|
### Polyglot opening books
|
|
16
15
|
|
|
17
16
|
- An engine to play moves from a polyglot (.bin) openings file.
|
|
18
17
|
- https://github.com/shaack/cm-polyglot
|
|
19
18
|
|
|
20
|
-
### Stockfish 14
|
|
21
|
-
|
|
22
|
-
Not implemented yet, does not work in Safari as of 2021-12-12
|
|
23
|
-
|
|
24
|
-
- Type: WASM
|
|
25
|
-
- Stockfish version: 14
|
|
26
|
-
- Latest js version, multithreaded
|
|
27
|
-
- https://github.com/nmrugg/stockfish.js
|
|
28
|
-
|
|
29
19
|
## Stockfish Skill Levels
|
|
30
20
|
|
|
31
21
|
this.uciCmd('setoption name Skill Level value ' + (LEVELS[props.level][1]))
|
package/index.html
CHANGED
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
const positionEndGame = "8/8/8/2k5/4K3/8/8/8"
|
|
34
34
|
console.log("polyglot", positionEndGame, await polyglotRunner.calculateMove(positionEndGame))
|
|
35
35
|
|
|
36
|
-
const stockfishRunner = new StockfishRunner({workerUrl: "./node_modules/stockfish/
|
|
36
|
+
const stockfishRunner = new StockfishRunner({workerUrl: "./node_modules/stockfish/bin/stockfish-18-lite-single.js", responseDelay: 0, debug: true})
|
|
37
37
|
console.log("stockfish", await stockfishRunner.calculateMove(startingFewMoves))
|
|
38
38
|
const postitionBlackWillWin = "4k3/3r4/8/8/8/8/6K1/8 w - - 0 1"
|
|
39
39
|
console.log("stockfish", await stockfishRunner.calculateMove(postitionBlackWillWin, {level: 1}))
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cm-engine-runner",
|
|
3
3
|
"description": "Abstraction layer to run chess engines, supports opening books",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "2.0.1",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"scripts": {
|
|
@@ -24,10 +24,10 @@
|
|
|
24
24
|
},
|
|
25
25
|
"homepage": "https://github.com/shaack/cm-chess-engine-adapter#readme",
|
|
26
26
|
"devDependencies": {
|
|
27
|
-
"teevi": "^2.
|
|
27
|
+
"teevi": "^2.3.0"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"cm-polyglot": "^1.1.0",
|
|
31
|
-
"stockfish": "^
|
|
31
|
+
"stockfish": "^18.0.5"
|
|
32
32
|
}
|
|
33
33
|
}
|
package/src/EngineRunner.js
CHANGED
|
@@ -22,10 +22,6 @@ export class EngineRunner {
|
|
|
22
22
|
Object.assign(this.props, props)
|
|
23
23
|
this.engineState = ENGINE_STATE.LOADING
|
|
24
24
|
this.initialized = this.init()
|
|
25
|
-
/**
|
|
26
|
-
* @deprecated 2023-04-11 use `this.initialized` instead
|
|
27
|
-
*/
|
|
28
|
-
this.initialization = this.initialized
|
|
29
25
|
}
|
|
30
26
|
|
|
31
27
|
init() {
|
package/src/StockfishRunner.js
CHANGED
|
@@ -37,9 +37,12 @@ export class StockfishRunner extends EngineRunner {
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
init() {
|
|
40
|
-
return new Promise((resolve) => {
|
|
40
|
+
return new Promise((resolve, reject) => {
|
|
41
41
|
const listener = (event) => {
|
|
42
42
|
this.workerListener(event)
|
|
43
|
+
if (this.engineState === ENGINE_STATE.READY) {
|
|
44
|
+
resolve()
|
|
45
|
+
}
|
|
43
46
|
}
|
|
44
47
|
if (this.engineWorker) {
|
|
45
48
|
this.engineWorker.removeEventListener("message", listener)
|
|
@@ -47,11 +50,13 @@ export class StockfishRunner extends EngineRunner {
|
|
|
47
50
|
}
|
|
48
51
|
this.engineWorker = new Worker(this.props.workerUrl)
|
|
49
52
|
this.engineWorker.addEventListener("message", listener)
|
|
53
|
+
this.engineWorker.addEventListener("error", () => {
|
|
54
|
+
reject(new Error("Engine worker failed to load from: " + this.props.workerUrl))
|
|
55
|
+
})
|
|
50
56
|
|
|
51
57
|
this.uciCmd('uci')
|
|
52
58
|
this.uciCmd('ucinewgame')
|
|
53
59
|
this.uciCmd('isready')
|
|
54
|
-
resolve()
|
|
55
60
|
})
|
|
56
61
|
}
|
|
57
62
|
|
|
@@ -80,8 +85,8 @@ export class StockfishRunner extends EngineRunner {
|
|
|
80
85
|
}
|
|
81
86
|
this.score = tmpScore
|
|
82
87
|
}
|
|
83
|
-
// match = line.match(/^bestmove ([a-h][1-8])([a-h][1-8])([
|
|
84
|
-
match = line.match(/^bestmove ([a-h][1-8])([a-h][1-8])([
|
|
88
|
+
// match = line.match(/^bestmove ([a-h][1-8])([a-h][1-8])([qrbn])?/) // ponder is not always included
|
|
89
|
+
match = line.match(/^bestmove ([a-h][1-8])([a-h][1-8])([qrbn])?( ponder ([a-h][1-8])?([a-h][1-8])?)?/)
|
|
85
90
|
if (match) {
|
|
86
91
|
this.engineState = ENGINE_STATE.READY
|
|
87
92
|
if (match[4] !== undefined) {
|
package/CLAUDE.md
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
# CLAUDE.md
|
|
2
|
-
|
|
3
|
-
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
-
|
|
5
|
-
## Project Overview
|
|
6
|
-
|
|
7
|
-
cm-engine-runner is a lightweight JavaScript library for running chess engines in the browser. It provides an abstraction layer supporting multiple backends: Stockfish (via WebWorkers) and Polyglot opening books.
|
|
8
|
-
|
|
9
|
-
## Development Commands
|
|
10
|
-
|
|
11
|
-
```bash
|
|
12
|
-
# Install dependencies
|
|
13
|
-
npm install
|
|
14
|
-
|
|
15
|
-
# Run the demo/test page
|
|
16
|
-
# Open index.html in a browser (uses importmap for ES6 module resolution)
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
No build step is required - the library uses pure ES6 modules that run directly in browsers.
|
|
20
|
-
|
|
21
|
-
## Architecture
|
|
22
|
-
|
|
23
|
-
The project uses an **adapter pattern** with a base class and engine-specific implementations:
|
|
24
|
-
|
|
25
|
-
```
|
|
26
|
-
EngineRunner (base class)
|
|
27
|
-
├── StockfishRunner → WebWorker → Stockfish WASM engine
|
|
28
|
-
└── PolyglotRunner → cm-polyglot → Opening book (.bin)
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
### Core Files
|
|
32
|
-
|
|
33
|
-
- `src/EngineRunner.js` - Abstract base class defining the interface and state machine (`ENGINE_STATE`: LOADING, LOADED, READY, THINKING)
|
|
34
|
-
- `src/StockfishRunner.js` - Stockfish adapter implementing UCI protocol communication, skill levels 1-20 with depth mapping
|
|
35
|
-
- `src/PolyglotRunner.js` - Polyglot opening book reader with probability-weighted move selection
|
|
36
|
-
- `engines/stockfish-v10-niklasf.js` - Compiled Stockfish v10 engine (runs in WebWorker)
|
|
37
|
-
|
|
38
|
-
### API Pattern
|
|
39
|
-
|
|
40
|
-
All adapters share this interface:
|
|
41
|
-
```javascript
|
|
42
|
-
runner.calculateMove(fen, props) → Promise<{from, to, promotion?, score?, ponder?}>
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
### Adding a New Engine
|
|
46
|
-
|
|
47
|
-
1. Extend `EngineRunner` class
|
|
48
|
-
2. Implement `init()` to set up the engine
|
|
49
|
-
3. Implement `calculateMove(fen, props)` returning a Promise with move data
|
|
50
|
-
4. Manage engine state via `ENGINE_STATE` constants
|
|
51
|
-
|
|
52
|
-
## Key Implementation Details
|
|
53
|
-
|
|
54
|
-
- Uses `importmap` in index.html for browser-based ES6 module resolution (no bundler)
|
|
55
|
-
- StockfishRunner communicates with the engine via `postMessage` using UCI protocol
|
|
56
|
-
- `responseDelay` prop adds artificial delay for UX purposes
|
|
57
|
-
- `debug` prop enables console logging
|