Dominó — the honest learner

Teaching a small neural network to play — by playing, from wins and losses. No lookahead, no simulations, no human games to copy.

Introduction

I am not sure if it still happens, but it used to be that in the afternoons bars in Perlora and Peran were full of older men playing dominó. It was loud because the dominoes were made out of marble and people put them down with some amount of emphasis. It was loud because the TV was on. It was loud because the players got angry when somebody else did something they deemed to be stupid. There were unbelievable fights, and then the next day the same people met to play again. It was played for the playing because at most the winner got the coffee paid by somebody else. I played myself a few times, but was never good, and I am sure I never got a coffee.

Coming to the here and now, I wanted to play a bit with training an AI and so I spent a day, with the invaluable help of Mistral's AI, training a program to play domino. First there is a play engine, which is pretty elementary because dominó is a rather simple game. You can try it below. If you want to play against the best of the best, choose "Serondo" as your opponent. If you want a competent but less magnificent adversary, choose "Cazurro". You can also choose random opponents, or you can let the opponents play at random. One of the most amazing consequences of this experiment is that these two are not the same: to keep a random strategy is better than to play at random!

After playing you have a basic description of the neural networks that I played with. Altogether there were 4 architectures and there was the learning rate to adjust. Two of these strategies had a single layer, and two had an intermediate layer. These intermediate layers didn't lead to any better result, something which kind of surprised me. What they did was to slow the training a lot. Anyways, I compared a bunch of training schedules, lengths, and learning rates. You could run these tests yourself (all the training happens in your browser, that is in your computer, not in a random data center somewhere), and you can find the conclusions on the training here.

What is more interesting is what all of this says about the game itself. You can see the conclusions about this here, but the main point seems to be that independently of your starting point some amount of experience makes you improve a lot, that once you reach a plateau you got to be really attentive (small learning rate) to improve at all, and that in the best of cases luck still plays a role because you will only manage to win about 60% of the games against 2 untrained random players (here the games are to 21, to reduce the effect of luck in a single hand). It also seems that if a good player is a player who wins a lot against random players: if X is more successful than Y against random players, then X is also going to be rather successful when playing against Y.

The rules of the game

Everything on this page uses the same rules the engine implements — the way the game is played in the village. For the standard experiments, three players and a target of 21.

So a match is a sequence of rounds with growing pressure: early rounds you want to shed pips; late rounds, with a high tally, you want to force others to score. Chance level for a three-player match is 33.3% — but as we will see, uniform random play scores far below chance against anyone consistent, and the game's real skill is working out what the hidden hands hold.

The brains — Serondo & Cazurro

Serondo: not loaded Cazurro: not loaded

When this page opens it looks for JSON/serondo.json and JSON/cazurro.json next to itself and loads them automatically. Browsers often refuse that for local files — then load each one once with the buttons and it stays ready for the whole session. Nothing on this page learns: every brain plays greedy from its saved weights.

New match

AI seats: Random (random play) picks blindly — the true chance level. Random strategy is a fresh untrained brain: nobody home, just random initial weights — but even that fixed arbitrary policy beats random play. Serondo and Cazurro play greedy from their trained weights, loaded from JSON/serondo.json and JSON/cazurro.json (see the card below if they are not found automatically).

Your hand

The brains

Two small neural networks, written from scratch in pure JavaScript — no machine-learning libraries, no game-tree search, no move simulation, no human games to imitate. A brain sees the table exactly as a player sees it and picks a move by probability. It learns only from the outcomes of the rounds it played.

What the brain sees (formal)

Every move is encoded as a feature vector of 106 numbers: my 7+ tiles and the full tile set (28, one-hot: in my hand / on the board / unseen), the two open ends, the size of el bote, each player's hand size and tally, and — crucially — the shown information about each opponent this round: which pip values they have played, how many tiles they drew from el bote, and their pasos. The game state that the law of the village hides (the opponents' hands) is never given to the brain. Hidden information must be inferred.

features(state, seat, ctx) → ℝ¹⁰⁶, ctx = { n players, target, my tally, opponents' tallies }

What the brain answers

The output layer has 56 scores — one per (tile, end) pair (28 tiles × 2 ends). Illegal moves are masked out and the remaining scores become a probability distribution over legal moves.

maskedProbs(scores, legalMoves) → probabilities; move ~ sampled (learning) or argmax (play)

Architecture v1 — the summariser (formal)

v1 is a feed-forward network: 106 inputs → 64 hidden neurons (tanh) → 56 outputs. A second hidden layer of 64 (v1 · 2L) was also tested. Opponents' past actions enter as fixed summaries in the input vector — the counts mentioned above.

Architecture v2 — the rememberer (formal)

v2 keeps the same body but adds a recurrent memory: a vector of 32 numbers updated after every event of the round — any tile played by anyone, any draw from el bote, any paso, in order. At each decision, the memory is first updated with the current observation, then read together with it. The whole event sequence of the round is trained end-to-end (back-propagation through time, BPTT).

What the architectures suggest (intuition)

v1 is the accountant. It keeps totals — how many fives she has shown, how many tiles he drew — and reacts. It cannot represent order: "he drew twice from the bote and then passed on a 5" is just "2 draws, 1 paso, no fives" to it. Its summaries are the kind of counting a casual human player does.

v2 is the gossip. Its memory is a running story of the round. It can, in principle, hold the sequence of events and support finer inferences — "she drew two tiles and still hasn't played a five, so she probably doesn't have one" — the reasoning of an attentive player. The price: it has more to learn (the memory must be trained through time), so it matures noticeably more slowly. This is not speculation — the champion league showed v2 seeds losing every early evaluation and dominating once given 50% more pre-training (see the league).

How it learns (formal)

Learning is REINFORCE (a policy-gradient method). Three copies of the same brain play complete rounds against each other. At the end of a round, each player receives a negative reward equal to the points added to their tally. Each move's contribution is weighted by the advantage of the outcome (round-average baseline), with a small entropy bonus (β = 0.01) to keep exploration alive:

for each taken move a: grad ∝ (reward − baseline) · (∇ log π(a|s)) + β · ∇H(π) ; update: Adam

The learning rate (formal)

All updates use the Adam optimiser with a single scalar learning rate. The experiments use a decayed schedule, one value per phase of training:

LR = 0.0005 → 0.0003 → 0.0001 → 0.00005 (20,000 rounds per phase; 80,000 total)

The learning rate, in plain words. The learning rate is the size of the step the brain takes after each lesson. A high rate is an enthusiastic student who overreacts to every round and never settles — trained at 0.002–0.003, brains ended 6–8 points weaker, thrashing around a plateau. A low rate is a careful student who barely moves. The schedule is a student who starts enthusiastic (0.0005 buys +20 points in a few thousand rounds), then cools down to consolidate what was learned. The surprising finding of the grand tour: the cooling itself is where most late progress comes from — each drop of the rate produces a visible jump, while extra rounds at the same rate produce almost nothing. The final phase at 0.00005 bought nothing measurable and could be skipped entirely.

Random strategy beats random play

Before measuring any trained brain, two honest baselines — both measured over 10,000 complete matches to 21 against two random opponents (every number wobbles only about ±1%):

  • Uniform random play (pick any legal move blindly, every turn) is the true chance level of the game: 33.3% of matches won — one third, by symmetry.
  • A fresh untrained brain is not a random player. Its random initial weights give it a fixed, arbitrary policy — a "strategy" nobody designed, with nobody home, but a strategy nonetheless. And it beats random play: ten independent fresh v1 · 1L brains, each playing 10,000 complete matches to 21 against two randoms, averaged 35.7% — 2.4 points above chance (full table below). Eight of the ten finished above chance, two as high as ~39.9%; one landed below it (31.9%) — a "strategy" can be worse than blind if it is consistently wrong, but even random weights usually beat blind picking.
TestWin % to 21vs chance
135.6%+2.3 pts
233.6%+0.2 pts
334.6%+1.2 pts
439.8%+6.5 pts
534.7%+1.4 pts
639.9%+6.5 pts
736.4%+3.1 pts
835.1%+1.7 pts
935.7%+2.4 pts
1031.9%−1.5 pts
Mean of 1035.7%+2.4 pts

Ten fresh, independently initialized v1 · 1L brains, each playing 10,000 complete matches to 21 (round after round, with tallies and eliminations) against two random players, greedy from their random initial weights. Chance is 33.3%; at 10,000 matches, pure noise moves each number by only about ±1%.

Why this matters. Any consistent policy — even one made of random weights — beats picking blindly. The reason is structural: uniform random play shreds pips at random, ignores the two ends, and hands the initiative to whoever happens to hold the right tiles. A fixed policy, however clumsy, at least does the same kind of thing every round, so the variance of its results drops and the weaknesses of blind play are punished. The practical lesson for everything that follows: compare trained brains against these two references, not against 33% alone — a brain at 55% is not "22 points above chance", it is ~19 points above a random-weight nobody.

Train it here and now — and the grand tournament

The first loop was the plain one: pick the opponents (learner copies, random players, or loaded brains frozen in the other seats), a number of rounds, and watch the statistics. Training in segments of 10,000–20,000 self-play rounds against chosen opponents, and measuring each time. Two facts surfaced immediately:

  • Self-play works. Three copies of the same brain playing each other, with nobody to copy and no rules explained beyond the moves — the win rate against randoms climbs from ~35.7% to ~56% in the first 4,000 rounds.
  • The learning rate decides the ceiling. Brains trained 200,000 rounds at constant LR 0.002–0.003 ended far below brains trained at 0.0005 — more rounds did not compensate for too-large steps.

Then the tournament: eleven brains — the products of different training runs (v1 and v2, one and two layers, various learning rates, self-play and training against randoms, 5,000 to 206,936 rounds) — played each other 10,000 complete matches to 21 per pairing, chairs alternating, with a random player in the third seat. Each entrant also played 10,000 matches against two random players.

The ranking (average share of matches won, head-to-head)

v2 · 1L · lr 0.0005 · self-play
48.8%
v1 · 2L · lr 0.0005 · self-play
45.5%
v2 · 2L · “pepe”
45.5%
v1 · 2L · lr 0.0005 · vs random
44.0%
v2 · 2L · lr 0.0005 · self-play
42.8%
v1 · 1L · “mike” (5,000 rounds)
41.5%
v2 · 1L · lr 0.002 · self-play
41.2%
v1 · 1L · self-play (200k)
40.2%
v1 · 2L · lr 0.003 · self-play
35.6%
v1 · 2L · lr 0.003 · vs random
35.1%
v1 · 1L · vs random (206,936)
33.8%

Bars scaled to 50% head-to-head (with a random third seat, ~42–45% is parity between equals).

What the tournament established

  • The champion: v2 · 1L trained at lr 0.0005 in self-play — 61.1% against two randoms, and it beat all ten opponents head-to-head (its worst cell is still 45.1%).
  • The learning rate dominates the round count. The two lr-0.003 brains (200,000 rounds each) and the 206,936-round brain trained against randoms form a clear bottom tier; the lr-0.0005 brains own the top. 40× more rounds did not rescue a bad rate.
  • Results against randoms predict the tournament. The correlation between each entrant's vs-randoms win rate and its head-to-head ranking was nearly perfect (r ≈ 0.99). The tournament crowned the brain the randoms had already identified.
  • Luck has a floor. In matches between two trained brains, the random third seat still won 14–23% of the matches. Between near-equals, most of the spread is chance — differences under ~1.5 points are noise at 10,000 matches.
  • Training against randoms was a trap. The brain trained against random opponents for 206,936 rounds ranked last — 33.8%: it learned to beat random play, which is a different game from beating players who count.

The full results matrix

Cell (row, column) = share of matches won by the row brain when facing the column brain, over 10,000 complete matches to 21 with a random player in the third seat, chairs alternating. Shaded cell = the brain does not play itself. Last column = 10,000 matches against two random players.

row beats columnv1·2L · .003 vs rndv1·2L · .003 selfv1·2L · .0005 vs rndv1·1L · vs rnd (207k)v1·2L · .0005 selfv1·1L · self (200k)v1·1L · “mike” (5k)v2·1L · .002 selfv2·1L · .0005 selfv2·2L · .0005 selfv2·2L · “pepe”vs two random
v1·2L · .003 vs rnd–38.9%34.1%40.1%34.2%36.1%36.0%34.7%30.3%33.1%33.5%46.0%
v1·2L · .003 self38.9%–34.8%41.1%34.5%36.2%35.7%36.0%31.3%34.7%33.0%46.3%
v1·2L · .0005 vs rnd47.0%46.9%–50.0%42.1%44.6%43.8%43.6%39.8%41.9%40.7%55.1%
v1·1L · vs rnd (207k)37.1%35.7%31.2%–33.0%35.8%35.6%33.8%29.7%32.9%33.3%45.3%
v1·2L · .0005 self48.3%47.3%42.7%49.4%–46.8%46.0%45.7%40.9%44.3%43.8%55.7%
v1·1L · self (200k)44.7%44.4%38.4%44.5%36.1%–40.8%40.8%35.3%40.3%36.6%52.9%
v1·1L · “mike” (5k)45.1%45.9%39.6%44.8%38.3%42.0%–41.6%38.1%39.8%39.4%53.5%
v2·1L · .002 self45.4%45.3%39.7%46.2%37.5%40.9%40.3%–37.0%40.4%39.6%53.4%
v2·1L · .0005 self53.5%51.4%46.0%53.9%45.1%48.5%46.2%48.4%–48.0%46.8%61.1%
v2·2L · .0005 self49.0%46.8%41.4%47.9%38.7%42.5%42.5%42.7%36.6%–40.0%55.2%
v2·2L · “pepe”49.7%49.1%44.2%49.5%41.6%47.0%43.9%45.8%39.3%44.8%–57.4%

The five random starts

One question the tournament could not answer: how much of a brain's strength is the architecture, and how much is the luck of its initial weights? So the same training protocol ran five times, with five independent v1 · 1L brains, each from its own fresh random initial conditions — four phases of 20,000 rounds at LR 0.0005 → 0.0003 → 0.0001 → 0.00005 (80,000 each), evaluated every 4,000 rounds over 10,000 matches to 21 against two random players.

RoundsLRRun 1Run 2Run 3Run 4Run 5Mean
0 (untrained)0.000534.6%34.6%31.5%35.5%34.7%34.2%
4,0000.000555.3%53.3%55.9%51.3%53.1%53.8%
8,0000.000558.0%56.9%56.5%55.0%56.3%56.6%
12,0000.000558.0%57.0%57.9%55.3%56.1%56.8%
16,0000.000556.1%59.0%57.8%54.7%56.8%56.9%
20,0000.000557.7%57.3%59.0%55.1%58.0%57.4%
24,0000.000357.5%58.4%59.2%56.1%57.9%57.8%
28,0000.000356.9%58.7%59.7%56.9%59.1%58.3%
32,0000.000358.3%59.2%59.2%58.5%61.0%59.2%
36,0000.000358.6%60.1%59.9%58.7%59.7%59.4%
40,0000.000359.1%60.0%59.4%58.9%59.7%59.4%
44,0000.000160.4%59.8%60.2%59.0%60.3%59.9%
48,0000.000159.3%59.1%60.4%59.8%61.3%60.0%
52,0000.000158.3%59.7%59.8%59.0%61.0%59.6%
56,0000.000159.3%60.3%60.0%59.2%60.6%59.9%
60,0000.000159.5%59.6%61.0%59.5%60.9%60.1%
64,0000.0000559.3%62.1%60.6%59.3%60.8%60.4%
68,0000.0000559.3%59.5%60.8%59.5%61.2%60.1%
72,0000.0000559.6%59.7%59.6%59.4%62.2%60.1%
76,0000.0000559.2%60.2%61.2%59.8%62.1%60.5%
80,0000.0000559.8%60.3%61.5%60.5%61.4%60.7%

What the five runs showed

  • Almost everything happens in the first 8,000 rounds: the mean jumps 34.2% → 56.6% (+22.4 points). The remaining 72,000 rounds add +4.1 points in total. The curve is a textbook saturating curve.
  • The late gains track the learning-rate decays, not the rounds: flat inside each phase, small step-ups exactly at each drop (57.4 → 57.8 → 59.9 → 60.4%).
  • Training compresses the seed lottery but does not erase it: the spread shrinks from 4.0 points untrained (31.5–35.5%) to 1.7 points at the end (59.8–61.5%). The five lines are parallel ribbons, not crossing spaghetti — Run 5 leads almost the whole way.
  • The untrained score predicts nothing: Run 4 started best (35.5%) and ended mid-pack; Run 5 started unremarkable and finished first. How so, together with the previous point? The random init deals two hidden cards: a transient beginner's luck (what the untrained score measures — erased within 4,000 rounds) and a durable learning potential (how well that wiring organises what it learns — invisible at round 0, but it sets the stable ranks from 8,000 rounds on). The init matters; the untrained measurement just cannot see it.
  • Seed luck is worth more than training time: the final draw of the initial weights is ±1.5 points; 40,000 extra rounds buy about +1 point. Choosing the best of several seeds beats doubling the training.
  • The best seeds rival the tournament champion: Runs 5 and 2 peaked at 62.2% / 62.1% vs the champion's 61.1% — within measurement noise, so "matches", not "beats". v1 · 1L ≈ v2 · 1L in pure self-play, and the self-play plateau is confirmed at 61–62%.

The self-training tour — all four brains from scratch

The same disciplined protocol for all four architectures at once — v1 · 1L, v1 · 2L, v2 · 1L, v2 · 2L — each from fresh random initial conditions, trained in self-play, evaluated every 4,000 rounds over 10,000 matches to 21 vs two random players. Final standings:

RoundsLRv1 · 1Lv1 · 2Lv2 · 1Lv2 · 2L
0 (untrained)0.000539.1%36.7%31.2%35.4%
4,0000.000556.3%55.6%51.1%49.8%
8,0000.000559.0%58.1%55.9%51.3%
20,0000.000558.3%57.2%58.8%57.2%
40,0000.000360.0%60.1%59.4%57.2%
60,0000.000161.4%60.1%59.3%57.5%
80,0000.0000561.8%59.3%60.2%58.4%

(Condensed; the full table has all 21 checkpoints.)

What the tour showed

  • Progress stops twice: within each phase (exhausted after ~8k rounds) and overall (the plateau). Averaged over the four brains, the gains per phase were +22.5, +1.3, +0.4 and +0.3 points. The final 20,000 rounds at LR 0.00005 bought nothing measurable and could be skipped entirely.
  • The drops in learning rate are where progress lives: each decay produced a clean +0.6–0.8 jump for all four brains; the rounds in between produced wander (±0.5–1%).
  • Architectures end close together: from an 8-point spread untrained (31.2–39.1%) to a ~3.4-point final spread — a real architecture effect, not init luck: the simple v1 · 1L ends best (61.8%), the recurrent v2 · 2L ends worst (58.4%). Bigger brains did not pay for themselves in self-play.
  • Self-play plateaus at 61–62% vs randoms for every architecture — the ceiling that motivated the champion league.
Recipe distilled from the tour: steal the schedule, cut the budget — ~10k rounds per phase (0.0005 → 0.0003 → 0.0001, ~30k total) should land within ~1 point of the 80k result; skip LR 0.00005; and don't train longer — train against stronger opponents.

The champion league — breed, compete, replace

Self-play's ceiling is 61–62%, and the five runs showed the seed lottery is worth more than tens of thousands of rounds. The champion league turns both facts into method — a small population of brains that breed, compete, and get selected, in four phases:

  1. Phase 0 — breed: a population of fresh v1 · 1L and v2 · 1L seeds trained from random initial conditions in classic self-play with the proven decayed LR (v2 seeds get 50% more pre-training — they mature more slowly).
  2. Phase 1 — league training: each member, in turn, trains a block of rounds as the learner while the other seats are frozen opponents drawn from a pool: the other members, snapshots of their past selves, the loaded champion to beat, and a share of random players. Nobody overfits to one table; every learner faces habits it has not absorbed.
  3. Phase 2 — evaluate and replace: a round-robin (chairs alternating) plus matches vs two randoms ranks the members; the bottom half is replaced by fresh clones warm-started from the top half (Adam state reset, doubled LR) — soft selection: nobody dies from one noisy day.
  4. Phase 3 — sharpen and crown: the top two fine-tune at low LR against the elite; the final ranking is computed; the champion plays 10,000 matches vs two randoms and 10,000 head-to-head vs the previous champion.

Run 1 — the warning

Six members, four cycles, serondo (the tournament champion, v2 · 1L, 61.1% vs randoms) loaded as the target. Result: champion 58.1% vs randoms, 43.0% vs serondo — a statistical tie with the old champion, not a victory. Three lessons, all confirmed by the per-cycle history:

  • Population drift: every lineage lost ~2.5 points per cycle against randoms while holding ~50% head-to-head — league training against mostly-league opponents was eroding the general game.
  • v2 · 1L was eliminated at the very first evaluation — not because it is weaker, but because equal-pre-training disadvantaged the slower-maturing architecture.
  • Selection was partly selecting noise: ranking margins of 1–2 head-to-head points from a few hundred matches per pairing.

Run 2 — the fixes

Three changes: a higher share of random opponents in the pool (30%), 50% extra pre-training for the v2 seeds, and bigger evaluation samples. Result: champion v2 · 1L-2″ at 59.9% vs randoms, 42.7% vs serondo — parity again, but with a healthy population:

  • The drift is gone: population mean 58.9% → 59.9% across cycles (it fell before).
  • The v2 boost flipped the league: from total v2 elimination to five of six finalists being v2 lineages and the champion being v2 · 1L-2″. v2 · 1L was never weaker — it matures more slowly.
  • Selection found a dynasty: the v2 · 1L-2 family held the best head-to-head in every single evaluation (52.2, 52.3, 52.6, 50.9, 51.1) across three generations — the mechanism works.
  • Sharpening remains suspect: 62.4% at the last evaluation, 59.9% in the post-sharpen championship test — the same pattern as run 1 (61.0 → 58.1). Fine-tuning against only the elite costs generality.

The honest verdict: two independent runs converged to the same result — the league reliably reproduces the best existing brain (parity with serondo, whose arch the champion shares) but does not exceed it. Fresh breeding spends most of its budget re-reaching the plateau; the next step is starting from strength — seeding the league with the best existing brains as competing entrants.

Conclusions about training

  1. The learning rate schedule dominates the round count. 40× more rounds did not rescue a bad rate (tournament bottom tier), and within a good schedule the gains die after ~8k rounds per phase — the final 20k rounds at the lowest rate bought nothing. Train ~10k per phase with decay, then stop.
  2. The drops are the gains. Visible progress after the early rounds comes mostly from the LR decays themselves, not from accumulating more rounds.
  3. Pure self-play has a ceiling at 61–62% vs randoms, identical for all four architectures — and 2.5× more rounds doesn't move it. Beyond it, the environment must change: league pools, past selves, loaded champions.
  4. The seed lottery is worth ±1.5 points — more than 40,000 extra rounds. Breed several candidates and select; never trust a single draw.
  5. The untrained score of a seed predicts nothing. The init deals a transient beginner's luck (erased in 4,000 rounds) and a durable learning potential (invisible until trained). The only way to find the good seeds is to train them.
  6. Architecture matters less than schedule and seeds. v1 · 1L ended the tour on top; v2 · 1L ≈ v1 · 1L in self-play, but v2's memory wins head-to-head among trained peers — when it is given the longer pre-training it needs to mature. Deeper (2L) variants never paid off.
  7. Training against randoms is a trap. 206,936 rounds against random opponents produced the worst tournament entrant (33.8% head-to-head ranking) — beating random play is a different game from beating players who count.
  8. League training drifts unless anchored. Populations that face mostly themselves lose ~2.5 points per cycle against the general game; a 30% share of random opponents in the pool stops the drift completely.
  9. Selection works but selection needs samples. Ranking on 500 matches per pairing selects coin flips; 1,000–2,000 cuts real differences. And beware sharpening against only the elite: it costs 1–2 points of generality.
  10. The number against randoms is a cheap, faithful ranking of players. Each entrant's win rate vs two randoms predicted its head-to-head tournament ranking almost perfectly (r ≈ 0.99) — one cheap test against random opponents stands in for the whole round-robin. But note the scale: every trained entrant clearly beat randoms (45.3%–61.1%), and within that "everyone beats randoms" band the real differences between trained players are large — up to ~16 points vs randoms and ~15 points head-to-head. Beating randoms is the entrance floor, not the measure of equality.
  11. Measure everything against the honest baselines — chance (33.3%), the random-weight nobody (35.7%), and the previous champion — at 10,000 matches per number, remembering that a random third seat wins 14–23% of matches between equals (parity head-to-head is ~42–45%, not 50%).

Conclusions about the nature of the game

  1. Blind play is the worst possible strategy. Uniform random play scores chance (33.3%) only against other blind players; against any consistent policy — even a brain of random weights — it loses ground. Consistency itself has value in this game: the tiles you leave, the ends you open, the pips you concede are information your opponents use.
  2. Dominó is a game of inference, not calculation. The network sees exactly what a player sees — and everything it achieves beyond the baseline it owes to inferring hidden hands from shown information: numbers played, draws from el bote, pasos. No amount of raw move-making skill (there is no lookahead at all) gets near 62% without inference.
  3. The skill ceiling against the table is real but bounded. The best brains win ~62% of three-player matches against random opponents — a decisive but far-from-dominant edge. When the tiles run against you, nothing rescues the round; skill operates on the margins where the cards are close.
  4. Luck is a permanent third player. Between two near-equal trained brains, a random player in the third seat still wins 14–23% of matches. El bote and the deal inject enough variance that ~10,000 matches are needed to tell strengths apart with confidence.
  5. Strength is mostly transitive — with pockets of style. Results vs randoms predicted tournament head-to-head almost perfectly (r ≈ 0.99), yet the league showed preferences can be local: a population can rank one style above another inside its own pool. There is a general "good dominó", and on top of it, styles that match up differently against each other.
  6. How good you are against bad players predicts how good you are, period — but only up to the floor. Results against random opponents ranked the tournament field almost perfectly (r ≈ 0.99): there is a general "good dominó", and it shows against any opposition. Yet all trained players beat randoms decisively, and the differences among them are just as real — the tournament field spans ~16 points vs randoms and ~15 points head-to-head. "It beats random players" tells you a player has learned the game; it tells you almost nothing about where they stand among players who have.
  7. What a "strong human move" looks like to the machine: trained brains shed heavy pips early, keep their options on both ends open, watch who draws (a player who drew from el bote and still passed on a number does not have it), and — most of all — avoid feeding the ends their opponents need. None of this was taught; all of it was learned from tally points alone, which is perhaps the strongest evidence of how much structure the game of the village has.

And the standing challenge: serondo (v2 · 1L, 61.1% vs randoms, undefeated in the tournament) has never been beaten by anything trained since. The league twice produced its equal — the reader who plays above and wants to try can challenge it in the game above.