Reports · 2026-09-19
A one or two strategy opponent portfolio beats full KLUSS at equal budget, and still loses to expectimax
Opponent-limited subgame solving against full KLUSS by budget
- olss2 n=1 v kluss
- olss2 n=2 v kluss
- olss2 n=2 v expectimax
| Series | budget (ms per move) | effective score |
|---|---|---|
| olss2 n=1 v kluss | 50 | 0.61 |
| olss2 n=2 v kluss | 50 | 0.605 |
| olss2 n=2 v kluss | 200 | 0.62 |
| olss2 n=2 v kluss | 1000 | 0.55 |
| olss2 n=2 v expectimax | 200 | 0.38 |
The searcher is the kluss crate of the previous study with mode set
to olss2 (OLSS-II, Liu et al. 2023, Figure 3 right): the opponent no
longer plays freely in the subgame but chooses one of N whole-game
strategies at a single CFR decision node at the root, and below the root
every opponent node plays the chosen strategy as a chance node. The
opponent's information sets collapse into that one choice, so the tree
holds only the searcher's information sets, and with N of one it is a
single-agent expectimax over the sampled worlds; a test in
crates/solve/tests/solve.rs checks the reduction against a reference
backup on a small position, and two more pin determinism and the
information boundary. The portfolio members act on the observation the
opponent would have at the node: greedy, a cheap expectimax, and
self, the searcher's own one-ply leaf policy at a temperature. The
full parameter list is in server/docs/search.md.
Calibration and cost
Each cell pairs equal bench cost, one thread on twenty middlegame positions. Measured on the idle machine at the end of the study: kluss reads 53 ms at 2,500 expansions, 139 ms at 5,000 and 467 ms at 10,000; olss2 with the two-strategy portfolio reads 51 ms at 5,000, 160 ms at 10,000 and 770 ms at 20,000, and olss2 with the greedy member alone reads 41 ms at 5,000. The olss2 tree grows several plies deep because every opponent ply is a single-child chance node, and the deep tree makes each CFR sweep dearer as the budget grows: the cost rises from 160 ms at 10,000 expansions to 8.1 s at 40,000 under the load of the study's runs. In the arena the cells measured 116 to 133 ms per move at the 50 ms calibration, 388 to 490 ms at 200 ms, and 1,798 to 2,812 ms at 1 s for the two searchers, against expectimax's 8.4 ms; the in-game cost runs about twice the bench figure, as it did for kluss. The 1 s cell was calibrated under load (818 ms against 848 ms on the bench at the time); on the idle machine its two sides read 467 and 770 ms, so that cell's nominal budget is looser than the smaller cells' and favours the olss2 side.
What the games show
Five cells, all under the training rules, the olss2 player always contestant zero. Games end almost entirely by Flag capture (191 of 200, 195, 190, 94 of 100 and 192 respectively, the rest with a side out of moves) and last 147 to 197 plies on average: ordinary Stratego, not stalling.
| cell | budget | opponent | games | effective | 95% Wilson | contrast | 95% interval |
|---|---|---|---|---|---|---|---|
| N=1 | 50 ms | kluss | 200 | 0.610 | 0.541 to 0.675 | 0.220 | 0.066 to 0.374 |
| N=2 | 50 ms | kluss | 200 | 0.605 | 0.536 to 0.670 | 0.210 | 0.064 to 0.356 |
| N=2 | 200 ms | kluss | 200 | 0.620 | 0.551 to 0.684 | 0.240 | 0.085 to 0.395 |
| N=2 | 1 s | kluss | 100 | 0.550 | 0.452 to 0.644 | 0.100 | minus 0.111 to 0.311 |
| N=2 | 200 ms | expectimax | 200 | 0.380 | 0.316 to 0.449 | minus 0.240 | minus 0.390 to minus 0.090 |
Three readings. First, limiting the opponent pays at equal budget: N of
one and N of two are indistinguishable at 50 ms (0.610 against 0.605),
so the gain comes from turning the subgame single-agent, not from
covering more opponent styles, and the diagnostic trace agrees: the
solved opponent mixture on twenty middlegame positions at the 200 ms
calibration puts 92% on greedy and 8% on self at temperature 0.3,
and the purified root keeps a single action. Second, the margin narrows
as the budget grows (0.220, 0.240, then 0.100 with the interval covering
zero), so a crossing plausibly sits above 1 s, where both searchers'
cost curves turn sharply superlinear; measuring it costs about four
hours of arena time per cell and is left registered-ready as the next
step. Third, the portfolio closes only part of the gap to plain search:
full kluss scored 26.8% against expectimax at this budget, the portfolio
player scores 38.0%, and expectimax at 8 ms per move remains the top of
the measured ladder.
For the theory this splits two claims. The mechanism of T2 is confirmed here: at every budget where both were measured, the opponent-limited subgame beats the free-opponent subgame at equal cost, and one or two strategies suffice, as Liu et al. found in Mahjong. The theory as a route to a stronger player fails at these budgets all the same: the portfolio player loses to the same expectimax that beat full kluss, and the log's disproof condition (a loss to plain expectimax) is met. The binding constraint is not the opponent model but what both kluss-mode searches share, the shallow tree over 64 worlds with the hand-written leaf.
What this means for the belief study and the ladder
The opponent portfolio is the right shape for a better leaf or belief:
it spends its budget on depth instead of on defending against every
opponent at once, and the portfolio parameter admits the cheap
expectimax member (about 25 times the greedy member per call) at
budgets that can afford it. The natural next registration is olss2 with
greedy, expectimax and self at the 1 s budget against expectimax
itself, with the scaled run's belief sampler when it exists. OLSS-I (the
non-uniform root weighting) was not implemented; with the root sample
already drawn from the counting belief and the opponent restricted, the
weighting is a smaller lever than the portfolio width.
Run records: N=1 at 50 ms, N=2 at 50 ms, N=2 at 200 ms, N=2 at 1 s and against expectimax.
Reproduction
Registrations experiments/2436cdbe-9447-4d1a-90d3-e85b8da1393d.toml,
experiments/81e925ab-4584-4bd4-b62a-f0869ac13125.toml,
experiments/092a047f-bad7-4d56-98f0-5e28094c6ec9.toml,
experiments/c8ba64ba-05df-4d3b-bbca-cdd7cb9556e8.toml and
experiments/4ffa3c2f-c818-4d24-828a-b3d8fc49d73f.toml. Commands, from the repository root:
cd server && cargo run --release -p armies-solve --bin bench -- --params '{"mode":"olss2","samples":64,"cfr_every":64,"portfolio":[{"policy":"greedy"},{"policy":"self","parameters":{"temperature":0.3}}]}' --expansions 5000,10000,20000
cd server && cargo run --release -p armies-solve --bin trace -- --params '{"mode":"olss2","samples":64,"cfr_every":64,"portfolio":[{"policy":"greedy"},{"policy":"self","parameters":{"temperature":0.3}}]}' --expansions 10000
cd server && cargo run --release -p armies-arena --bin matchup -- --red 'olss2 n2 200ms=kluss:{"mode":"olss2","samples":64,"expansions":10000,"cfr_every":64,"portfolio":[{"policy":"greedy"},{"policy":"self","parameters":{"temperature":0.3}}]}' --blue 'kluss 200ms=kluss:{"samples":64,"shadows":4,"expansions":5000,"cfr_every":64}' --games 200 --seed 0 --rules training --threads 8 --record-dir ../research/runs/092a047f-bad7-4d56-98f0-5e28094c6ec9/records --out ../research/runs/092a047f-bad7-4d56-98f0-5e28094c6ec9/matchup.json --tag 092a047f-bad7-4d56-98f0-5e28094c6ec9
cd research && python3 scripts/build_portfolio_assets.pyThe other four cells differ only in the contestants' parameters and the game count; the exact commands are in the five run records. The matches took 593 s, 657 s, 2,220 s, 5,553 s and 1,294 s of wall time on 8 threads. Each record carries the SHA-256 of its JSON output.