← Back to all posts

You cannot defeat my dynamically learning rock-paper-scissors bot

Represent your species in the ultimate field of battle.

Mark Henry

Ideal rock-paper-scissors play converges to a 33% winrate given perfectly random play. But humans are not perfectly random. Can we exploit human nonrandomness to beat the 33% baseline?

What you are playing against

A neural net with 1,091 parameters, pretrained on a corpus of human play. It sees the last five rounds (your throw and its throw, one-hot encoded), passes them through a 32-unit hidden layer, and outputs a probability distribution over your next throw. It then plays whatever beats your predicted move.

Diagram of the network: 30 input nodes in five groups of six (one-hot you/bot throw for each of the last five rounds), fully connected to 32 hidden ReLU units, fully connected to three softmax outputs labelled rock, paper, scissors.
The whole network. Thirty inputs, thirty-two hidden units, three outputs. The two filled input nodes show one round encoded: you threw paper, the bot threw scissors.

After you throw, the net takes your move as a training example and does sixteen steps of gradient descent (Adam, learning rate 0.01): one step on the round that just happened, fifteen replaying rounds sampled from the last forty-eight. Then it predicts again.

Gwern thinks that this is how personalized LLMs should work.

Results

In this configuration, a naive, untrained network can download a simple opponent in 20 rounds.

Fresh weights against scripted opponents. Margin is win% minus loss%, 20 seeds. "Beat bot’s last" plays whatever would have beaten the bot’s previous throw; "win-stay, lose-shift" repeats after a win and beats the bot’s last throw after a loss; "counter the counter" assumes the bot will counter its last throw and counters that; "markov exploiter" is a second bot that models this one’s throws by its previous two and counters them. "Never repeat" is a two-way coin flip, against which the ideal margin is +50%.
alogrithmic opponentmargin, first 30margin, first 200
always rock+97%+100%
cycle R,P,S+81%+97%
pattern R,R,P+86%+98%
pattern R,P,P,S,R+68%+95%
beat bot’s last+47%+92%
win-stay, lose-shift+46%+92%
never repeat+15%+25%
counter the counter+79%+97%
random−0%+1%
markov exploiter+5%+16%

But because the typical website visitor is just going to play a couple rounds, I've decided to give it a head start by pretraining it on a corpus of 266,415 rounds of human play, from 911 players across four published experiments: Brockbank and Vul, Arai et al., and Komai, Kurokawa and Kim.

What does this get us?

Three starting points against scripted opponents. Self-play: 400 rounds against a second learning net. Humans: one pass over 911 real players. The human prior is roughly a wash here: a little slower on some patterns, a little faster on others, and better on the coin-flip "never repeat", because it starts out expecting people to shift.
opponentmargin, first 30 roundsmargin, first 200 rounds
untrainedpretrained
(self-play)
pretrained
(humans)
untrainedpretrained
(self-play)
pretrained
(humans)
always rock+97%+93%+93%+100%+99%+99%
cycle R,P,S+81%+80%+83%+97%+97%+98%
pattern R,R,P+86%+77%+74%+98%+97%+96%
pattern R,P,P,S,R+68%+55%+63%+95%+93%+95%
beat bot’s last+47%+50%+39%+92%+92%+91%
win-stay, lose-shift+46%+32%+35%+92%+89%+90%
never repeat+15%+25%+30%+25%+25%+27%
counter the counter+79%+57%+83%+97%+94%+98%
random−0%+4%−6%+1%−1%+1%
markov exploiter+5%+4%+6%+16%+15%+12%
Against held-out humans. Twenty percent of the players in the first four corpora were held out from pretraining; all of Komai’s players were, as an out-of-distribution test resembling a blog visitor: fifty throws, then gone. Replay is open-loop: the person’s throws are fixed history, so whatever they would have done in reaction to this bot’s throws is not in the data, which cuts against the bot. Self-play pretraining is omitted: it was within a point of untrained on every corpus. Pretrained on humans, the bot finished ahead against 73% of the fifty-round players, versus 61% untrained.
held-out corpusmargin, first 30 roundsmargin, all rounds
untrainedpretrained
(humans)
untrainedpretrained
(humans)
human vs. human (Brockbank v1)+5%+10%+11%+12%
vs. fixed-pattern bots (Brockbank v2)+15%+21%+43%+44%
vs. adaptive bots (Brockbank v3)+4%+13%+13%+16%
vs. online perceptron (Arai 2025)+7%+13%+19%+22%
vs. GP model, 50 rounds (Komai 2022)+5%+10%+8%+13%
all held-out (726 players)+6%+11%+18%+21%
Line chart of bot margin per round over the first 100 rounds against 726 held-out players, for fresh weights, self-play weights, and weights pretrained on humans. The humans-pretrained line starts higher and all three converge by around round 40.
Learning curve against 726 held-out players. Mean margin per round, smoothed over seven rounds. The head start from pretraining on humans is largest in the first thirty rounds and never fully closes; self-play buys nothing.

How to beat it

If you are in the corpus distribution, you have the following weaknesses:

What humans do, over all 357,007 throws in the five corpora. Every cell should be 33%. Up means playing what would have beaten your last throw (rock → paper), down means playing what it beats (rock → scissors). The first-throw row hides the biggest bias in the data because the populations disagree: the American participants opened with paper 40–45% of the time, the Japanese participants 20%.
tendencywhat 1,637 people did
any throwrock 32%paper 33%scissors 35%
first throwrock 34%paper 30%scissors 35%
after a winstay 28%up 39%down 33%
after a lossstay 28%up 35%down 37%
after a tiestay 30%up 34%down 36%
vs. opponent’s last throwbeat it 33%copy it 33%lose to it 34%

The masters say that if you meditate upon the above table and let go your conscious self, you will transcend your biases.

Some also say that you can tick the "cheat" checkbox and see what the bot predicts you will do.

Or reject your human fallacies, and roll a die.