# Sudoku Lanterns: training and evaluation

This game’s policy was actually fitted with **`pytoolz.wsrf.WSRFRegressor`**. It evaluates each available action separately and chooses the greatest estimated value. Training is supervised regression; a simulation or explicit puzzle/music/clue objective supplies the targets. This is not online browser training or a claim of general reasoning.

## What was learned

A verified-deduction ranking score: progress, newly available deductions, how many peer candidates a placement removes, preference for naked singles, and completing a row. These are one-move structural targets, not a learned proof generator. The rule engine supplies only logically forced naked or hidden singles. WSRF chooses their order. All policies restricted to those verified moves finish these easy puzzles; equal 46-move completion is expected and does not establish WSRF superiority.

The prepared pools contain 80 training, 24 validation, 64 test, and 32 public-play puzzles. Each removed clue is accepted only while the grid solves entirely through forced singles; a completed forced path proves uniqueness. Test puzzle grids are disjoint from training grids. Actual `pytoolz.wsrf_spn` writes and parses [the example path](training/example.spn), and parses the browser’s exported notation; see [the SPN receipt](training/spn-report.json). Manual entries are also restricted to verified singles. This edition does not implement candidate eliminations, arbitrary guesses, or advanced Sudoku variants.

Inputs, in order: `naked single, row blanks, column blanks, box blanks, affected candidates, available deductions, remaining squares, digit, row position, column position, prefer singles, prefer rows`. The browser uses the same feature code and action-availability rules as the Node simulation. The active condition chooses the `calm` or `challenge` ensemble. Unavailable actions are excluded before ranking. World updates, animations, rules, and opponent logic are coded separately from fitted forest inference.

## Training procedure

`pt.indexrng.Index("academy-eight-v2", backend="blake2b")` generates reproducible named streams for 64 initial training episodes, 16 recovery-training episodes, 16 validation episodes, 64 test episodes, and 32 guided test episodes. Initial training trajectories include a seeded exploratory move every seventh turn. The early model has 8 trees per zone and maximum depth 10. Its guided recovery trajectories are relabeled with the same target calculation and added before a refit with 24 trees per zone and depth 18. This release selected **final**, with **53,443 training action rows** and **48 total trees**.

Both candidates play the same validation seeds. Selection maximizes wins or draws, then musical quality where applicable, then minimizes mean turns. A complete tie retains the later refit. The test split is measured afterward; model fitting never uses it. The namespace was changed for the release evaluation after initial development checks. Episode seeds are independent; some small games can still revisit the same underlying states.

Parameters include minimum leaf size 2, all features available, random seed 2026, one training worker, no adaptive complexity, zero zone-prior weight, and no calibration. Full parameters are recorded in [report.json](training/report.json). Every fitted tree is exported, with float32 input traversal to match Python’s decision trees.

## Measured results

| Policy | Wins | Mean turns | Mean harmony score |
| --- | --- | --- | --- |
| Early model | 64/64 | 46.00 | — |
| Selected model | 64/64 | 46.00 | — |
| Selected model, guided | 32/32 | 46.00 | — |
| Reference strategy | 64/64 | 46.00 | — |
| Seeded random legal moves | 64/64 | 46.00 | — |

Guided episodes change priority and conditions every five turns. Mean turns includes failures, so a quickly lost game is not a faster success. For Lantern Tactics, a win means the learned golden side wins, and the report also records draws. Other games use their explicit completion goal. Random legal moves are sampled deterministically from qrand using the episode seed and turn. Reference-strategy results are strong baselines, not a guarantee that the learned policy will beat them.

Held-out action-value mean absolute error: **0.219405**. R²: **0.675073**. These describe the training objective’s numerical targets, not a probability of winning. Python and browser predictions matched within `1e-9` on **354,154 cases**, including held-out visited states and float32 neighbors around learned thresholds. Observed maximum absolute error: `0`. The fixtures are in [validation.json](training/validation.json).

The early forest is retained as `early-forest.json`. The optional brain panel compares early and selected policies on exactly the same current board, shows actual features, and traces one tree while explaining that all trees contribute to the final estimate. A priority comparison reruns inference on the same state with balanced priorities. It does not mutate the board. Decision replay stores real before/after states; continuing from a past decision creates a new branch of the current playthrough.

## Reproduction and provenance

Recorded environment: numpy 2.5.2, pandas 3.0.5, scikit-learn 1.9.0, python 3.14.4, wsrf 8.0.0. The WSRF implementation used was `/home/wiliamrocha/CelestialsPartDeux/wsrf-lib/src/wsrf/regressor.py`. The report preserves source hashes for the estimator, data generator, training script, game rules, shared model interpreter, and prepared library data. Selected model SHA-256: `bdfd6d2325e834baae5abd69fdc107829d23553c0d9aed5166ee01da78b2b7a9`.

From the source arcade root, using the local Python environment with pytoolz and its WSRF packages available:

```sh
/home/wiliamrocha/.spenv/bin/python -B tools/academy/prepare.py
/home/wiliamrocha/.spenv/bin/python -B tools/academy/parity.py
/home/wiliamrocha/.spenv/bin/python -B tools/academy/train.py --game sudoku-lanterns
node tools/academy/validate.cjs games/sudoku-lanterns/forest.json games/sudoku-lanterns/training/validation.json
npm run test:academy
npm run test:academy:browser
npm run build
```

Use `--game all` for all eight models. `prepare.py` uses real `rail_walk`, `ruler`, `ntcomb.submasks`, `tri_xor.evolve`, and `indexrng` calls. Existing checked qrand browser arithmetic generates reproducible game variations. `parity.py` uses real `wsrf_hlib.P2Frame` and `ParityDetector`. Sudoku path validation uses real `wsrf_spn`. The prepared mathematics has its own [source receipt](../../tools/academy/math-report.json).

Normal static builds use the committed fitted models and fixtures. Netlify needs the whole `dist/` folder, including shared scripts; it needs no Python runtime, account service, or external model API. Browser tests use Chrome at phone, tablet, and desktop sizes; physical-device testing is a separate check.
