# Distance Draw — actual pytoolz / WSRF training

Three trained advisers serve Distance Draw, River School, and Pocket Studio. The latter two reuse Sage’s model; they do not claim separate training runs. The forests estimate **showdown pot share against uniformly random opponent cards**, with all remaining board cards dealt. Targets count a win as 1, a tie as 0.5, and a loss as 0.

Training uses the installed `pytoolz.wsrf.WSRFRegressor` (WSRF 8.0.0) and `pytoolz.indexrng.Index` seed streams. The deployed site runs the complete exported trees through `shared/academy-forest.js`; it needs no Python service or external API.

## Data and validation

- 16,000 training states × 384 simulated completions = 6,144,000 training rollouts. Equal preflop, flop, turn, and river coverage.
- 1,024 separate validation states × 1,024 completions. Model sizes were fixed in advance; test results were not used to select a winner.
- 2,048 untouched test states × 2,048 completions. Separate `train`, `validation`, `test`, and `match-test` streams in `distance-draw-training-v1`.
- Average Monte Carlo standard error of test labels: 0.950 percentage points. Those labels are estimates, so prediction error includes label noise.
- 551,213 Python/browser prediction fixtures, including float32 neighbors around every learned branch threshold. All match within 1e-10.

| Adviser | Training states | Trees | Held-out MAE |
| --- | ---: | ---: | ---: |
| gentle | 2,400 | 32 | 4.166 percentage points |
| table | 8,000 | 64 | 2.749 percentage points |
| sharp | 16,000 | 96 | 2.228 percentage points |
| no-distance | 16,000 | 96 | 2.092 percentage points |

Each model has four explicit street zones. Robin has 8 trees per zone, Fern 16, and Sage 24. Full parameters, feature names, dependencies, source hashes, seed receipts, and all match results are in [report.json](training/report.json).

## What the bot learns, and what is explicit code

The **equity estimator is learned**. A published action policy separately compares its estimate with the cost of calling and configured raise thresholds. Robin explores alternative legal actions 22% of the time, Fern 6%, and Sage 0%; all three can make a small occasional bluff. These are intentionally different practice levels, not claims of optimal poker play. Caution nudges change policy thresholds, not the fitted estimate.

The model sees its own two cards and the revealed board. Its feature builder has no opponent hole cards, future deck, shuffle seed, or hidden game state. Action selection additionally sees legal actions and public betting amounts. Browser dealing uses `crypto.getRandomValues` with rejection-sampled Fisher–Yates; offline experiments use separate reproducible deck and policy streams. This is a local play-chip game, not a secure multiplayer server.

## Playing evaluation

Each matchup uses the same 512 fresh decks, played in both seats, with 40-big-blind starting stacks and no rake. A paired observation is the mean of the two seat results on one deck. Intervals use the sample SD of those observations divided by √512, then mean ± 1.96 SE. Each hand resets stacks. These are finite comparisons against these particular policies; they do not establish long-run profit against humans or GTO. The live 25/100/200-blind variations were tested for rules and browser behavior, not separately benchmarked for playing strength.

| Sage versus | Hands | BB / 100 | Approximate paired 95% interval |
| --- | ---: | ---: | --- |
| gentle | 1,024 | +33.20 | [+16.09, +50.32] |
| table | 1,024 | +9.18 | [+0.68, +17.68] |
| call | 1,024 | +53.52 | [+47.45, +59.58] |
| random | 1,024 | +368.65 | [+268.57, +468.74] |
| no-distance | 1,024 | -0.78 | [-2.16, +0.60] |

## Distance-map ablation

The `no-distance` forest uses the same 16,000 training states, targets, tree count, depth, random state, and action policy as Sage, with the 13 distance inputs removed. Sage has 35 inputs; the baseline has 22. **This experiment did not establish an extra playing edge from the distance features.** The baseline had slightly lower held-out equity error, and the paired playing interval includes zero. We publish that result alongside the map’s teaching value.

No target receives a handcrafted distance bonus. The guide’s historical profit multipliers and headline billions-of-hands figures were not used as labels or treated as verified results of this project.

## Mathematical compression and timing

The guide’s four reference ranks map the unseen deck into 0-away, 1-away, 2-away, and 3+-away groups. Exact remaining-card counts are shown, rather than fixed group percentages. Across all 1,326 physical starting pockets, the 0–1 group ranges from 20% to 92% of the 50 unseen cards, averaging 63.92%. Rank parity checks use the actual installed `wsrf.dograndom.distance.circular_distance` on all 169 rank pairs.

The map displays mean and SD of **rank distance in steps**. The brain displays **between-tree disagreement**. Match reports use **SD of paired chip results** and **standard error of their mean**. These are separate statistics. A grouped entropy is smaller because the representation discards card identity; the physical shuffle has not changed.

On `11th Gen Intel(R) Core(TM) i9-11900H @ 2.50GHz`, Node v22.22.1, a warmed 256-state timing sample measured 0.024 ms per Sage estimate (feature generation included), 0.013 ms without distance inputs, and 1.666 ms for a fresh 2,048-completion Monte Carlo estimate. This is a single-host timing, not a performance guarantee. The speed comparison is **trained approximation versus fresh simulation**, not proof that the distance map alone accelerates or improves poker decisions. See [benchmark.json](training/benchmark.json).

## The two challenge games

River School scores each challenge with exact enumeration: 990 possible opposing pockets on the river, or 45,540 opponent/runout outcomes on the turn. Its final-call exercise explicitly assumes no more betting and a uniform opponent; call EV is equity × (pot + call) − call. Wins, ties, and losses all count.

Pocket Studio compares all 15 pockets from six offered cards. Unchosen cards return to the unseen deck, so the model and exact scorer have the same card-removal assumptions. River, turn, and weakest-pocket variations share the trained adviser. Exact enumeration supplies the answer after the choice; the optional brain uses only the forest estimate. Hints and pre-answer brain inspection mark a round as assisted.

## Reproduce

```sh
/home/wiliamrocha/.spenv/bin/python -B tools/poker/train.py
node tools/poker/benchmark.cjs
python3 -B tools/poker/document.py
node tools/test-poker-rules.cjs
node tools/test-poker-models.cjs
```

Training requires the local pytoolz/WSRF installation. Tests and deployment use the saved model files. Training caches are omitted from `dist/`; recipes, measured reports, tests’ reference data, and compressed parity fixtures are retained. The immutable source receipts make later code changes detectable.

Rules checks enumerate all 2,598,960 five-card hands, compare 9,000 best-five evaluations with an independent evaluator, and finish 10,000 randomized legal heads-up hands with chip-conservation checks. Model tests replay all 5,120 held-out match hands. Browser tests cover all levels and variations, illegal raises, hidden inputs, actual tree inspection, pause/watch behavior, storage failure, and phone/desktop layout.
