Rust/Wasm Othello AI running entirely in the browser with Bitboards, alpha-beta search, and worker-based parallelism. The engine includes exact endgame search and stability-aware evaluation for stronger late-game decisions.
- Game demo: https://billzi2016.github.io/Othello-AI/
- Documentation site: https://billzi2016.github.io/Othello-AI/docs/
- Algorithm deep dive: https://billzi2016.github.io/Othello-AI/docs/en/algorithm-deep-dive/
- Browser-only Othello game deployable to GitHub Pages.
- Local two-player mode, human-vs-AI mode, and AI-vs-AI mode.
- Rust/Wasm search engine using two
u64Bitboards. - Alpha-Beta / NegaMax search with iterative deepening.
- Exact endgame search when the remaining empty squares are low.
- Stability-aware evaluation to distinguish temporary material from safe discs.
- Up to 4 seconds of thinking time per move.
- Web Worker pool using about 90% of local CPU threads by default.
coi-serviceworker.jssupport forcrossOriginIsolatedon static hosting.- Search statistics panel showing depth, score, nodes, NPS, and time for each AI move.
- Yellow AI legal-move highlights while the engine is thinking.
index.html # Page entry and menus
coi-serviceworker.js # Adds COOP/COEP headers through a Service Worker
assets/js/main.js # UI, rules, animation, and game flow
assets/js/ai-manager.js # Worker pool using about 90% CPU threads
assets/js/ai-worker.js # Loads Rust/Wasm and runs search jobs
assets/wasm/ # Generated browser Wasm bindings
rust-ai/ # Rust/Wasm AI engine
server.py # Threaded local static server with random free port selection
.github/workflows/pages.yml # GitHub Actions build and Pages deployment
docs-site/ # MkDocs documentation site source, published under /docs/
Do not open index.html through file://. Web Workers, Wasm, and Service Workers need an HTTP environment.
Use the included server:
python3 server.pyYou can also choose a port manually:
python3 server.py --port 9000The server prints the actual URL, for example:
http://127.0.0.1:8342/
On the first visit, coi-serviceworker.js may reload the page once so the page is controlled by the Service Worker.
Install Rust and wasm-bindgen-cli, then build the engine:
cd rust-ai
rustup target add wasm32-unknown-unknown
cargo install wasm-bindgen-cli
cargo build --target wasm32-unknown-unknown --release
mkdir -p ../assets/wasm
wasm-bindgen --target web --out-dir ../assets/wasm --out-name othello_ai target/wasm32-unknown-unknown/release/othello_ai.wasmGenerated files:
assets/wasm/othello_ai.js
assets/wasm/othello_ai_bg.wasm
ai-worker.js loads assets/wasm/othello_ai.js and calls the exported Rust function search_best_move().
The engine stores the board as two u64 Bitboards:
black: occupied squares for black discs.white: occupied squares for white discs.
Bit index mapping:
index = row * 8 + col
Search strategy:
- JavaScript splits root legal moves across multiple Workers.
- Each Worker searches its own root-move shard in Rust/Wasm.
- Rust uses NegaMax-style Alpha-Beta search.
- Iterative deepening keeps a usable best move available within the 4-second budget.
- The endgame phase searches directly to game over instead of relying on heuristic evaluation.
- Evaluation combines square weights, corners, mobility, frontier discs, parity, stability, and terminal disc count.
- Rust/Wasm: the search core is written in Rust and compiled to WebAssembly, giving the browser a fast local engine without any backend server.
- Bitboards: the board is represented by two
u64values, so move generation and board updates stay compact and cache-friendly. - NegaMax Minimax: the engine assumes both sides choose their best moves and uses a symmetric NegaMax form to simplify recursive search.
- Alpha-Beta pruning: branches that cannot affect the final decision are cut early, allowing deeper search within the same time budget.
- Iterative deepening: the engine searches depth 1, then depth 2, and so on, so it always has a valid best move when the 4-second limit expires.
- Transposition table: previously searched positions are cached during a move search, reducing repeated work when the same position is reached through different move orders.
- Move ordering, killer moves, and history heuristic: likely strong moves are searched first, which improves Alpha-Beta pruning efficiency.
- Exact endgame search: when few empty squares remain, the engine searches directly to the end of the game instead of relying on heuristics.
- Stability-aware evaluation: stable discs, corners, mobility, frontier discs, parity, and terminal disc count are evaluated to improve late-game decisions.
- Web Worker parallelism: root moves are split across Workers using about 90% of available CPU threads, keeping the UI responsive while the AI searches.
- Search telemetry: every AI move reports depth, Minimax score, visited nodes, nodes per second, and elapsed time to the side panel.
The current AI parallelism model is root-move sharding across multiple Web Workers, with each Worker loading its own Wasm module. It does not require Wasm pthreads or SharedArrayBuffer. coi-serviceworker.js is kept so static hosting such as GitHub Pages can provide cross-origin isolation headers, which also leaves room for future features that may require crossOriginIsolated. A normal server can set:
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
GitHub Pages cannot configure custom response headers directly, so this project uses coi-serviceworker.js to add the required headers from the client side through a Service Worker.
This repository includes a GitHub Actions workflow:
.github/workflows/pages.yml
On push to main or master, the workflow:
- Installs Rust.
- Installs
wasm-bindgen-cli. - Builds
rust-aiforwasm32. - Generates browser-loadable files in
assets/wasm/. - Builds the MkDocs documentation site.
- Copies the documentation output to
_site/docs/. - Uploads the static site artifact.
- Deploys to GitHub Pages.
The workflow can also be triggered manually from the GitHub Actions page.
If you do not use GitHub Actions, build the Rust/Wasm output locally with the commands above, then publish the static files to your GitHub Pages branch or configured Pages directory. Make sure these files are present:
index.html
coi-serviceworker.js
assets/js/main.js
assets/js/ai-manager.js
assets/js/ai-worker.js
assets/wasm/othello_ai.js
assets/wasm/othello_ai_bg.wasm
GitHub Pages only serves static files. All AI computation runs locally in the visitor's browser and CPU.