feat(offline): robot move-choice strategy in TS (parity-pinned) #189

Merged
developer merged 1 commits from feature/offline-robot-strategy into development 2026-07-05 23:59:07 +00:00
Owner

Phase A (2/2) of PWA offline mode, on top of #188. The offline robot picks its move exactly as the server does, so a local vs_ai game plays the same. Not wired into a game loop yet (Phase B).

  • ui/src/lib/robot/strategy.ts: port of backend/internal/robot/strategy.go's move-choice slice — mix (FNV-1a, via BigInt for bit-exact uint64), playToWin (~40%), deviates (the fading off-strategy wobble) and selectMove (pick the candidate whose resulting margin lands closest to the ±[1,30] band, conservative tie-break), composed by decide(). The generator's ranked moves feed straight in. Think-time/sleep/nudge scheduling is server-only and not ported.
  • backend/internal/robot/strategyfixture_test.go: an in-package, env-gated emitter (EMIT_STRATEGY_FIXTURES=1) writing golden fixtures from the real Go strategy (reaches the unexported mix/playToWin/deviates/selectMove).
  • strategy.parity.test.ts: 21 mix + 56 decision cases match Go exactly (play/exchange/pass, the deviate flip, tie-break, band overshoot).

Pure additive library code; no runtime behavior change (unused at runtime, so the bundle is unchanged). Local verification green: backend build/vet/gofmt/test; UI check + test:unit (432 passed) + build.

Phase A (2/2) of PWA offline mode, on top of #188. The offline robot picks its move exactly as the server does, so a local vs_ai game plays the same. Not wired into a game loop yet (Phase B). - `ui/src/lib/robot/strategy.ts`: port of `backend/internal/robot/strategy.go`'s move-choice slice — `mix` (FNV-1a, via BigInt for bit-exact uint64), `playToWin` (~40%), `deviates` (the fading off-strategy wobble) and `selectMove` (pick the candidate whose resulting margin lands closest to the ±[1,30] band, conservative tie-break), composed by `decide()`. The generator's ranked moves feed straight in. Think-time/sleep/nudge scheduling is server-only and not ported. - `backend/internal/robot/strategyfixture_test.go`: an in-package, env-gated emitter (`EMIT_STRATEGY_FIXTURES=1`) writing golden fixtures from the real Go strategy (reaches the unexported `mix`/`playToWin`/`deviates`/`selectMove`). - `strategy.parity.test.ts`: 21 mix + 56 decision cases match Go exactly (play/exchange/pass, the deviate flip, tie-break, band overshoot). Pure additive library code; no runtime behavior change (unused at runtime, so the bundle is unchanged). Local verification green: backend build/vet/gofmt/test; UI check + test:unit (432 passed) + build.
developer added 1 commit 2026-07-05 23:54:39 +00:00
feat(offline): port robot move-choice strategy to TS (parity-pinned)
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 10s
CI / integration (pull_request) Successful in 15s
CI / ui (pull_request) Successful in 1m9s
CI / conformance (pull_request) Successful in 9s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m37s
8c5995c076
Phase A (2/2) of PWA offline mode: the offline robot picks its move exactly as the
server does, so a local vs_ai game plays the same. Builds on the move generator
from #188; not wired into a game loop yet (Phase B).

- ui/src/lib/robot/strategy.ts: port of backend/internal/robot/strategy.go's
  move-choice slice — mix (FNV-1a, via BigInt for bit-exact uint64), playToWin
  (~40% play-to-win), deviates (the fading off-strategy wobble) and selectMove
  (pick the candidate whose resulting margin lands closest to the +/-[1,30] band,
  conservative tie-break), composed by decide(). The generator's ranked moves feed
  straight in. Think-time/sleep/nudge scheduling is server-only and not ported.
- backend/internal/robot/strategyfixture_test.go: an in-package, env-gated emitter
  (EMIT_STRATEGY_FIXTURES=1) writing golden fixtures from the real Go strategy — it
  reaches the unexported mix/playToWin/deviates/selectMove.
- strategy.parity.test.ts: 21 mix + 56 decision cases match Go exactly (play/
  exchange/pass, the deviate flip, tie-break, band overshoot).

Pure additive library code; no runtime behavior change (unused at runtime, so the
bundle is unchanged).
owner approved these changes 2026-07-05 23:57:19 +00:00
developer merged commit d694ead7b6 into development 2026-07-05 23:59:07 +00:00
developer deleted branch feature/offline-robot-strategy 2026-07-05 23:59:07 +00:00
Sign in to join this conversation.
No Reviewers
No Label
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: developer/scrabble-game#189