AI Initiative logoAI Initiative
Reading room / Learning games

Matiz — poker, checked and drilled

Combines exact poker arithmetic and enumerated runout drills with explicitly weak imitation-agent practice. Separates the checkable mathematical calculator from uncertain learned play.

Product and research-interface description
This is the retained source text, not a new validation of its claims. Numerical results and comparative claims require the accompanying source review before public reuse.

Read the connected case study or article →

Not stated in document opening · Date not established

Provenance, authorship and editorial notes

Matiz — poker, checked and drilled

Id

learning-games-matiz-readme

Project

learning-games

Source path

learning-games/matiz/README.md

Source sha256

87742da1807a5e30ba8eb576b01d4bf9f9270b50ab4fbdde021e323dc891776d

Repo head

15898ff4893edc5ae8643b60619277462fee7330

Date
Not recorded
Date provenance

No date near opening; git date separate

Git last change

2026-10-12T09:20:47+01:00

Author

Not stated in document opening

Document status

Product and research-interface description

Summary

Combines exact poker arithmetic and enumerated runout drills with explicitly weak imitation-agent practice. Separates the checkable mathematical calculator from uncertain learned play.

Topics
  • poker
  • mathematics
  • games
  • NN
Related ids
  • learning-games-whetstone-readme
  • learning-games-proof-hunter-readme
  • learning-games-word-magnet-readme
  • poker-agents-readme
Evidence concerns
  • Browser practice agent is not a solver or deployed merger of every poker research model. Naming and model-choice notes are dated; account/live service status not checked.
Word count

3218

Headings
  • Matiz — poker, checked and drilled
  • What is in it
  • The engine
  • Ranges
  • How it is checked
  • Deploying
  • Responsible use
  • Decisions on the real hands and naming (2026-10-02)
  • Which agent is Matiz AI (2026-10-02)
  • What it is not
Publication status

Publication or peer-reviewed acceptance not established by discovery

Format

md

Private review scan
Known secret pattern hits

0

Customer or player record sets

None identified in selected narrative/design documents; no gameplay records, account databases or hand datasets copied.

Scope

Pattern scan plus document review; not a formal exhaustive privacy audit.

Matiz — poker, checked and drilled

Built from the two pieces on aiinitiative.co.uk: AI in Poker and *Matiz the
Math Wiz
*. Matiz itself is a research system — an adversarial collaborative
network trained on six-handed no-limit hold'em, still in validation. This app is
the part of it you can check by hand: the exact arithmetic underneath every
decision, drilled until it is instinct.

The drills and Check a hand do not guess. Where a number can be counted, it is
counted, and the app says how many runouts it counted. Where a shortcut is
taught, the true figure is shown beside it, so you learn where the shortcut
breaks rather than trusting it blindly.

Stage three adds the one thing in the app that is not exact: Matiz AI, our
trained agent — an imitation of elite professionals, and weak — that you can
play against and compare yourself with. It is labelled that way everywhere it
appears.

What is in it

Check a hand — the validation half. Give it your two cards, the board, what
they had, the pot and the bet, and it returns your hand, your equity, your outs
by name, the price you are being laid, and the verdict, with the working shown.

Four drills, ten hands each:

ShowdownTwo hands, five community cards. Who takes it?
OutsYou are behind on the flop and they have shown you. How many cards save you?
Pot oddsThey bet. Is the price right?
PositionSix-handed, folded to you. Open or fold?

Stage two — real tables. At a real table nobody shows you their cards, so
two more drills deal them face down:

Real outsThey raised from a seat and bet the flop. How many outs do you really have against what they could hold?
Real oddsSame spot, plus a pot and a bet. Call or fold against their range — set beside what you'd have believed against a random hand.

Each shows the range their action implies as the standard 13×13 grid, shaded by
how likely each hand is, and how it splits into value, top pair, draws, weak
pairs and air. The answer separates clean outs from dirty ones (a heart
that also makes them a bigger flush is worth half) and traps (cards that
improve you and still lose). "Change their range" opens the same hand in Check a
hand, where the range is editable.

Stage three — against Matiz AI. Both screens are drawn by their own
modules (table.js, realhands-ui.js) and only use Matiz AI on hands the app
did not get from you (see Responsible use below). Names are fixed (see
Naming below): Matiz AI is ours; the 2019 research AI ("Research AI"
for short) is the program in the recorded hands; the professionals are Pro n.

TableSix-handed, you against five copies of Matiz AI, 100 big blinds each hand (10,000 chips, blinds 50/100), the button moving every hand. With Coach on (the switch on the home screen), each of your turns shows how often Matiz AI would take each option, and after you act, how your choice compares.
Real handsA real decision from 10,000 recorded six-handed hands the 2019 research AI played against elite professionals: a player faces a bet after the flop. You choose fold, call or raise; then the hand is turned over — what the real player did, how the hand went, the result, every player's hole cards, and Matiz AI's mix for the same spot, replayed chip for chip through its own game. There is no answer key: a real choice is shown, not graded.

About Matiz AI (home screen) says what it is, how it was trained, how strong
it is — said once, from strength_note in agents/index.json, so it always
matches the agent that loads — where it is and is not used, and credits the
data, including the light-anonymity note below.

The agent's weights (agents/<id>-<sha8>.bin, about 377 KB) and the real hands
(data/realhands-<sha8>.txt, about 1.2 MB) are not built into the page.
They are fetched the first time Table or Real hands opens, checked against the
size and SHA-256 their index records, and cached by the service worker. A
manifest is only cached once every file it names is cached, so offline the app
always has a complete agent and a complete hands file.

Check a hand takes either their exact cards or their range — typed
(QQ+, AKs, ATo+, JJ-99), picked from a seat (UTG / MP / CO / button raise), or
edited by tapping hands on the grid — with a switch for "they bet the flop".

Hand rankings, generated by running the evaluator over one example of each —
so the reference page cannot drift away from what the app believes.

The engine

engine.js is the whole of it, and it is deliberately plain: no bit tricks, no
lookup tables, nothing that cannot be read and checked by eye.

comparable number, packing the category and its tiebreakers.

From the flop there are only 990 runouts and from the turn 44, so it counts
them. Only pre-flop is too big, and then it says so and samples.

behind to in front. This is the definition "outs" is taught with. An earlier
version counted anything that improved your hand category, which sounds the
same and is not — it said A♥K♥ on Q♥7♥2♣ had 23 outs, because pairing the
deuce is an improvement. It is, and it loses.

Ranges

A range is the one guess Matiz makes, so it is always stated, shown and
editable — and everything is still counted exactly against it.

round-trip: a range edited on the grid has to read back as itself.

your hand blocks — an ace on the board leaves three combos of AA, not six.

actually bets, street by street and size by size. The table (MEASURED in
engine.js) is measured, not assumed: counted from all 10,000 six-handed
hands the 2019 research AI played against elite professionals (PHH dataset, MIT licence),
where every hole card is recorded — folded hands included, so successful
bluffs are in it. On the flop the pre-flop raiser bet a set or better 80% of
the time, top pair 60%, a flush draw 61%, a weak pair 40%, and nothing at all
44%. The model it replaced ("value always bets, air one time in seven") made
opponents look far stronger than real players are. It is still a population
average, not a read on the player in front of you.

— with your own score per runout computed once and reused. A 544-combo button
range takes under a second on a laptop. Pre-flop still samples, and says so.

candidate next card, it removes opponent hands containing that card, then
averages the resulting pot share over the remaining weighted hands: a win
contributes 1, a tie 0.5 and a loss 0. Effective outs sum those per-card
averages. Against one known hand currently ahead of you, this is the number
of winning cards plus half the number of tying cards; it equals the ordinary
win-only count when no next card ties. Each card has its own compatible
behind-range denominator; the sum is a card-equivalent count, not an equity
probability.

tests/ranges.js holds the new maths to the old: against one known hand, range
equity and effective outs must reproduce the existing figures exactly. Its
speed check is an opt-in benchmark (MATIZ_BENCH=1 node tests/ranges.js): it
times a calibration loop first and asserts the range count beats counting combo
by combo, plus the 4-second budget. A plain run only reports the time, so a
busy machine cannot fail a correctness run.

Chart corrected 2026-10-01. Several opening-chart entries could never
fire — UTG listed "J-high suited, kicker J or better", which no non-pair hand
can be. They are now read as the suited connectors they almost certainly meant
(UTG gains JTs, T9s, 98s, 87s, 76s; MP 65s, 54s; CO 43s, 32s), and entries
with no possible reading are removed. UTG moves from 8.4% to 10.0% of hands;
MP 14.5% → 15.1%; CO 25.0% → 25.6%; button and small blind are unchanged. This
changes some Position drill answers. A test now fails if a dead entry returns.

How it is checked

tests/engine.js proves it two ways.

1. Hands whose answer is known by hand — the wheel, the steel wheel,
quads under a straight flush, flush tiebreaks down to the fifth card, two
pair decided by the kicker.
2. 20,000 random seven-card matchups against a brute-force scorer written
a completely different way, which enumerates all 21 five-card subsets. If the
two ever disagree on which of two hands is better, the test fails.

Then the numbers themselves, against figures anyone can look up: aces beat one
random hand about 85% of the time; seven-deuce offsuit about 35%; the nut flush
draw with two overcards has exactly 15 outs against a pair, is 54.4% against
jacks over all 990 runouts, and is exactly 15/44 on the turn.

node tests/engine.js        # the engine
node tests/ranges.js        # ranges, against the engine
node tests/agent-parity.js  # agent.js against the Python agent, hand by hand
node tests/realhands.js     # the real-hands reader and its data file
node tests/realhands-ui.js  # Real hands: replaying spots for Matiz AI
node tests/table.js         # the table: thousands of hands with a fake agent
node tests/sw.js            # the offline cache rules
MATIZ_BENCH=1 node tests/ranges.js   # opt-in: the speed benchmark
node build.js               # regenerate index.html from its parts
bash ../run-browser-tests.sh   # every screen in headless Chrome, served over http

index.html is generated. Edit app.html, body.html, app.js,
engine.js, agent.js, realhands.js, table.js or realhands-ui.js and run
build.js. It inlines the five scripts in that order, cutting each one's
node-only module.exports tail, and pulls the shared phone layout and swipe
reader in from ../shared. It does not include the shared Gmail bridge: Matiz
is for adults and has no parent-report flow. It refuses to write a page that
still has a node export in it, or that contains the word "Pluribus".

The browser driver for Matiz (../browser/drive-matiz.js) plays every drill,
then twenty Table hands with the coach on and five Real hands spots by pressing
the real buttons, and checks the new screens in 320- and 390-pixel frames for
anything wider than the screen, touch targets under 44 pixels (with Chrome
reporting a touch screen), and console errors.

Deploying

Nothing in this folder deploys by itself. The steps:

1. node build.js, then the node tests and bash ../run-browser-tests.sh;
look at the screenshots (node ../browser/shoot-matiz.js <dir> 320 640 and
390 844).
2. Stage:

``bash
bash stage-deploy.sh [staging-dir] # default matiz-deploy-staging
``

A relative staging-dir is taken relative to where you run the command. It
must be outside this repo, must not be $HOME or /, and if it exists and
is not empty it must be a folder this script made (it carries a
.matiz-staging marker).
3. A person deploys what was staged: npx vercel deploy --prod <staging-dir>.

What stage-deploy.sh does, in order:

fails or reports no checks at all;

manifest.json, robots.txt, icons/*.png,
agents/index.json and exactly the files it names, data/index.json and
exactly the files it names. Nothing else in agents/ or data/ ships, and
no dotfile does. A manifest naming anything but a plain file name in its own
folder is refused;

line whitelisted in the script (CITATION), or looks like test material: a
byte-for-byte copy of a file in tests/, or JSON with a fixture's shape
(checks, fixtures, cases, expected, stacked_coverage, or hands
with dealt decks);

manifest sha256 matches its file, and everything index.html loads is
staged;

mz- + 12 hex of a hash over every staged file. Any change to the page, an
agent or the real hands is therefore a new sw.js: phones install it,
precache the new manifests' files into a new cache (activate tops up
anything install missed), and delete the old cache, old weights included.
Nobody bumps V by hand; the source keeps a placeholder (mz-v3);

manifests; a year, immutable, for the hashed .bin/.txt)
and prints the deploy command. It assembles in a temp folder first, so a
refusal leaves the previous staging untouched.

Responsible use

Operator decision, 2026-10-01. In the core app Matiz AI runs *only on hands
Matiz deals itself or on the bundled real hands
*:

The boundary, stated honestly. No path in the app's screens feeds typed
cards to Matiz AI. That is a property of the app, not a lock on the model:
Matiz AI's code and weights ship inside the page, so someone using the
browser's developer tools can call it directly — the MatizAgent global
exposes newHand(deck) and actionProbs, and a dealt hand's state can be
replaced — and give it any cards they like. On-device code cannot prevent
that, and Matiz does not claim to. MatizTable refusing a caller-supplied deck
(refuseDeck in table.js) only keeps the app's own Table honest; it is not a
security boundary. The weights in agents/*.bin are public files anyway.

Matiz AI never receives cards the user types in. Check a hand and the drills
use the engine's exact counting and never call the network. Reviewing a hand
after you played it, or advice on any state you describe, are *later,
separately labelled features
* — not in this version.

Also: no search and no opponent modelling (Matiz AI answers from its trained
network alone and does not adapt to you); play money only, with no money,
wagering, or link to anywhere that takes a bet; and the word "Pluribus" never
appears in a shipped file (one academic citation line is the only exception,
and stage-deploy.sh whitelists that exact line). Every place Matiz AI's
advice or view appears carries its strength note (an imitation of
professionals, and weak): the Table intro says it once, and each coach display —
the line above your buttons, the Coach panel, and the note on your last move —
carries a short "imitates pros, weak" marker; Real hands' Matiz AI view carries
it too, with a note that it learned from those same hands. The
opponents' seat labels ("Matiz AI 1"…"Matiz AI 5") are names only and do not
repeat it.

The real hands are from the PHH (Poker Hand History) dataset, MIT licence,
doi 10.5281/zenodo.10796885, with
player names removed.

Decisions on the real hands and naming (2026-10-02)

permutation, not by how many hands they played, and the data file's header
no longer explains any ordering. The About sheet says honestly that the
dataset is public, so this anonymity is light: anyone with the dataset can
find the original record of a hand.

cards when a hand is turned over — seeing what everyone really held is what
this dataset teaches. Cards that were never shown at the table are labelled
"recorded in the dataset, not shown at the table".

2019 recorded hands is the 2019 research AI (short: Research AI). The
human players are Pro 1, Pro 2, and so on.

Which agent is Matiz AI (2026-10-02)

Matiz AI is pros-clone (agents/pros-clone-ff654a9a.bin, the default
in agents/index.json; app.js AGENT_ID and table.js's fallback load
exactly that id, and tests/agent-parity.js checks all three agree). The app
has no agent picker.

professionals' decisions in 9,000 of the 10,000 public PHH hands; on the
1,000 held-out hands it matches their action 81.8% of the time (always
guessing the commonest action: 52%). No self-play, no search. Exported from
poker-agents/runs/pros-clone.pt (sha256 f9d3dacc…) with
export_matiz.py --agent pros-clone --default.

rule bots −9.0 ± 3.5 (LEAGUE-1, 50k hands; best of the 7 candidates, and it
still loses) and −1.3 ± 2.5 after the adapter all-in fix (LEAGUE-2, 140k);
vs five copies of itself +1.3 ± 2.7 (LEAGUE-2, 120k); vs five copies of
f2b-br, a sibling tuned to exploit rule bots, −7.3 ± 3.8 (SELFTABLE, 120k).
Paired against the previous agent, deepcfr-0010, vs complex: +56.3 ± 9.0
(LEAGUE-1). Not a strong player in absolute terms; none of these
measure play against strong humans.

a quick learned best response gained about 112 bb/100 against five f2b-br
seats but about 22 against five pros-clone seats at the same 6-minute
budget (in-port, one run each). f2b-br is far easier to exploit, and a
human on the phone adapts. Reports: pokerforbots-adapter/runs/LEAGUE-1.md,
LEAGUE-2.md, ROUND-2.md, SELFTABLE.md. All of it is same-family
(Claude-only) analysis, not a cross-family verdict.

learned from, so on most spots its view may partly be recall. The app says so.

default: tests/table.js and tests/realhands-ui.js load it by id. It ships
in staging (about 377 KB) though the app never loads it.

What it is not

It is not a solver, and Matiz AI is not one either. The drills and Check a
hand answer exact questions about a hand you can name. Matiz AI is a small network
(seven actions) that imitates elite professionals, with no self-play and no
search at decision time: a sparring partner and a second opinion, weak by its
own index's description (it does not beat even a simple rule bot), not a
source of correct answers. Ranges in the drills are a published six-handed
opening chart, used as a baseline and labelled as one.

It is also not gambling: there is no money, no wagering, and no link to anywhere
that takes a bet. It is a calculator, a set of drills, and a practice table.

Continue exploring