feat(robot): occasional off-strategy deviation, strict in the endgame #69

Merged
developer merged 1 commits from feature/ai-strategy-deviation into development 2026-06-15 19:49:28 +00:00
Owner

What

The honest/disguised robot followed its per-game playToWin/lose intent on every
move, making the outcome too predictable. It now flips that intent for a single move
on ~20% of opening/midgame turns (a winning robot eases off, a losing one surges
ahead), so the chosen strategy may not pan out — which favours the human.

The deviation chance tapers linearly to 0 over the last 14 tiles in the bag and is
0 once the bag is empty, so the endgame follows the chosen strategy strictly.

How

  • deviateProb(bagLen) / deviates(seed, moveCount, bagLen) in robot/strategy.go
    deterministic per-turn draw (mix(seed,"deviate",moveCount)), reproducible across
    restarts like the rest of the seed-derived behaviour.
  • act() flips playToWin(seed) for the move when deviates fires, before the existing
    selectMove — so it reuses the margin-band logic and applies to both robot paths.
  • selectMove stays a pure function of its inputs; the per-game intent (admin card) is
    unchanged.

Tests

robot unit: taper bounds + monotonicity, never-in-endgame, determinism, ~20% rate.
Local gate green: gofmt/vet/build, all backend unit tests, full backend
integration suite (CI parity, inttest incl. the AI-game tests).

Docs (same PR)

docs/ARCHITECTURE.md §7, docs/FUNCTIONAL.md (+_ru), backend/README.md,
PRERELEASE.md (AI follow-up), PLAN.md Stage 5.

## What The honest/disguised robot followed its per-game `playToWin`/lose intent on **every** move, making the outcome too predictable. It now flips that intent for a **single move** on **~20%** of opening/midgame turns (a winning robot eases off, a losing one surges ahead), so the chosen strategy may not pan out — which favours the human. The deviation chance **tapers linearly to 0 over the last 14 tiles in the bag** and is **0 once the bag is empty**, so the endgame follows the chosen strategy strictly. ## How - `deviateProb(bagLen)` / `deviates(seed, moveCount, bagLen)` in `robot/strategy.go` — deterministic per-turn draw (`mix(seed,"deviate",moveCount)`), reproducible across restarts like the rest of the seed-derived behaviour. - `act()` flips `playToWin(seed)` for the move when `deviates` fires, before the existing `selectMove` — so it reuses the margin-band logic and applies to **both** robot paths. - `selectMove` stays a pure function of its inputs; the per-game intent (admin card) is unchanged. ## Tests `robot` unit: taper bounds + monotonicity, never-in-endgame, determinism, ~20% rate. Local gate green: `gofmt`/`vet`/`build`, all backend unit tests, full backend integration suite (CI parity, `inttest` incl. the AI-game tests). ## Docs (same PR) `docs/ARCHITECTURE.md` §7, `docs/FUNCTIONAL.md` (+`_ru`), `backend/README.md`, `PRERELEASE.md` (AI follow-up), `PLAN.md` Stage 5.
developer added 1 commit 2026-06-15 19:37:41 +00:00
feat(robot): occasional off-strategy deviation, strict in the endgame
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 9s
CI / integration (pull_request) Successful in 13s
CI / ui (pull_request) Has been skipped
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m9s
3bceafbc12
The robot followed its per-game playToWin/lose intent on every move, which made
the outcome too predictable. It now flips that intent for a single move on ~20%
of opening/midgame turns (a winning robot eases off, a losing one surges ahead),
so the chosen strategy may not pan out — which favours the human. The chance
tapers linearly to 0 over the last 14 tiles in the bag and is 0 once the bag is
empty, so the endgame follows the chosen strategy strictly.

The decision is deterministic from the seed (mix(seed,"deviate",moveCount)) and
applies to both robot paths via the shared selectMove; the per-game play-to-win
intent the admin card shows is unchanged. Adds deviateProb/deviates helpers and
unit tests (taper bounds + monotonicity, never-in-endgame, determinism, ~20%
distribution); bakes the behaviour into ARCHITECTURE §7, FUNCTIONAL (+_ru),
backend/README, PRERELEASE and PLAN Stage 5.
owner approved these changes 2026-06-15 19:49:08 +00:00
developer merged commit f59c8dcd43 into development 2026-06-15 19:49:28 +00:00
developer deleted branch feature/ai-strategy-deviation 2026-06-15 19:49:28 +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#69