No description
  • TypeScript 67.4%
  • HTML 18.5%
  • CSS 14.1%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Michael Davis f14df4116d Default the reconstruction quiz to off
New users found it confusing and distracting. It's still available
as an opt-in toggle via the Quiz chip for advanced users.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-27 18:23:57 -07:00
public Initial commit: SansBoard blindfold chess trainer 2026-07-26 15:45:42 -07:00
src Default the reconstruction quiz to off 2026-07-27 18:23:57 -07:00
.gitignore Initial commit: SansBoard blindfold chess trainer 2026-07-26 15:45:42 -07:00
index.html Move Ko-fi link to top center of the header 2026-07-26 17:11:03 -07:00
mockup.html Initial commit: SansBoard blindfold chess trainer 2026-07-26 15:45:42 -07:00
package-lock.json Initial commit: SansBoard blindfold chess trainer 2026-07-26 15:45:42 -07:00
package.json Initial commit: SansBoard blindfold chess trainer 2026-07-26 15:45:42 -07:00
README.md Update README: chess-sound voice biasing, Ko-fi link location 2026-07-26 17:11:58 -07:00
tsconfig.json Initial commit: SansBoard blindfold chess trainer 2026-07-26 15:45:42 -07:00
vite.config.ts Initial commit: SansBoard blindfold chess trainer 2026-07-26 15:45:42 -07:00
wrangler.jsonc Initial commit: SansBoard blindfold chess trainer 2026-07-26 15:45:42 -07:00

SansBoard

A single-user blindfold chess trainer. You play against a built-in engine, but the board only shows you the current position at configurable checkpoints ("blind windows") — for the moves in between, you're playing from memory.

Live at sansboard.com.

How it works

  • Choose a blind window length (in half-moves) — an odd number so the window alternates between opening on your move and the engine's.
  • While a window is open, the board stays frozen at the last synced position. If the window opened on the engine's move, you get that move in notation only (never reflected on the board) before you reply.
  • When the window closes, you're asked to reconstruct the current position from memory (drag/click pieces into place, or replay the moves by typing or speaking them) before the real position is revealed.
  • Moves can be entered by keyboard (lenient SAN — case-insensitive, 0-0 works for castling) or by voice, hands-free.

Everything else — Elo, flash duration, hard mode (strip extra info from notation), text-to-speech, the reconstruction quiz, move-list visibility — is configurable from the sidebar and persisted to localStorage.

Enjoying it? There's a quiet Ko-fi link at the top of the page.

Stack

Vanilla TypeScript + Vite. No UI framework — the board is hand-rolled CSS grid + absolutely positioned piece elements, animated with CSS transforms.

  • chess.js for rules/SAN/FEN
  • Stockfish 18 (WASM, lite single-threaded build) running in Web Workers via UCI — one instance plays as the (strength-limited) opponent, a second runs at full strength in the background to score your moves by centipawn loss
  • Web Speech API for text-to-speech and continuous, hands-free speech recognition, with a natural-language parser (src/voice.ts) that biases garbled transcripts toward chess sounds ("before" → b4, "tonight" → knight) — but never toward legal moves, so a clearly-uttered illegal move is rejected and logged rather than reinterpreted as something else

Development

npm install
npm run dev

Build and typecheck:

npm run build

Deploy

Deployed as a Cloudflare Worker (static assets), via Wrangler:

npm run build
npx wrangler deploy

See wrangler.jsonc for the custom domain / routes configuration.