Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Mind Reader

Rock paper scissors against a model that learns how you throw.

Live demo Tests License

Play it — keyboard works immediately, camera optional

Mind Reader


You are not random

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%.

Seven experts, combined by multiplicative weights

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.

Which is why it doesn't beat a coin

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.

A bug my own test had

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.

Two design decisions worth stating

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.

Run it

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:8000

The 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

Limits

  • 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 Sampathportfolio · LinkedIn · devapriyan1723@gmail.com

About

Rock paper scissors against a Hedge ensemble that learns your habits — beats patterned players 80-100% while correctly settling at chance against true randomness.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages