Rock paper scissors against a model that learns how you throw.
▶ Play it — keyboard works immediately, camera optional
Asked to be unpredictable, people over-alternate, avoid repeating themselves, and switch after losing. Those are patterns, and patterns are learnable. Give it twenty rounds and watch the line climb off 33%.
Rather than commit to one theory of how you play, the model runs several and
lets the evidence decide. Each round every expert takes a loss equal to the
surprise of what you actually threw, and its weight is scaled by
exp(−η · loss) — the Hedge algorithm.
| Expert | Its theory |
|---|---|
uniform |
you are genuinely random — the safety net |
favourite |
you have a preferred throw |
markov-1/2/3 |
what you throw after any one, two or three moves |
win-stay |
how you react to winning and losing — usually the strongest |
second-guess |
you are trying to out-think it |
Hedge is the right combiner rather than "use whichever expert has been best" because its regret against the best single expert in hindsight grows as O(√(T log N)). The ensemble can't end up much worse than whichever theory turns out to be right — including the uniform one.
That is the test that matters. Anything looks clever on biased data; a predictor that "beats" a fair coin is one that has fooled its own author.
| Opponent | Model win rate |
|---|---|
| truly random | 32.9% — chance is 33.3% |
| avoids repeating itself | 53.8% |
| 70% rock | 79.2% |
| win-stay, lose-shift | 99.6% |
| cycles rock → paper → scissors | 99.6% |
| always rock | 100% |
Against a random player the uniform expert ends up holding 90% of the weight. It correctly concludes there's nothing to learn.
It also shows a real learning curve — on a period-8 pattern with 20% noise it goes from 60% in the first 25 rounds to 82.7% over the last 150.
The browser test originally generated its "random" player with a hand-rolled
LCG: (s * 1103515245 + 12345) & 0x7fffffff. The model scored 39.7% against
it — correctly, because that generator's low bits aren't random and
floor(r * 3) inherits the bias.
Testing "does it beat randomness" with a predictable generator tests the
opposite of what it claims to. It now uses crypto.getRandomValues with
rejection sampling (256 isn't divisible by 3, so a plain modulo would favour
rock and paper), and the model settles at 25–34% across runs.
It commits before it sees you. The model picks its throw before your move is registered, and the committed move is revealed afterwards. Choosing after would make it unbeatable and pointless.
The hand shapes are not learned, deliberately. Rock, paper and scissors are separated by which fingers are extended — a geometric question with an exact answer. Training a model to rediscover that would be ceremony. Extension is measured against the hand's own palm width so it works at any distance, and an ambiguous shape returns nothing rather than stealing a round off you.
git clone https://github.com/Devapriyan-S/mind-reader-rps.git
cd mind-reader-rps
npm test # 48 checks, no browser needed
python -m http.server 8000 -d web # open http://localhost:8000The predictor is a dependency-free ES module:
import { MindReader } from "./web/js/predictor.js";
const ai = new MindReader();
const { move, belief } = ai.choose(); // commits before seeing you
ai.observe(playerMove, move); // reweights every expert
ai.tally(); // { wins, draws, losses, rounds }
ai.readout(); // "after losing with rock you usually play paper"
ai.ranked(); // every expert, its weight, and what it currently believes- No opponent modelling of the model. A player who realises it's exploiting win-stay can invert deliberately, and it will take a few dozen rounds to adapt. A proper solution would be a regret-minimising strategy that mixes toward Nash when it detects being exploited.
- η is fixed at 0.55. Tuning it per-player, or annealing it, would adapt faster early and be steadier late.
- The experts are hand-picked. They cover the patterns the human-RPS literature reports; a player with an unusual habit outside that set gets treated as random.
- Hand tracking needs decent light, and MediaPipe's landmarks degrade with a busy background. The keyboard path has no such problem.
MIT licensed. Built by Devapriyan Sampath — portfolio · LinkedIn · devapriyan1723@gmail.com