This is a stdlib-only Python recreation of Donald Michie’s Matchbox Educable Noughts And Crosses Engine from 1961. It proves that the unplugged matchbox activity works at kid scale and shows what the class will see.
python3 menace.py # 2000 games vs a random opponent (~0.2 s)
python3 menace.py --opponent careful # opponent wins/blocks when it can
python3 menace.py --games 500 --seed 7 # change the length and the dice
It needs Python 3.12 or newer and no other packages. Each run takes well under a second.
Each fact below comes from Michie (1963), “Experiments on the mechanization of game-learning, Part I”, The Computer Journal 6(3), pp. 232–236 (scan).
| Michie’s matchbox machine | This prototype |
|---|---|
| “Every one of the 287 essentially distinct positions which the opening player can encounter … is represented by a separate box” | One box per position, with rotations and reflections merged. The script counts 304 boxes for MENACE’s moves 1–4, which matches the figure modern rebuilders use. Michie’s 287 is smaller. We couldn’t find a source that explains the gap; Rodney Brooks notes the same mismatch (Brooks). See EXPERIMENTS.md, MENACE. |
| Beads per move by stage of play: 4, 3, 2, 1 (Table 2) | START_BEADS |
| When it “has done badly, it is ‘punished’ by confiscation of the selected bead” | Loss: −1 bead |
| “a draw was reckoned a good result, and received a unit bonus. A win … was rewarded by three extra beads” | Draw +1, win +3 |
| “Considerations of symmetry … reduce these to four” moves | distinct_moves() keeps one move per symmetry class |
| The machine was “equipped to function as the opening player” | MENACE plays X and moves first |
Where we differ:
Boxes needed for MENACE's moves 1-4: 304 (1 + 12 + 108 + 183), plus 34 one-choice boxes for move 5.
MENACE (X, plays first) vs random opponent (O), 2000 games, seed 1961
games | win draw loss | bar (#=win .=draw)
1-200 | 64% 13% 24% | #########################.....
201-400 | 74% 7% 20% | #############################...
401-600 | 70% 11% 18% | ############################....
601-800 | 76% 8% 16% | ###############################...
801-1000 | 83% 8% 8% | #################################...
1001-1200 | 77% 11% 12% | ###############################....
1201-1400 | 79% 8% 14% | ################################...
1401-1600 | 82% 8% 10% | #################################...
1601-1800 | 81% 9% 10% | ################################....
1801-2000 | 88% 6% 7% | ###################################..
Boxes opened so far: 330
Opening box beads: corner=873, edge=1664, centre=2011
Against the careful opponent (--opponent careful --games 3000 --block 300), losses drop from 19% to about 0% after the first 300 games. Wins then climb from 5% to 44% as MENACE finds traps the opponent can’t see. By the end, nearly all the beads in the opening box are on the centre square (centre=4591).
We also ran five other seeds against the random opponent (1–5). Every one improved: wins in games 1–1000 ranged from 69% to 82%, and wins in games 1001–2000 from 80% to 87%.