Only the games in the file you chose are shown. One move takes 2 seconds at 1×. Tap a board to pause just that board; Space pauses everything. Amber rings mark what changed on the last move. X always moves first. Leave "Game numbers" empty to see an even sample of the file; type numbers (the same numbers as python run.py replay game 100) to see exact games.
How to play
- Load a model to start.
- The model thinks by tree search guided by its network. "Model thinks" sets how many positions it looks at per move: more is stronger and slower.
- Every finished game is kept for learning. Games you played: 0.
Let the model learn, then download everything
The learner reads your games file and the games you played, copies what winners did, learns who tends to win, and plays some new games against itself. Then it measures itself against fixed opponents before and after, so you can see if it really improved. It runs on this page with the same Python code as in rlgames.zip.
What will be used
- Load a model first.
Settings
Tic-tac-toe takes seconds. Connect 4, Othello and Flock take a few minutes. Morris is slow in a browser (long games): use 1 round and few self-play games, or run python run.py learn on your computer.
Progress
Download
The updated games file holds your original games, the games you played, and the new self-play games. Load the two updated files next time and carry on.
Report
No learning run yet.
Reinforcement learning, and how this Arena's learner is different
Written by Claude, an AI assistant, at Kevin's request. Where it says "Claude", that is the AI that wrote the code and ran the tests.
Short version: reinforcement learning (RL) is learning by trying things and being told how it went, not by being told the right answer. This tab explains it from scratch, shows the main families, and then says honestly where the learner in this Arena is the same as the famous ones and where it is not.
1. The idea in one picture
- Agent = the player (here: the model). World = the game.
- The agent picks a move. The world answers with the new position and a reward (win +1, draw 0, loss −1).
- Repeat thousands of times. The agent slowly learns which moves lead to rewards. Nobody ever tells it "this move was good".
2. How it differs from other machine learning
| Supervised | Unsupervised | Reinforcement | |
|---|---|---|---|
| Learns from | examples with the right answer | raw data, no answers | trying things and a reward |
| Feedback | instant, for every example | none | often late (end of the game) |
| Where data comes from | a fixed dataset | a fixed dataset | the agent makes its own by playing |
| Example | "this photo is a cat" | group similar customers | win at Go |
3. The three hard parts of RL
- Delayed reward (credit assignment). In a 40-move game you only learn at the end that you won. Which of the 40 moves deserves the credit? Every RL method is a different answer to this.
- Explore or exploit. Keep playing the move that has worked (exploit), or try a new one that might be better (explore)? Only exploiting gets stuck; only exploring never improves.
- Making its own data. If the agent gets worse, the games it plays get worse, and it learns from those. Mistakes can feed on themselves.
4. The family tree of RL methods
| Family | What it learns | Known for | Needs |
|---|---|---|---|
| Value-based Q-learning (1989), SARSA, DQN (2013-15) | A score for "how good is this move here?"; then it plays the best score | DQN learning Atari games from the screen | no rules, just experience |
| Policy-based REINFORCE (1992), PPO (2017) | The move choice itself: it makes moves that led to reward more likely | PPO is widely used, including for tuning chat models from human ratings | no rules, just experience |
| Actor-critic A2C / A3C (2016), SAC | Both: an "actor" picks moves, a "critic" scores them | robots, continuous control | no rules, just experience |
| Planning with search MCTS (2006), AlphaGo (2016), AlphaZero (2017) | A network guesses; a tree search checks the guess by imagining moves ahead, using the exact rules | Go, chess and shogi from nothing but the rules | the rules of the game (a perfect model) |
| Learned model Dyna, MuZero (2019) | It learns its own rough copy of the rules, then plans inside that copy | strong play without being given the rules | experience only |
Dates are approximate (first well-known paper or result). Claude has not run these other methods in this project; this table is background, not measurements.
5. Where the Arena sits
- It is in the "planning with search" family: a small copy of AlphaZero. The game rules are known, so the search can imagine moves ahead exactly (tab "How the code works", part 3).
- One small network with two heads: a policy head (a probability for each move) and a value head (who is winning).
- It learns by self-play: the model plays itself with search, then trains so that its quick guess matches what the search found and who really won.
- That answers the three hard parts: the search gives a better move than the raw guess (so credit is assigned move by move), random noise at the root of the search and a little variety in the moves it plays keep it exploring, and fixed opponents (random, greedy, plain search) check it is really improving.
6. How Claude's learner is different (the honest part)
■ Green = same as AlphaZero. ■ Orange = Claude's own addition, not a published algorithm.
| Standard AlphaZero | This Arena | |
|---|---|---|
| Training data | only its own self-play games | self-play plus games from your file plus games you play (your games count 3× by default) |
| Value target | who won | who won (same) |
| Policy target on self-play | how often the search visited each move | same |
| Policy target on games from files | (none: it does not use outside games) | if the mover won: 40% on the move played, 60% on what the network already thought. Drew: 20% / 80%. Lost: keep the network's own opinion (neither copy nor punish) |
| Weak opponents | not applicable | never copy moves made by the "random" or "greedy" players: a lucky win over them teaches nothing |
| Scale | millions of games on special hardware | a few rounds of a few games, in your browser |
| Check | played against older versions or other programs | score before and after vs random, greedy, (perfect for tic-tac-toe) and your original model |
- Why not just copy every game? Copying moves from a file is imitation learning (a kind of supervised learning). It can only get as good as the people or programs in the file. Self-play search can go beyond them.
- Why mix? AlphaGo (2016) used human games first and self-play after. Claude mixes them in the same round, so you can teach a model from your own games and let it check them by playing itself.
- Why 40%? In Claude's tests 30% to 50% worked as well as or better than 80%: copying winners too hard made models worse. This number is a hand-tuned setting, not a law.
7. What Claude's runs showed
- Self-play with search did learn in the full runs (score against random and greedy players near 1.0).
- The "learn from my games" step is much weaker evidence: one tiny Connect-4-mini test did not improve the model. Claude fixed what made it worse (copying weak players’ moves, and copying winners too hard at 80%), but cannot claim it makes a model stronger in general.
- Claude did not compare against other RL algorithms (Q-learning, PPO and so on), so there is no claim that this one is better or worse than them.
- Each row rests on only 8 to 30 games, so read trends, not single numbers.
8. Best of five: merging several runs into one model
- Idea: train five variants of the learner (full recipe, no root noise, no temperature, few searches, no symmetry views), score them all the same way, keep the best, and then merge all five into one student model.
- How the merge works (distillation): the five models answer together as a committee, and the better a model scored, the more its answer counts. A student network, which starts as a copy of the best model, is trained to give the committee's answer by itself.
- Not new science: ensembles (many models voting, like a random forest), distillation and "keep the winner" are old ideas. Claude only wrote a small readable version. Averaging the numbers of separately trained networks does not work, which is why distillation is used.
- Run it:
python run.py best_of tictactoefrom the downloaded package. It writesmodel.npz, the student and the best single model, a pooled games file for the Learn tab, and a report. - Honest rule: the student is only chosen if it scores at least as well as the best single model. In a quick test on tic-tac-toe (20 iterations per variant, 20 games per check) it did not beat the best single model: they were level within noise. Tic-tac-toe is probably too small for this to help; a bigger game such as Connect 4 is where it could show.
How the code works
The package is called rlgames. It is a small copy of AlphaZero's idea, written in plain Python and NumPy so every line can be read. Download it here (it also runs this page).
1. The big picture: the learning loop
- Rules are the only game-specific part. Everything else works for any game that follows the same five-function shape.
- Self-play makes training data without any human: the model plays itself and keeps what happened.
- Fixed opponents never change, so a rising score means real progress, not just "better than yesterday's me".
2. A game is five things
| Function | What it answers | Example (tic-tac-toe) |
|---|---|---|
initial() | What does the game start like? | an empty 3×3 board, X to move |
legal(s) | Which moves are allowed here? | the empty squares, as numbers 0 to 8 |
step(s, a) | What does this move do? (returns a new position, never changes the old one) | put X on square 4 |
result(s) | Is it over? Who won? | +1 / 0 / −1 for the player to move, or nothing yet |
encode(s) | Show me the board as numbers for the network | two planes: my stones, their stones |
A move is one number. Because moves and positions are plain numbers, the search can try a move, look at the result, and try another, without any picture or screen.
3. Choosing one move: tree search (MCTS)
- The network gives a quick guess: which moves look good (the "prior" P) and who is winning (the "value" v).
- The search then checks the guess by imagining moves ahead. It picks the child with the best
Q + c·P·√N/(1+n): Q is how well that move has gone so far, P the network's hunch, and the last part nudges it to try moves it has not visited much. - When the imagined line ends, the value is added back up the line, and its sign flips at every step, because my gain is your loss.
- After N simulations the move that was visited most is played. More simulations means stronger but slower.
4. The network and how it learns
- It is a small "multi-layer perceptron": a few layers of numbers multiplied together, with negative values cut to zero (ReLU).
- Two heads share it: the policy head (a probability for every move) and the value head (one number from −1 to +1: who is winning).
- The targets come from self-play: the policy target is what the search chose; the value target is who actually won.
- Backpropagation is written out by hand in
rlg/net.py(about 70 lines). The optimiser is Adam. A learning step looks at a small random batch of positions, each shown through a random rotation or mirror (symmetry), so what it learns in one corner it knows in all.
5. What this page does with your files
- The page loads Pyodide: Python and NumPy compiled to run inside your browser, in a background worker so the screen never freezes.
- It then loads
rlgames.zip(the same file you can download) and callsrlg/web_api.py. - Files are checked before use: the model must be plain float numbers whose sizes fit one of the games (no pickled code); every move of every game is replayed through the real rules, and games with an illegal move are dropped.
6. How "learn from my games" works exactly
- For every position in a game, the value target is who won from that player's point of view.
- The move target: if the player who moved went on to win, copy their move (40% of the weight on it, the rest on what the network already thought). If the game was a draw, half as strongly. If they lost, leave the network's own opinion alone.
- Games you played count 3× by default, then self-play games are added and the network trains on the mix.
- Moves made by the weak fixed opponents (random, greedy) in a games file are never copied: a lucky win teaches nothing.
- Before and after, the model plays fixed opponents (random, greedy, and perfect for tic-tac-toe) and also the model you gave it, so you can see if it got better.
- What Claude measured: a Connect 4 model learning from its own run's later games beat the original in head-to-head matches (about 0.7 to 0.9 over 36 games, 4 tries) while self-play alone gave about 0.55. A tiny Connect 4 mini model from a very short run did not improve. So learning from a file helps when the file is large and from a reasonably trained model; it is not magic.
7. Where everything lives
| File | What it does |
|---|---|
run.py | The commands: train, learn, play, eval, replay, lab, export, selftest. |
rlg/games.py | The rules of every game behind one shape (Tic-tac-toe, Connect 4 and mini, Othello 6×6, Flock, Morris), including the rotations and mirrors. |
rlg/net.py | The network, backpropagation and Adam, in plain NumPy. |
rlg/mcts.py | The tree search. It works with any "evaluator", so the network and a random play-out are interchangeable. |
rlg/train.py | The learning loop, the settings per game, and the checks against fixed opponents. |
rlg/baselines.py | The fixed opponents: random, greedy, rollout search, a perfect tic-tac-toe player. |
rlg/gamelog.py | Saves every game as one line (just the moves) and replays it. |
rlg/web_api.py | What this page calls: load files with checks, play against the model, learn from games, export. |
rlg/lab.py | The Game Lab: measures a new game (length, draws, first-player edge, skill versus luck) and tests strategy ideas. |
rlg/user_games.py | Where you add a game of your own (Nim is the example). |
8. A few lines you can read
The whole forward pass of the network:
def forward(self, X):
hs = [X]; a = X
for W, b in zip(self.W, self.b):
a = np.maximum(0, a @ W + b); hs.append(a) # layer: multiply, add, cut negatives to 0
return hs, a @ self.Wp + self.bp, np.tanh(a @ self.Wv + self.bv)[:, 0] # policy scores, value (-1..+1)
The choice inside the search (who to explore next):
q = np.divide(node.W, node.N, out=np.zeros_like(node.W), where=node.N > 0) # how well has each move gone so far i = int(np.argmax(q + c_puct * node.P * math.sqrt(tot + 1) / (1 + node.N))) # plus the network's hunch, plus curiosity
One self-play game, and what it keeps:
while game.result(s) is None:
legal, visits = search(game, s, ev, sims, rng, noise=sw['dirichlet']) # think ahead
a = pick(legal, visits, T, rng) # choose (random early on, best later)
hist.append((game.encode(s), pi, s.turn)); s = game.step(s, a) # remember the position and the search's opinion
# at the end every position is labelled with who won: +1 / 0 / -1
9. Add your own game
- Write a class with the five functions in
rlg/user_games.py(about 60 lines).python run.py lab yourgamethen measures it andtraincan teach a network (add a settings line inrlg/train.py). - This page plays only the games listed on it, because it needs a board picture for each.
Results from Claude's own runs
| Game | Time | What it reached | How far to trust it |
|---|---|---|---|
| Tic-tac-toe | 0.4 min | 0 losses to the perfect player from iteration 40 | Solid (a perfect opponent exists) |
| Connect 4 mini | 0.7 min | 1.00 vs random, 0.95 vs greedy, 0.70 vs plain search | Learned; rows are noisy |
| Connect 4 | 1.8 min | 1.00 vs random, 0.93 vs greedy, 0.90 vs plain search | Learned; not proven strong |
| Othello 6×6 | 2.3 min | 1.00 vs random, 0.94 vs greedy, 1.00 vs plain search | Learned; not proven strong |
Score = wins plus half the draws, out of 1. Single rows rest on 8 to 30 games: read trends, not single numbers. A GPU does not help here: about 80% of the time is search and game rules in Python; the network is under 20%.
python run.py lab morris) is the other half: give it the rules of a new game and it plays thousands of games with players of different strength, then reports game length, draws, first-player edge, how much skill matters and how many truly different openings exist. It can only find strategies written in the features you give it.Why AI invented games
I asked AI to code chess, shatranj, shogi, xiangqi, draughts, dama, Go, Othello, backgammon, mancala, Connect 4 and more. Each one taught AI a trick. Then I asked a different question: what happens if AI summarised all these experience and start innovate new kind of game? Chapters 59 and 60 are the answer.
Chapter 59: Flock
A game with one kind of stone and three rules, where a stone's power depends on its neighbours.
The rules
- Move: slide in a straight line over empty squares, as far as your flock is big (touching stones of your colour, up to 3). Alone you move 1; in a clump of three you move 3.
- Capture: after you move, an enemy stone touching the stone you moved, with another of yours right behind it, is captured (a sandwich). Only the stone that moved captures.
- Win: capture 3 stones, or leave the other side with no move. After 100 moves, more stones wins. You may not step straight back.
The idea behind it
- In chess a queen is always a queen. Here the same stone is slow alone and fast in a crowd, so every turn is a choice between safe and slow and fast and exposed.
- Easy to teach first. Claude wrote the three rules, then asked: can a new player say them back after one lesson? The stone shows its range as a number, so the main rule is on the board.
- One kind of piece. Chess has six pieces to memorise. Flock gets its variety from neighbours instead.
Self-played summary
- Result: a depth-3 computer beat a depth-1 computer 12–0 on 6×6 and 14–0 on 5×5. In 600 random games per board, Light won 248 and Dark 237 (5×5), and Light 220 and Dark 242 (6×6): side advantage looks small.
- How the computer thinks: alpha-beta search, captures tried first, a score of 100 per stone plus a little for range and mobility. Easy = depth 1 plus noise; Normal 3; Hard 5; Master up to 9 within 2.4 s.
- Honest limit: there are no human experts for a new game, so the levels are only as good as the self-play that tuned them.
Chapter 60: Runes
Claude's second invented game, with dice. The number you roll chooses which old game's magic you may cast.
The rules
- Roll two dice, pick one. Doubles give both. Spend the die to step one square (8 directions, capture by stepping on), or cast its spell.
- Win: capture the enemy Mage (only a Mage can capture a Mage), or end your turn on the enemy Throne and still be there when your next turn starts. After 60 turns each, more Apprentices wins.
| Die | Spell | Borrowed from |
|---|---|---|
| 1 | 🛡 Ward | Royal Game of Ur (safe squares) |
| 2 | 🔀 Swap | Senet |
| 3 | 🐴 Leap | Chess knight |
| 4 | ✨ Summon | Shogi drops |
| 5 | 💜 Charm | Othello flips |
| 6 | ⚡ Bolt | Xiangqi cannon |
The idea behind it
- Dice decide which magic is available; you decide which of two to use. A 6 is not always the best die, so luck gives variety but choice still matters.
- Borrow, don't invent everything. Each spell is a trick Claude had already used in an older chapter, so the engine reused tested ideas.
- Claude's first try, Arcana (with mana), felt unsure, so Claude replaced it instead of patching it. Throwing a design away early was cheaper than tuning it.
What dice change for a computer
- Search gets a third kind of step, a chance node: the dice are rolled before each turn and the score is averaged over a few sampled rolls (2 or 3 here; all 36 would be too slow). This is a cheaper cousin of the backgammon method (expectimax).
- A turn can hold two actions (doubles), so the search must know whether the next action is still mine: same sign if yes, flip the sign if the turn passed.
What self-play changed
| Version | What I saw | Change |
|---|---|---|
| 1: a die for every action, three on doubles | Games lasted about 3 turns; a Mage could be walked to the Throne or hit by a Leap almost at once; luck decided everything | Pick one die only (doubles give two) |
| 2 | About 5 turns; skill starts to show, but stepping on the Throne won instantly | Hold the Throne through one enemy turn |
| 3 | A lone Apprentice could still end the game | Only a Mage can capture a Mage |
| Final | About 8 turns per game | A depth-3 computer beats depth-1 31–9 as Light and 31–9 as Dark (40 games each way) |
- Honest limits: the computer mostly steps and Leaps; Charm and Summon are rarely used because they need a 5 or 4 and a matching board. 40 games cannot prove whether Light has a first-move edge (depth-2 against depth-2 split 24–16). Runes has dice, so the learner on this page cannot play it yet.
Seven lessons that held for every game
- Keep the rules in one place that never draws. Easy to test with a bot, easy to put a new screen on.
- A move is one small value (an integer or a short path) you can list, compare, undo and send to a search.
- make and unmake beat copying in a search, if a test proves undo restores the exact position.
- Tune by self-play, not by feeling. Claude's first Flock was drawn to death; one rule fixed it, and Claude only knew because it counted the games.
- Repetition is the enemy of every perfect-information game. Decide how yours ends before you build it.
- Show the rule on the board (the range number on a Flock stone) so players learn without reading.
- Say honestly what is untested. A new game has no experts; the levels are only as good as the tuning.
Full write-ups are in the wiki pages for Chapters 59 and 60. You can load a Flock model and play it on this page.