feat(offline): local game engine (Phase B1) #191

Merged
developer merged 1 commits from feature/offline-localgame-engine into development 2026-07-06 06:15:56 +00:00
Owner

Phase B1 of PWA offline mode, on top of #188/#189/#190. The offline vs_ai game engine — a faithful TS port of backend/internal/engine that drives a whole local game with no backend. Composes with the Phase-A move generator + robot strategy; not wired into the UI yet (B2/B3).

  • ruleset.ts: static per-variant tile values / bag counts / blanks, mirrored from rules.go (offline scoring self-contained); pinned by ruleset.parity.test.ts against a Go fixture.
  • bag.ts: tile bag (fill / draw-from-end / return+reshuffle) on a deterministic in-house PRNG — replays from the seed, not bit-identical to a server game (per plan).
  • board.ts: mutable board satisfying the validator/generator read view + set().
  • engine.ts: LocalGame — deal / play (reusing validate.ts) / pass / exchange / resign, scoreless(6) + out-of-tiles end, end-of-game rack penalties, winner; mirrors game.go. End-game math exported as pure functions, pinned vs the Go engine (engine.parity.test.ts, 9 constructed positions).
  • engine.test.ts: a full-loop smoke — two robots play a whole vs_ai game to completion via generateMoves+decide, reproducible from the seed.
  • backend: movegen now dumps the per-variant rulesets; a new in-package engine emitter (endfixture_test.go, env-gated) produces the end-game golden.

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

Phase B1 of PWA offline mode, on top of #188/#189/#190. The offline vs_ai game engine — a faithful TS port of `backend/internal/engine` that drives a whole local game with no backend. Composes with the Phase-A move generator + robot strategy; not wired into the UI yet (B2/B3). - `ruleset.ts`: static per-variant tile values / bag counts / blanks, mirrored from `rules.go` (offline scoring self-contained); pinned by `ruleset.parity.test.ts` against a Go fixture. - `bag.ts`: tile bag (fill / draw-from-end / return+reshuffle) on a deterministic in-house PRNG — replays from the seed, not bit-identical to a server game (per plan). - `board.ts`: mutable board satisfying the validator/generator read view + `set()`. - `engine.ts`: `LocalGame` — deal / play (reusing `validate.ts`) / pass / exchange / resign, scoreless(6) + out-of-tiles end, end-of-game rack penalties, winner; mirrors `game.go`. End-game math exported as pure functions, pinned vs the Go engine (`engine.parity.test.ts`, 9 constructed positions). - `engine.test.ts`: a full-loop smoke — two robots play a whole vs_ai game to completion via `generateMoves`+`decide`, reproducible from the seed. - backend: `movegen` now dumps the per-variant rulesets; a new in-package engine emitter (`endfixture_test.go`, env-gated) produces the end-game golden. Pure additive library code; no runtime behavior change (unused at runtime, bundle unchanged). Local verify green: backend build/vet/gofmt/test; UI check + test:unit (450 passed) + build.
developer added 1 commit 2026-07-06 06:02:26 +00:00
feat(offline): local game engine (Phase B1)
CI / changes (pull_request) Successful in 1s
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 1m39s
e4cf143e9f
The offline vs_ai game engine — a faithful TS port of backend/internal/engine that
drives a whole local game with no backend. Composes with the move generator (#188) and
robot strategy (#189) from Phase A; not yet wired into the UI (Phase B2/B3).

- ui/src/lib/localgame/ruleset.ts: static per-variant tile values / bag counts / blank
  count, mirrored from rules.go (offline scoring is self-contained; online uses the
  server alphabet). Pinned by ruleset.parity.test.ts against a Go fixture.
- bag.ts: the tile bag (fill from counts/blanks, draw-from-end, return+reshuffle) on a
  deterministic in-house PRNG — a game replays from its seed, not bit-identical to a
  server game (per plan).
- board.ts: the mutable board, satisfying the validator/generator read view + set().
- engine.ts: LocalGame — deal / play (reusing validate.ts) / pass / exchange / resign,
  scoreless(6) & out-of-tiles end detection, end-of-game rack penalties, winner; mirrors
  game.go. The end-game math is exported as pure functions, pinned against the Go engine
  (engine.parity.test.ts, 9 constructed positions).
- engine.test.ts: a full-loop smoke — two robots play a whole vs_ai game to completion
  via generateMoves + decide, and it is reproducible from the seed.
- backend: movegen now dumps the per-variant rulesets; a new in-package engine emitter
  (endfixture_test.go, env-gated) produces the end-game golden.

Pure additive library code; no runtime behavior change (unused at runtime, bundle unchanged).
owner approved these changes 2026-07-06 06:15:38 +00:00
developer merged commit afa44d41b4 into development 2026-07-06 06:15:56 +00:00
developer deleted branch feature/offline-localgame-engine 2026-07-06 06:15:56 +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#191