Lookup tables as the leaf of the search
Four registered screens on fresh seeds
Measured evidenceScroll the chart horizontally to inspect all values.
Paired per-seed win difference, tables minus hand-written leaf, with 95% intervals over 64 fresh deterministic seeds (256 games per screen). Each screen seats the frozen tables in slot 0 and the hand-written leaf in slot 1 with an ETA and a fast builder; d1, d2, d3 are planned turns, and the depth-3 seats run under a 1.5 s budget.
Source: Engine-arena runs 09fb758b, d249aa28, 169b0772, ec904c96 (registrations ea8af9cc, 6a712b5a, 9ed38762, acf5812a).
View data table
| Series | Comparison | Wins per game, tables minus hand-written leaf | Low | High |
|---|---|---|---|---|
| Paired seed contrast | tables d2 vs hand d2 | 0.2188 | 0.1239 | 0.3136 |
| Paired seed contrast | tables d1 vs hand d2 | 0.1641 | 0.0581 | 0.27 |
| Paired seed contrast | tables d2 vs hand d3 | 0.1562 | 0.0507 | 0.2618 |
| Paired seed contrast | tables d3 vs hand d3 | 0.2422 | 0.1398 | 0.3445 |
Pilot: which pattern families make a leaf
Measured evidenceScroll the chart horizontally to inspect all values.
Each arm trained for eighteen minutes of wall time (20,000 builder warm-up games then about 44,000 self-play games on 32 threads) and was then played as the depth-2 leaf against the hand-written leaf in the same search, with an ETA and a fast builder, on 24 fixed deterministic seeds in every rotation (96 games). Bars are the paired per-seed margin with a normal-approximation 95% interval. These games chose the layout and cannot confirm it.
Source: Training runs under runs/ntuple/; the last validation tournament of each arm (24 fixed deterministic seeds, four rotations, depth 2, hand-written leaf in slot 1, ETA and fast builders).
View data table
| Series | Layout | Wins per game, tables minus hand leaf | Low | High |
|---|---|---|---|---|
| Validation margin after the pilot budget | hex + portfolio | 0.3021 | 0.1406 | 0.4636 |
| Validation margin after the pilot budget | hex + vertex + portfolio | 0.2708 | 0.115 | 0.4267 |
| Validation margin after the pilot budget | portfolio only | 0.2083 | 0.056 | 0.3606 |
| Validation margin after the pilot budget | full, no point reward | 0.1875 | -0.0297 | 0.4047 |
| Validation margin after the pilot budget | vertex + portfolio | -0.125 | -0.3272 | 0.0772 |
| Validation margin after the pilot budget | hex + vertex | -0.1771 | -0.326 | -0.0282 |
Why a learned leaf
Every planned turn of expectimax-v2 ends by asking a leaf how good the
position is, and the ablations showed that the search's
lookahead and dice scenarios matter far more than any single hand-written term.
The Drop7 n-tuple tables
suggested the other route: keep the search, and replace the leaf with numbers
learned from play. A lookup table can hold a distinct number for every small
pattern the board can show, so it can learn that a city on a five-pip ore hex is
worth more than its production rate says, or that a particular hand and building
count is a dead end, without anyone writing the rule down.
What the tables read
Each position is read from one seat's point of view through three families of windows, and every window reads only what that seat can see in a sampled world: the board and layout, its own hand and development cards, and public counts.
| Family | Windows per position | Pattern | Entries |
|---|---|---|---|
| Hex | 19 | Resource, pips, robber, and the six corners (empty, own settlement, own city, other settlement, other city), canonical under the hex's twelve symmetries | 1,125,000 |
| Intersection | 54 | The three touching hexes as a sorted triple, the building or blocked state, own and foreign road adjacency, the port | 8,509,704 |
| Portfolio | 5 | Production pips per resource; hand, hand total, settlements and cities left; own and the two best opponent scores with the turn; knights, cards, army and road holders, own trail, roads left, deck; largest opponent hand, opponent production, opponent count, own production, best opponent | 2,456,718 |
The value is the sum of the looked-up entries, in win-probability units. A hex window is shared by all nineteen hexes and an intersection window by all fifty-four corners, so one entry can be active several times in a position; the learning step weights each entry by that multiplicity. Inside the search the sum is scaled by 1,000 so that one win equals ten points on the hand-written currency, and nothing else changes: the same turn planner, the same opponents' round under common random scenarios, the same iterative deepening.
How the tables learn
Thirty-two threads play self-play games on shared tables without locks. Every seat plans its turn with the depth-1 search over the tables on the true state; the leaf never sees a hidden hand, so the tables cannot learn from information a seated player would not have. At game end each seat's chain of end-of-turn positions is updated backward with TD(λ = 0.7) toward 1 for the winner and 0 for everyone else, plus 0.05 per point gained, with temporal-coherence step sizes that shrink once an entry's errors stop pointing the same way.
Blank tables cannot finish a game: every candidate looks equally good, nobody builds, every game reaches the turn cap, and the tables learn that everything is worth zero. The first 20,000 games are therefore played by the fast builder for every seat while the tables watch, at 15,000 games per second. Self-play then runs at 45 to 65 games per second, and every chunk the frozen tables play a validation tournament as the depth-2 leaf against the hand-written leaf in the same search with an ETA and a fast builder on fixed deterministic seeds. The validation point with the largest paired margin is the candidate.
The pilot
Six layouts trained for eighteen minutes of wall time each, 20,000 builder games and about 44,000 self-play games, and were validated on 24 seeds in every rotation (96 games). The margin is the per-seed difference in wins between the tables and the hand-written leaf.
| Layout | Tables wins | Hand wins | ETA | Fast | Margin (95% interval) |
|---|---|---|---|---|---|
| hex + portfolio | 56 | 27 | 5 | 8 | +0.302 (+0.141 to +0.464) |
| hex + intersection + portfolio | 49 | 23 | 14 | 10 | +0.271 (+0.115 to +0.427) |
| portfolio only | 43 | 23 | 14 | 16 | +0.208 (+0.056 to +0.361) |
| full layout, no point reward | 47 | 29 | 12 | 8 | +0.188 (−0.030 to +0.405) |
| intersection + portfolio | 33 | 45 | 9 | 9 | −0.125 (−0.327 to +0.077) |
| hex + intersection, no portfolio | 26 | 43 | 14 | 13 | −0.177 (−0.326 to −0.028) |
Two readings are clear even at this budget. The portfolio tables carry the mechanism: without them the board windows alone lose to the hand-written leaf, and alone they already beat it. The hex windows add to the portfolio tables, while the intersection windows, with eight and a half million entries and only tens of thousands of games, add noise. Every arm was still improving at its last validation point. The point reward helped the full layout by a margin inside the noise. The main run trains hex plus portfolio from scratch under a three-hour wall with a plateau rule.
Compact records of every arm (configuration, progress rows, validation
summaries, stop reason) are under records/training/ntuple-pilot/.
The main run
Hex plus portfolio tables trained again from scratch on 32 threads: 20,000 builder games, then self-play at about 44 games per second, validated every 32,000 games on 32 fixed deterministic seeds in every rotation (128 games) as the depth-2 leaf against the hand-written leaf with the two builders, and played one ply in a second tournament. The run stopped on its plateau rule after eight validation points, 256,000 games and 1 hour 50 minutes of wall time, when the mean margin of the last three points (+0.245) was no longer above the mean of the three before (+0.333).
Main run: the tables against the hand-written leaf as training proceeds
Measured evidenceScroll the chart horizontally to inspect all values.
Hex plus portfolio tables trained from scratch: 20,000 builder warm-up games, then self-play on 32 threads at about 44 games per second. Every 32,000 games the frozen tables played 128 deterministic games (32 fixed seeds, every rotation) as the depth-2 leaf against the hand-written leaf in the same search with an ETA and a fast builder; the second series plays the same tables one ply with no search. Bands are normal-approximation 95% intervals of the paired per-seed margin. The run stopped on its plateau rule after eight points; the point at 96,000 games, the largest margin, is the frozen candidate.
Source: Training run runs/ntuple/main; every validation point is a tournament on fixed deterministic seeds against the hand-written leaf in the same search with the two builders.
View data table
| Series | Self-play games trained (thousands) | Wins per game, tables minus hand leaf | Low | High |
|---|---|---|---|---|
| Tables as the depth-2 leaf | 32 | 0.1562 | 0.0074 | 0.3051 |
| Tables as the depth-2 leaf | 64.1 | 0.1797 | 0.0253 | 0.3341 |
| Tables as the depth-2 leaf | 96.1 | 0.375 | 0.221 | 0.529 |
| Tables as the depth-2 leaf | 128.1 | 0.3047 | 0.1527 | 0.4567 |
| Tables as the depth-2 leaf | 160.2 | 0.3203 | 0.1659 | 0.4747 |
| Tables as the depth-2 leaf | 192.2 | 0.2734 | 0.1337 | 0.4132 |
| Tables as the depth-2 leaf | 224.2 | 0.1406 | -0.0311 | 0.3124 |
| Tables as the depth-2 leaf | 256.2 | 0.3203 | 0.174 | 0.4666 |
| Tables played one ply | 32 | 0.0078 | ||
| Tables played one ply | 64.1 | 0.0547 | ||
| Tables played one ply | 96.1 | 0.1094 | ||
| Tables played one ply | 128.1 | 0.125 | ||
| Tables played one ply | 160.2 | 0.1328 | ||
| Tables played one ply | 192.2 | 0.1406 | ||
| Tables played one ply | 224.2 | 0.1328 | ||
| Tables played one ply | 256.2 | 0.1953 |
Main run: who wins the validation games
Measured evidenceScroll the chart horizontally to inspect all values.
Share of the 128 validation games won by each slot at every validation point of the main run. The tables and the hand-written leaf play the same depth-2 search; the builders are the fixed ETA and fast policies.
Source: Training run runs/ntuple/main; per-slot win share of each validation tournament.
View data table
| Series | Self-play games trained (thousands) | Share of validation games won |
|---|---|---|
| Tables as the depth-2 leaf | 32 | 0.4766 |
| Tables as the depth-2 leaf | 64.1 | 0.4688 |
| Tables as the depth-2 leaf | 96.1 | 0.6094 |
| Tables as the depth-2 leaf | 128.1 | 0.5547 |
| Tables as the depth-2 leaf | 160.2 | 0.5938 |
| Tables as the depth-2 leaf | 192.2 | 0.5234 |
| Tables as the depth-2 leaf | 224.2 | 0.4609 |
| Tables as the depth-2 leaf | 256.2 | 0.5859 |
| Hand-written leaf, depth 2 | 32 | 0.3203 |
| Hand-written leaf, depth 2 | 64.1 | 0.2891 |
| Hand-written leaf, depth 2 | 96.1 | 0.2344 |
| Hand-written leaf, depth 2 | 128.1 | 0.25 |
| Hand-written leaf, depth 2 | 160.2 | 0.2734 |
| Hand-written leaf, depth 2 | 192.2 | 0.25 |
| Hand-written leaf, depth 2 | 224.2 | 0.3203 |
| Hand-written leaf, depth 2 | 256.2 | 0.2656 |
| ETA builder | 32 | 0.1172 |
| ETA builder | 64.1 | 0.1562 |
| ETA builder | 96.1 | 0.1094 |
| ETA builder | 128.1 | 0.1172 |
| ETA builder | 160.2 | 0.0859 |
| ETA builder | 192.2 | 0.1406 |
| ETA builder | 224.2 | 0.0859 |
| ETA builder | 256.2 | 0.0625 |
| Fast builder | 32 | 0.0859 |
| Fast builder | 64.1 | 0.0859 |
| Fast builder | 96.1 | 0.0469 |
| Fast builder | 128.1 | 0.0781 |
| Fast builder | 160.2 | 0.0469 |
| Fast builder | 192.2 | 0.0859 |
| Fast builder | 224.2 | 0.1328 |
| Fast builder | 256.2 | 0.0859 |
| Games trained | Tables wins | Hand wins | ETA | Fast | Margin (95% interval) | One ply, tables wins | Entries touched |
|---|---|---|---|---|---|---|---|
| 32,031 | 61 | 41 | 15 | 11 | +0.156 (+0.007 to +0.305) | 47 | 306,764 |
| 64,062 | 60 | 37 | 20 | 11 | +0.180 (+0.025 to +0.334) | 51 | 429,628 |
| 96,093 | 78 | 30 | 14 | 6 | +0.375 (+0.221 to +0.529) | 54 | 504,727 |
| 128,124 | 71 | 32 | 15 | 10 | +0.305 (+0.153 to +0.457) | 57 | 558,302 |
| 160,155 | 76 | 35 | 11 | 6 | +0.320 (+0.166 to +0.475) | 56 | 599,345 |
| 192,186 | 67 | 32 | 18 | 11 | +0.273 (+0.134 to +0.413) | 60 | 631,971 |
| 224,217 | 59 | 41 | 11 | 17 | +0.141 (−0.031 to +0.312) | 58 | 659,822 |
| 256,248 | 75 | 34 | 8 | 11 | +0.320 (+0.174 to +0.467) | 65 | 683,529 |
Every point beat the hand-written leaf inside the same search, and the point
at 96,093 games, with the largest margin, is the frozen candidate
(artifacts/ntuple/hex-portfolio-main.bin, SHA-256 f8e61e66…, receipt under
records/artifacts/). About half a million of the 3.6 million entries had
been touched by then. The margin on the validation seeds is noisy from point to
point, and choosing its maximum makes +0.375 an optimistic reading; the fresh
seeds below are the test. The tables played one ply, with no search at all,
improved at every point and won 65 of the last 128 games against a table where
the hand-written leaf searched two turns ahead; that arm is registered on fresh
seeds too.
What the tables learned
The hex table can be read directly. For a window holding exactly one own settlement and nothing else, the entry rises with the pips of the hex number on every resource, and ore and grain are worth most; a city is valued above a settlement on the same hex almost everywhere. No term for pips, resources, or cities was written down; the tables learned these from which positions went on to win.
What one settlement on a hex is worth, by resource and pips
Measured evidenceScroll the chart horizontally to inspect all values.
Darker cells mean higher Table entry (win-probability units): 0.0355–0.191. Blank cells have no value.
Entries of the frozen hex table for a window holding exactly one own settlement, no robber, and five empty corners, read straight from the candidate tables. Values are contributions to the win-probability sum and are comparable with one another, not absolute probabilities. Nobody told the tables that ore and grain matter or that pips do; they learned it from self-play.
Source: Frozen candidate tables artifacts/ntuple/hex-portfolio-main.bin (SHA-256 f8e61e66...), decoded by analysis/ntuple_inspect.py.
View data table
| Series | Pips of the hex number | Resource | Table entry (win-probability units) |
|---|---|---|---|
| Hex window value with one own settlement and empty corners | 1 | brick | 0.0381 |
| Hex window value with one own settlement and empty corners | 2 | brick | 0.0766 |
| Hex window value with one own settlement and empty corners | 3 | brick | 0.11 |
| Hex window value with one own settlement and empty corners | 4 | brick | 0.119 |
| Hex window value with one own settlement and empty corners | 5 | brick | 0.1374 |
| Hex window value with one own settlement and empty corners | 1 | lumber | 0.0412 |
| Hex window value with one own settlement and empty corners | 2 | lumber | 0.0509 |
| Hex window value with one own settlement and empty corners | 3 | lumber | 0.0814 |
| Hex window value with one own settlement and empty corners | 4 | lumber | 0.1008 |
| Hex window value with one own settlement and empty corners | 5 | lumber | 0.1158 |
| Hex window value with one own settlement and empty corners | 1 | wool | 0.0355 |
| Hex window value with one own settlement and empty corners | 2 | wool | 0.0495 |
| Hex window value with one own settlement and empty corners | 3 | wool | 0.0926 |
| Hex window value with one own settlement and empty corners | 4 | wool | 0.0945 |
| Hex window value with one own settlement and empty corners | 5 | wool | 0.1155 |
| Hex window value with one own settlement and empty corners | 1 | grain | 0.0441 |
| Hex window value with one own settlement and empty corners | 2 | grain | 0.0704 |
| Hex window value with one own settlement and empty corners | 3 | grain | 0.1114 |
| Hex window value with one own settlement and empty corners | 4 | grain | 0.1342 |
| Hex window value with one own settlement and empty corners | 5 | grain | 0.1535 |
| Hex window value with one own settlement and empty corners | 1 | ore | 0.0526 |
| Hex window value with one own settlement and empty corners | 2 | ore | 0.0873 |
| Hex window value with one own settlement and empty corners | 3 | ore | 0.142 |
| Hex window value with one own settlement and empty corners | 4 | ore | 0.1787 |
| Hex window value with one own settlement and empty corners | 5 | ore | 0.191 |
The same window with a city instead of a settlement
Measured evidenceScroll the chart horizontally to inspect all values.
Darker cells mean higher Table entry (win-probability units): 0.0386–0.2033. Blank cells have no value.
Entries of the frozen hex table for one own city with empty corners and no robber. A city doubles production, and the tables value it above a settlement on nearly every hex, most on ore and grain.
Source: Frozen candidate tables artifacts/ntuple/hex-portfolio-main.bin (SHA-256 f8e61e66...), decoded by analysis/ntuple_inspect.py.
View data table
| Series | Pips of the hex number | Resource | Table entry (win-probability units) |
|---|---|---|---|
| Hex window value with one own city and empty corners | 1 | brick | 0.0619 |
| Hex window value with one own city and empty corners | 2 | brick | 0.087 |
| Hex window value with one own city and empty corners | 3 | brick | 0.1578 |
| Hex window value with one own city and empty corners | 4 | brick | 0.1409 |
| Hex window value with one own city and empty corners | 5 | brick | 0.1677 |
| Hex window value with one own city and empty corners | 1 | lumber | 0.0386 |
| Hex window value with one own city and empty corners | 2 | lumber | 0.0728 |
| Hex window value with one own city and empty corners | 3 | lumber | 0.1111 |
| Hex window value with one own city and empty corners | 4 | lumber | 0.1267 |
| Hex window value with one own city and empty corners | 5 | lumber | 0.1389 |
| Hex window value with one own city and empty corners | 1 | wool | 0.0462 |
| Hex window value with one own city and empty corners | 2 | wool | 0.0771 |
| Hex window value with one own city and empty corners | 3 | wool | 0.1246 |
| Hex window value with one own city and empty corners | 4 | wool | 0.1476 |
| Hex window value with one own city and empty corners | 5 | wool | 0.1603 |
| Hex window value with one own city and empty corners | 1 | grain | 0.0534 |
| Hex window value with one own city and empty corners | 2 | grain | 0.0839 |
| Hex window value with one own city and empty corners | 3 | grain | 0.1294 |
| Hex window value with one own city and empty corners | 4 | grain | 0.1703 |
| Hex window value with one own city and empty corners | 5 | grain | 0.202 |
| Hex window value with one own city and empty corners | 1 | ore | 0.0724 |
| Hex window value with one own city and empty corners | 2 | ore | 0.1155 |
| Hex window value with one own city and empty corners | 3 | ore | 0.1525 |
| Hex window value with one own city and empty corners | 4 | ore | 0.1889 |
| Hex window value with one own city and empty corners | 5 | ore | 0.2033 |
The portfolio tables can be read the same way. The race table, in the mid-game turn bucket, rises steeply with own points and falls with the best opponent's: at eight points against an opponent on five the entry is +0.32, at four against eight it is −0.09. The hand table values every card above an empty hand, ore most (four ore +0.07 above nothing; four lumber +0.05). The production table's marginal effect is small: averaged over the profiles play reached, one more pip in any resource moves the entry by under 0.01, so the production signal lives in the hex windows, which see each building on its hex directly.
The race: own points against the best opponent
Measured evidenceScroll the chart horizontally to inspect all values.
Darker cells mean higher Table entry (win-probability units): -0.1709–0.4673. Blank cells have no value.
Entries of the race table in the mid-game turn bucket with the second opponent two points behind the best, from the frozen tables, over the score range play reaches there. Rows are own points, columns the best opponent's public points.
Source: Frozen candidate tables artifacts/ntuple/hex-portfolio-main.bin (SHA-256 f8e61e66...), decoded by analysis/ntuple_inspect.py.
View data table
| Series | Best opponent's public points | Own points | Table entry (win-probability units) |
|---|---|---|---|
| Race table entry, mid-game, second opponent two points behind the best | 4 | 2 | -0.1341 |
| Race table entry, mid-game, second opponent two points behind the best | 5 | 2 | -0.1595 |
| Race table entry, mid-game, second opponent two points behind the best | 6 | 2 | -0.1709 |
| Race table entry, mid-game, second opponent two points behind the best | 7 | 2 | -0.1475 |
| Race table entry, mid-game, second opponent two points behind the best | 8 | 2 | -0.0776 |
| Race table entry, mid-game, second opponent two points behind the best | 9 | 2 | 0.0292 |
| Race table entry, mid-game, second opponent two points behind the best | 4 | 3 | -0.0646 |
| Race table entry, mid-game, second opponent two points behind the best | 5 | 3 | -0.1149 |
| Race table entry, mid-game, second opponent two points behind the best | 6 | 3 | -0.1402 |
| Race table entry, mid-game, second opponent two points behind the best | 7 | 3 | -0.1439 |
| Race table entry, mid-game, second opponent two points behind the best | 8 | 3 | -0.0836 |
| Race table entry, mid-game, second opponent two points behind the best | 9 | 3 | 0.0146 |
| Race table entry, mid-game, second opponent two points behind the best | 4 | 4 | 0.0073 |
| Race table entry, mid-game, second opponent two points behind the best | 5 | 4 | -0.0492 |
| Race table entry, mid-game, second opponent two points behind the best | 6 | 4 | -0.0854 |
| Race table entry, mid-game, second opponent two points behind the best | 7 | 4 | -0.1033 |
| Race table entry, mid-game, second opponent two points behind the best | 8 | 4 | -0.0938 |
| Race table entry, mid-game, second opponent two points behind the best | 9 | 4 | 0.0279 |
| Race table entry, mid-game, second opponent two points behind the best | 4 | 5 | 0.0969 |
| Race table entry, mid-game, second opponent two points behind the best | 5 | 5 | 0.0376 |
| Race table entry, mid-game, second opponent two points behind the best | 6 | 5 | -0.017 |
| Race table entry, mid-game, second opponent two points behind the best | 7 | 5 | -0.0621 |
| Race table entry, mid-game, second opponent two points behind the best | 8 | 5 | -0.0746 |
| Race table entry, mid-game, second opponent two points behind the best | 9 | 5 | 0.0048 |
| Race table entry, mid-game, second opponent two points behind the best | 4 | 6 | 0.1706 |
| Race table entry, mid-game, second opponent two points behind the best | 5 | 6 | 0.1276 |
| Race table entry, mid-game, second opponent two points behind the best | 6 | 6 | 0.0592 |
| Race table entry, mid-game, second opponent two points behind the best | 7 | 6 | 0.0128 |
| Race table entry, mid-game, second opponent two points behind the best | 8 | 6 | -0.0589 |
| Race table entry, mid-game, second opponent two points behind the best | 9 | 6 | -0.0185 |
| Race table entry, mid-game, second opponent two points behind the best | 4 | 7 | 0.2416 |
| Race table entry, mid-game, second opponent two points behind the best | 5 | 7 | 0.2286 |
| Race table entry, mid-game, second opponent two points behind the best | 6 | 7 | 0.1778 |
| Race table entry, mid-game, second opponent two points behind the best | 7 | 7 | 0.1092 |
| Race table entry, mid-game, second opponent two points behind the best | 8 | 7 | -0.0221 |
| Race table entry, mid-game, second opponent two points behind the best | 9 | 7 | 0.0222 |
| Race table entry, mid-game, second opponent two points behind the best | 4 | 8 | 0.2874 |
| Race table entry, mid-game, second opponent two points behind the best | 5 | 8 | 0.3214 |
| Race table entry, mid-game, second opponent two points behind the best | 6 | 8 | 0.3234 |
| Race table entry, mid-game, second opponent two points behind the best | 7 | 8 | 0.2487 |
| Race table entry, mid-game, second opponent two points behind the best | 8 | 8 | 0.0514 |
| Race table entry, mid-game, second opponent two points behind the best | 9 | 8 | -0.0213 |
| Race table entry, mid-game, second opponent two points behind the best | 4 | 9 | 0.1283 |
| Race table entry, mid-game, second opponent two points behind the best | 5 | 9 | 0.4077 |
| Race table entry, mid-game, second opponent two points behind the best | 6 | 9 | 0.4673 |
| Race table entry, mid-game, second opponent two points behind the best | 7 | 9 | 0.4245 |
| Race table entry, mid-game, second opponent two points behind the best | 8 | 9 | 0.1968 |
| Race table entry, mid-game, second opponent two points behind the best | 9 | 9 | 0.0227 |
What holding cards of one resource is worth
Measured evidenceScroll the chart horizontally to inspect all values.
Entries of the hand table for a hand of k cards of a single resource and nothing else, with three settlements and four cities still to build, from the frozen tables.
Source: Frozen candidate tables artifacts/ntuple/hex-portfolio-main.bin (SHA-256 f8e61e66...), decoded by analysis/ntuple_inspect.py.
View data table
| Series | Cards of the one resource in hand | Table entry (win-probability units) |
|---|---|---|
| brick | 0 | -0.1061 |
| brick | 1 | -0.0889 |
| brick | 2 | -0.0854 |
| brick | 3 | -0.0677 |
| brick | 4 | -0.0585 |
| lumber | 0 | -0.1061 |
| lumber | 1 | -0.0835 |
| lumber | 2 | -0.0703 |
| lumber | 3 | -0.0621 |
| lumber | 4 | -0.0537 |
| wool | 0 | -0.1061 |
| wool | 1 | -0.0833 |
| wool | 2 | -0.0712 |
| wool | 3 | -0.0656 |
| wool | 4 | -0.0571 |
| grain | 0 | -0.1061 |
| grain | 1 | -0.0791 |
| grain | 2 | -0.0665 |
| grain | 3 | -0.0626 |
| grain | 4 | -0.0581 |
| ore | 0 | -0.1061 |
| ore | 1 | -0.0841 |
| ore | 2 | -0.0624 |
| ore | 3 | -0.0476 |
| ore | 4 | -0.0404 |
Looking into the search: expected outcomes
The search can now say what it expects. In explain mode a report carries, for the chosen move, the distribution of end-of-turn positions it leads to at every planned level: each position's probability along the chosen move (from dice, purchases, thefts, the sampled hands, and the common random scenarios of the opponents' round), the value the leaf gave it, and what the player has by then. Positions are merged by their builds, cards, points, and whether the game has ended, so the reading is "a city at 19 and a road, with probability 0.4" rather than one entry per sampled hand. The decision itself is unchanged; only positions the search would have discarded are kept.
What the tables expect after settling at 34
Red player · turn 35 · Build and trade · expectimax-v2-tables
5 candidates
Scroll the chart horizontally to inspect all candidates.
What it expects after this move
Positions the chosen move leads to, merged by what the player has by then, with the probability the search assigned along that move and the value it gave each. Level 1 is the end of this turn, level 2 the end of the next own turn.
End of this turn · turn 36
- 100%settlement at 344 pts · 269.3
End of the next turn · turn 40
- 56%settlement at 344 pts · 221.7
- 17%settlement at 34, 1 development card4 pts · 310.9
- 9%settlement at 34, road on 504 pts · 316.5
- 6%settlement at 34, 2 development cards4 pts · 437.4
- 5%settlement at 34, 1 development card5 pts · 236.8
- 3%settlement at 34, 2 development cards5 pts · 370.8
- 3%settlement at 34, city at 22, road on 505 pts · 381.6
- 0%settlement at 34, 2 development cards6 pts · 323.3
- Depth
- 2
- Time
- 92.1 ms
- Level 1
- 164 nodes · 41 afterstates
- Level 2
- 2218 nodes · 1831 afterstates
- Totals
- 22647 transitions · 9489 leaves · 328 scenarios · 363 transpositions
One recorded decision of the learned-leaf search at depth 2 in explain mode (engine arena, seed 5, turn 35). The chosen move is a settlement at 34; the panel lists the positions the search expects by the end of this turn and the next own turn, merged by what the player has by then, with the probability mass the search assigned along the chosen move and the value it gave each position. Probabilities come from dice, purchases, thefts, sampled hands, and the common random scenarios of the opponents round; they are the policy own expectations, not verified outcomes.
Source: Engine-arena game with --trace and explain: true, frozen tables hex-portfolio-main (SHA-256 f8e61e66...), analysis/trace_asset.py.
View data table
| Candidate | Value | Chosen | tables | expected | trade_margin |
|---|---|---|---|---|---|
| settlement at 34 | 269.3 | Yes | 269.3 | ||
| offer 1 grain for 1 ore to seat 2 | 264.5 | No | 276.5 | -12 | |
| offer 1 grain for 1 ore to seat 3 | 264.5 | No | 276.5 | -12 | |
| offer 2 grain for 1 ore to seat 2 | 251.7 | No | 263.7 | -12 | |
| offer 2 grain for 1 ore to seat 3 | 251.1 | No | 263.1 | -12 |
In the recorded decision above the tables settle at 34 and then expect, by the end of their next turn, to have added nothing further with probability 0.56, one development card with 0.17, a road on 50 with 0.09, two cards with 0.06, and a fifth point in a few percent of futures. A researcher can read from this what the policy is playing for, and a disagreement between those expectations and what actually happens is the place to look for a leaf that is wrong.
Why the tables spend more search time
The tables are not the expensive part. One evaluation of the hex plus portfolio tables costs 0.64 microseconds against 1.65 for the hand-written terms on the same positions. The search over the tables simply expands more: per decision at depth 2 it visited 2,689 own nodes and 393 chance branches where the hand-written leaf visited 1,292 and 195, and at depth 3 the ratio is the same. The tables steer play toward purchases and thefts, whose chance outcomes the planner branches over exactly, so the trees are wider. A cheaper search under the tables is a search-side question, not a feature question.
Screens on fresh seeds
Four cohorts were registered before the candidate was frozen, all on seeds 256 to 319, which nothing had read, each seed played once per rotation of the four slots (256 games), with the tables in slot 0, the hand-written leaf in slot 1, and an ETA and a fast builder in the other seats. The primary outcome of every cohort is the per-seed difference in wins between slots 0 and 1.
Screen: the tables against the hand-written leaf at depth 2
95% interval| Screen | Registration | Run | Tables wins | Hand wins | ETA | Fast | Contrast (95% interval) | Reading |
|---|---|---|---|---|---|---|---|---|
| Equal depth: tables d2 vs hand d2 | ea8af9cc | 09fb758b | 130 | 74 | 32 | 20 | +0.219 (+0.124 to +0.314) | supported; the rule asked for at least +0.10 |
| One ply: tables d1 vs hand d2 | 6a712b5a | d249aa28 | 121 | 79 | 35 | 21 | +0.164 (+0.058 to +0.270) | the tables without any search beat the two-turn search |
| Buys a ply: tables d2 vs hand d3, 1.5 s | 9ed38762 | 169b0772 | 122 | 82 | 37 | 15 | +0.156 (+0.051 to +0.262) | the learned leaf is worth more than a planned turn |
| Deployment depth: tables d3 vs hand d3, 1.5 s | acf5812a | ec904c96 | 135 | 73 | 30 | 18 | +0.242 (+0.140 to +0.345) | the margin transfers to depth 3 |
Screen: the tables against the hand-written leaf at depth 3 under 1.5 s
95% intervalDecision cost differs. The tables are slower to evaluate than the hand-written terms (125 ms against 85 ms per decision at depth 2, 612 ms against 363 ms at depth 3 under the same budget), because every window is recomputed at every leaf and the portfolio tables call the road-length walk. The one-ply tables decide in 15 ms, six times faster than the depth-2 hand-written search they beat.
How the tables play
The build counts of the equal-depth screen say something about the style the tables learned. Per game, the tables seat bought 4.9 development cards to the hand-written leaf's 2.6, built 1.3 cities to its 1.7, and settled and traded at about the same rate (1.7 settlements, 5.1 player trades). The first version of the hand-written leaf over-bought development cards and lost; the tables buy even more and win, which suggests the cards themselves were never the problem, only how the earlier leaf priced everything else around them. Which patterns drive the difference is a question for a follow-up that reads the portfolio tables as the hex table is read above.
The protocol cohort
The registered protocol cohort seated the same tables inside
expectimax-v2-plan's exact search against expectimax-v2-plan itself, with
the two builders, on 20 deterministic seeds through the authoritative server:
46 wins to 25 of 80, paired contrast +0.263 (95% interval +0.094 to +0.431),
every game valid. The protocol report records it
and makes ntuple-leaf the protocol-arena baseline.
Second pilot: learning settings and a compact corner window
Nine arms trained for eighteen minutes each under the first pilot's protocol, with the hex plus portfolio layout unless named otherwise: a repeat of the defaults as the control, step size 0.5, λ 0.9 and 0.3, point reward 0.1, 2% random exploration, optimistic initialization at 0.25, a 100,000-game warm-up, and the hex plus corner plus portfolio layout, where a corner window is the three touching hexes and the building state only (303,918 entries).
Second pilot: learning settings and the corner family
Measured evidenceScroll the chart horizontally to inspect all values.
Nine arms with the hex plus portfolio layout unless named otherwise, each trained for eighteen minutes of wall time on 32 threads and validated on the same 24 fixed deterministic seeds in every rotation (96 games) as the depth-2 leaf against the hand-written leaf with the two builders. Bars are the paired per-seed margin at the last validation point with a normal-approximation 95% interval. The control repeats the first pilot's hex plus portfolio arm, which finished at +0.302; the gap between the two identical runs is the noise floor of this pilot.
Source: Training runs under runs/ntuple/; the last validation tournament of each arm (24 fixed deterministic seeds, four rotations, depth 2, hand-written leaf in slot 1, ETA and fast builders).
View data table
| Series | Layout | Wins per game, tables minus hand leaf | Low | High |
|---|---|---|---|---|
| Validation margin after the pilot budget | defaults (control) | 0.1146 | -0.0548 | 0.284 |
| Validation margin after the pilot budget | lambda 0.3 | 0.3542 | 0.2099 | 0.4984 |
| Validation margin after the pilot budget | lambda 0.9 | 0.2812 | 0.0679 | 0.4946 |
| Validation margin after the pilot budget | epsilon 0.02 | 0.2292 | 0.0359 | 0.4224 |
| Validation margin after the pilot budget | optimistic 0.25 | 0.1875 | 0.0484 | 0.3266 |
| Validation margin after the pilot budget | hex + corner + portfolio | 0.1667 | -0.0119 | 0.3453 |
| Validation margin after the pilot budget | warm-up 100k | 0.1354 | 0.0104 | 0.2605 |
| Validation margin after the pilot budget | alpha 0.5 | 0.0417 | -0.1576 | 0.241 |
| Validation margin after the pilot budget | point reward 0.1 | 0.0938 | -0.1144 | 0.3019 |
| Arm | Last: tables / hand / ETA / fast | Last margin (95% interval) | Best margin |
|---|---|---|---|
| defaults (control) | 44 / 33 / 9 / 10 | +0.115 (−0.055 to +0.284) | +0.219 |
| λ 0.3 | 58 / 24 / 8 / 6 | +0.354 (+0.210 to +0.498) | +0.354 |
| λ 0.9 | 58 / 31 / 3 / 4 | +0.281 (+0.068 to +0.495) | +0.281 |
| ε 0.02 | 48 / 26 / 14 / 8 | +0.229 (+0.036 to +0.422) | +0.312 |
| optimistic 0.25 | 48 / 30 / 9 / 9 | +0.188 (+0.048 to +0.327) | +0.281 |
| hex + corner + portfolio | 45 / 29 / 13 / 9 | +0.167 (−0.012 to +0.345) | +0.167 |
| warm-up 100,000 | 45 / 32 / 12 / 7 | +0.135 (+0.010 to +0.260) | +0.135 |
| step size 0.5 | 40 / 36 / 11 / 9 | +0.042 (−0.158 to +0.241) | +0.219 |
| point reward 0.1 | 44 / 35 / 12 / 5 | +0.094 (−0.114 to +0.302) | +0.094 |
The control finished at +0.115 where the identical configuration finished at +0.302 in the first pilot. Training on shared tables is not deterministic across runs, and 96 validation games have a wide interval, so two identical runs differ by about 0.2 wins per game; nothing in this pilot separates from that floor. λ 0.3 and 0.9 sit at the top and the corner family in the middle, which says the defaults are not obviously wrong and that the compact intersection window is no better than none. Two four-hour runs, the defaults and λ 0.3, each on sixteen threads with a 192-game validation cohort, follow to ask whether longer training helps and whether the λ reading survives.
Two four-hour runs
The second pilot could not separate any setting from noise, so two runs took the question to a longer budget with a validation cohort twice the size: the default settings and λ 0.3, each on sixteen threads for four hours of wall time, validated every 30,000 games on 48 seeds in every rotation (192 games) against the hand-written leaf in the same depth-2 search with the two builders.
Four-hour run, default settings: the tables against the hand-written leaf
Measured evidenceScroll the chart horizontally to inspect all values.
Hex plus portfolio tables trained from scratch for four hours of wall time on sixteen threads with the default learning settings, validated every 30,000 games on 48 fixed deterministic seeds in every rotation (192 games) as the depth-2 leaf against the hand-written leaf with the two builders. Bands are normal-approximation 95% intervals of the paired per-seed margin. The point at 150,000 games, the largest margin, is the frozen candidate long-default.
Source: Training run runs/ntuple/long-default; every validation point is a tournament on fixed deterministic seeds against the hand-written leaf in the same search with the two builders.
View data table
| Series | Self-play games trained (thousands) | Wins per game, tables minus hand leaf | Low | High |
|---|---|---|---|---|
| Tables as the depth-2 leaf | 30 | 0.0208 | -0.1111 | 0.1528 |
| Tables as the depth-2 leaf | 60 | 0.1979 | 0.075 | 0.3208 |
| Tables as the depth-2 leaf | 90 | 0.2188 | 0.0814 | 0.3561 |
| Tables as the depth-2 leaf | 120.1 | 0.2552 | 0.1408 | 0.3696 |
| Tables as the depth-2 leaf | 150.1 | 0.375 | 0.2556 | 0.4944 |
| Tables as the depth-2 leaf | 180.1 | 0.2708 | 0.1349 | 0.4068 |
| Tables as the depth-2 leaf | 210.1 | 0.3594 | 0.2474 | 0.4714 |
| Tables as the depth-2 leaf | 240.1 | 0.3333 | 0.2268 | 0.4399 |
| Tables as the depth-2 leaf | 270.1 | 0.2917 | 0.1822 | 0.4012 |
| Tables as the depth-2 leaf | 300.1 | 0.2188 | 0.0944 | 0.3431 |
Four-hour run, lambda 0.3: the tables against the hand-written leaf
Measured evidenceScroll the chart horizontally to inspect all values.
The same run with lambda 0.3 in place of 0.7, trained concurrently on the other sixteen threads and validated on the same 192-game cohort. The point at 270,000 games is the frozen candidate long-lambda-0.3.
Source: Training run runs/ntuple/long-lambda-0.3; every validation point is a tournament on fixed deterministic seeds against the hand-written leaf in the same search with the two builders.
View data table
| Series | Self-play games trained (thousands) | Wins per game, tables minus hand leaf | Low | High |
|---|---|---|---|---|
| Tables as the depth-2 leaf | 30 | -0.0885 | -0.2136 | 0.0365 |
| Tables as the depth-2 leaf | 60 | 0.1875 | 0.0582 | 0.3168 |
| Tables as the depth-2 leaf | 90 | 0.2552 | 0.1399 | 0.3705 |
| Tables as the depth-2 leaf | 120.1 | 0.2865 | 0.161 | 0.412 |
| Tables as the depth-2 leaf | 150.1 | 0.2448 | 0.1232 | 0.3664 |
| Tables as the depth-2 leaf | 180.1 | 0.2865 | 0.1698 | 0.4032 |
| Tables as the depth-2 leaf | 210.1 | 0.276 | 0.1591 | 0.393 |
| Tables as the depth-2 leaf | 240.1 | 0.2708 | 0.148 | 0.3936 |
| Tables as the depth-2 leaf | 270.1 | 0.2917 | 0.1719 | 0.4114 |
| Run | Games | Points | Best margin (at games) | Last margin | Frozen candidate |
|---|---|---|---|---|---|
| Default settings | 300,150 | 10 | +0.375 (150,075) | +0.219 | long-default, SHA-256 7fefc641… |
| λ 0.3 | 270,135 | 9 | +0.292 (270,135) | +0.292 | long-lambda-0.3, SHA-256 9c166eb4… |
The default run climbed to +0.375 at 150,000 games and then wandered between +0.22 and +0.36; the λ 0.3 run reached +0.29 by 120,000 games and stayed there. On this larger cohort neither run's best point is clearly above the main run's candidate (+0.375 on 128 games at 96,000 games), and the intervals of the two runs overlap at every point after the first. Each best point was frozen and screened against the frozen 96,000-game tables on fresh seeds (340 to 403 for the earlier cohorts; 404 to 467 here), the only comparison that counts.
| Screen | Registration | Run | Candidate wins | Frozen tables wins | Contrast (95% interval) | Reading |
|---|---|---|---|---|---|---|
| Default settings, four hours, vs frozen tables | caf6e656 | dee1f84c | 109 | 101 | +0.031 (−0.082 to +0.145) | inconclusive |
| λ 0.3, four hours, vs frozen tables | 714fa798 | a144ba45 | 106 | 92 | +0.055 (−0.046 to +0.155) | inconclusive |
Neither longer training nor the λ change produced tables measurably better than the ones frozen after 96,000 games. The plateau the first run stopped on was real: with these windows and this learning rule, the tables reach their level in about a hundred thousand games, and the remaining lever is the representation or the search around it, not more of the same games.
Depth 4 and deepening where it matters
A planned turn ends at the leaf before the next round's dice, so a deeper cap
keeps more of the resource dynamics inside the tree. Depth 4 with the tables
costs a median of 3.5 s and a 90th percentile of 6.5 s per main-phase decision
on sampled positions, and the default node budget of 400,000 transitions
aborts most depth-4 searches, so a depth-4 configuration needs a larger node
budget and a larger time budget. Two search changes make that budget go where
decisions are close: a position with a single candidate never deepens past the
first depth (29% of the tables' decisions), and with deepen_gap the search
stops deepening once the best move leads the runner-up by that many leaf units
(on 509 traced decisions the median lead was 5.5 units, half a percentage
point of win probability, and a tenth exceeded 38).
The first registered configuration, ntuple-leaf-deep (depth cap 4, 4 s
budget, 5,000,000 transitions, gap 20), played the depth-3 baseline
configuration on seeds 468 to 531:
| Screen | Registration | Run | Deep wins | Depth-3 wins | Contrast (95% interval) | Reading |
|---|---|---|---|---|---|---|
| Tables, depth 4 (4 s, gap 20) vs depth 3 (1.5 s) | c36715d4 | 57717b3e | 129 | 109 | +0.078 (−0.039 to +0.196) | inconclusive |
| Hand-written leaf, the same two configurations | 6d9624c9 | 90009612 | 89 | 102 | −0.051 (−0.176 to +0.074) | inconclusive |
| Tables at equal time: cap 4 vs cap 3, both 10 s, 32 seeds | 8dc65a70 | 4e81a0cd | 60 | 52 | +0.062 (−0.105 to +0.230) | inconclusive |
| Gap rule alone: baseline (depth 3, 1.5 s) with gap 20 vs without | 0ce4a417 | a32e7819 | 120 | 103 | +0.066 (−0.044 to +0.177) | not weaker, 42% less time |
The effort counters say why the gain is small: with the time rule still at
30% of the budget the deep seat completed depth 4 on few decisions (mean
completed depth 1.98 against 2.18 for the baseline seat, which counts
single-candidate positions as depth 1) and mostly spent its budget finishing
depth 3 where the 1.5 s seat had to abort (858 ms against 447 ms per
decision). The protocol cohort settled the question for this configuration. Through
the authoritative server, ntuple-leaf-deep against ntuple-leaf with the
two builders on 20 deterministic seeds (372d07bc, run 8f6dd1a7, an 8 s
deadline, no timeout moves): 27 wins to 43, a contrast of −0.200 (95%
interval −0.357 to −0.043). The registered rule reads an interval below zero
as a refutation, so the baseline stays ntuple-leaf and the depth-4
configuration with a 4 s budget and the gap rule is weaker, not stronger,
where it counts. Twelve matches ran at once, so both searches shared the
machine; the deep seat pays for every depth-4 attempt it has to abort, and the
gap rule may be settling decisions at depth 1 that deserve the lookahead. Two
cohorts separate those causes. At equal time, with 10 s budgets and deepening
allowed while under 60% of them, the cap of 4 reached a mean completed depth
of 2.85 against 2.34 for the cap of 3 and spent 3.5 s per decision against
0.7 s, for 60 wins to 52 on 32 seeds (+0.062, −0.105 to +0.230): the fourth
planned turn costs five times the time of the third for a gain this cohort
cannot see. The gap rule alone, on the baseline configuration against itself
without it, won 120 to 103 (+0.066, −0.044 to +0.177) while spending 262 ms
per decision against 448 ms: stopping deepening on settled decisions costs no
measurable strength and saves 42% of the time. The depth-4 protocol loss is
therefore not the rule's doing; it belongs to the depth-4 attempts themselves,
which abort under contention and pay for it, and to a cohort of twenty seeds.
Depth 4 is not the baseline; the gap rule is a free saving that a future
baseline configuration can carry.
More searches at the table
Two follow-up cohorts on seeds 340 to 403 asked whether the margin depends on the two weak builders. With a second hand-written search in place of the fast builder, the tables won 107 of 256 slot-games against 63 and 58 for the two hand-written seats and 28 for ETA (contrast +0.172, 95% interval +0.056 to +0.287). In a symmetric field of two table seats and two hand-written seats, each table seat won 76 against 52 for each hand-written seat (contrast +0.094, +0.004 to +0.183); that lineup repeats under a two-seat shift, so the cohort holds 128 distinct games and its interval is narrower than it should be. The advantage survives more searches at the table and shrinks, as it must, when half the table is the tables.
Limitations
The pilot's and the main run's validation seeds are reused at every point and chose the layout and the candidate, so their margins are optimistic; the fresh seeds of the screens are the evidence, and they are development-tier engine games on one lineup with two fixed builders. Strength against other searches, against humans, or in trade-rich tables with negotiating opponents is not established. The tables were trained by depth-1 self-play for under two hours on one layout; none of the learning settings (step size, lambda, point reward, warm-up) has been varied beyond the pilot's single ablation of the point reward. Self-play against copies of the tables could learn a style that beats itself; the builders at every table are the guard against that.