An Othello (Reversi) game where you play against an AI opponent. The game UI is built with Solid.js and the game logic in TypeScript, while the AI engine is written in C, compiled to WebAssembly, and run off the main thread in a Web Worker for a smooth, responsive experience.
- 🧠 Native-speed AI powered by a negamax algorithm compiled to WebAssembly
- ⚙️ Three difficulty levels (Easy, Medium, Hard) that adjust search depth
- 🧵 AI runs in a Web Worker, so the UI never freezes while it thinks
- ✨ Animated discs — placement and flip animations, last-AI-move highlight, and legal-move hints
- 📱 Responsive board that scales from mobile to desktop
┌─────────────┐ move ┌──────────────┐ board+player ┌──────────────────┐
│ Solid.js │ ────────► │ Web Worker │ ─────────────► │ WASM AI engine │
│ UI + state │ │ (AIworker.ts)│ │ (othelloAI.c) │
│ (othello.ts)│ ◄──────── │ │ ◄───────────── │ │
└─────────────┘ AI move └──────────────┘ best move └──────────────────┘
src/othello.ts— game rules and state (legal moves, flipping, scoring, win detection).src/components/— Solid.js components for the board, game status, and result screen.src/AIworker.ts— Web Worker that loads the WASM module, marshals the board into shared memory, and calls into the engine.othelloAI.c— the AI engine, compiled tosrc/othelloAI.wasm.
When it's the AI's turn, the board is serialized into the WASM module's linear memory and getAImove is invoked. The computed move is posted back to the UI thread, with a minimum "thinking" delay so the AI's turn feels natural.
The AI uses the negamax variant of minimax with alpha–beta pruning to search the game tree and pick the move that maximizes its advantage while minimizing the opponent's options.
Positions are scored with a heuristic combining:
- Stability — discs that can no longer be flipped (e.g. along secured edges).
- Parity — the disc-count difference between the AI and the opponent.
- Position — a weighting of each square, favoring strong squares like corners and penalizing risky ones.
Search depth adapts to both the difficulty level and the game phase (opening, midgame, endgame).
Requires Node.js and a package manager (npm shown below).
# install dependencies
npm install
# start the dev server
npm run dev
# build for production
npm run build
# preview the production build
npm run serveThe compiled src/othelloAI.wasm is committed, so you only need this if you change othelloAI.c. It requires the Emscripten SDK:
emcc othelloAI.c -O3 --no-entry -s STANDALONE_WASM \
-s EXPORTED_FUNCTIONS=_getAImove \
-o src/othelloAI.wasm| Layer | Technology |
|---|---|
| UI | Solid.js, CSS Modules |
| Game logic | TypeScript |
| AI engine | C → WebAssembly (Emscripten) |
| Concurrency | Web Worker |
| Tooling | Vite, TypeScript |
