Rock Scissors Paper Game
Code Battle
한글로 보기
Check the rules of the game, fill in the following functions, select the opponent, and click the Start Game button to start the battle.
Scissors are 1, Rock is 2, Paper is 3
Scissors win Paper, Rock wins Scissors, and Paper wins Rock.
1 point if you win with Scissors, 2 points if you win with Rock, 3 points if you win with Paper

My Code (JavaScript)

Opponents

Online battles are played between signed-in members. Sign in to join.
If you or the opponent's screen is not visible, the communication speed will be slower.
TURN
WIN
0
LOSE
0
ROUND
WIN
0
LOSE
0
GAME
WIN
0
LOSE
0

Game Log

Recent logs are displayed at the top.

Code Arena

Enter your saved code and other members challenge it. The record grows while you are away.
Entering and challenging require a signed-in account. The list and the code are readable without signing in.
See the entry list

Where strategy in this game starts

People call rock-paper-scissors luck. But here the winning hand decides the points, and a round is 100 turns. Over 100 turns luck averages out, and what is left is the scoring rule and your opponent's habits. Below are three strategies and the results each actually produced.

1. What you win with matters more than winning

Winning with scissors scores 1, with rock 2, with paper 3. So an equal win rate does not mean an equal score. Lay your hand against theirs and write down the score difference:

your score − their score
yours \ theirs Scissors Rock Paper
Scissors 0-2+1
Rock +20-3
Paper -1+30

Look at the paper row. Catching rock earns 3, and losing to scissors costs only 1. If the opponent plays all three hands evenly, paper is worth +0.67 per turn while scissors and rock are both −0.33. That single line beats a random opponent.

function onTurnStart() {
	return 3;              // always paper
}

function onTurnEnd(result) {}

RANDOM wins every game LEVEL 1·2·3 loses every game

2. Habits get read. Including yours

Always playing paper is a habit. Once an opponent counts your frequencies, they switch to scissors. So try the other direction and read their habit instead: next turn, throw whatever beats what they just threw.

var next = 2;

function onTurnStart() {
	return next;
}

function onTurnEnd(result) {
	next = result.opponentchoice % 3 + 1;
}

LEVEL 1 wins every game LEVEL 2·3 loses every game

LEVEL 1 never looks at your previous move, so it walks straight into this rule. LEVEL 2 does something else: it counts the distribution of your last 50 turns, works out the score-weighted value against it, and answers probabilistically. A fixed rule leaves a distribution behind, and distributions get read.

3. A distribution with nothing to read

Then give them nothing to read. There is one set of frequencies where no answer earns your opponent anything. Solve the table above for the mix that drives all three hands to an expected value of zero and you get one half scissors, one sixth rock, one third paper.

function onTurnStart() {
	var r = Math.random();

	if (r < 1 / 2) { return 1; }       // scissors 50%
	if (r < 1 / 2 + 1 / 6) { return 2; }  // rock 16.7%
	return 3;                          // paper 33.3%
}

function onTurnEnd(result) {}

RANDOM · LEVEL 1·2·3 roughly even

Scissors, the lowest-scoring hand, takes half your throws. Paper is attractive precisely because it scores 3, so the scissors that catch it are needed just as often. Hold this mix and your expected value is zero no matter what the opponent does. Where every other strategy loses every game to LEVEL 2 and 3, this one holds even. The price is that it cannot beat weak opponents either.

4. From here it is your turn

The balanced mix is a way not to lose, not a way to win. To win you have to exploit the opponent's lean, and the moment you do, your own distribution leans and becomes readable. Write code that holds the balance and departs from it only when the opponent looks lopsided: it crushes RANDOM and LEVEL 1, and loses every game to LEVEL 2 and 3. When to exploit, when to return to balance, and how to notice that you are the one being read — that is what is left. Paste the code above into the editor and start there.

How a battle runs

  • Code battle is a battle between your code and opponent's code, and the language is JAVASCRIPT.
  • Fill in the code, select the opponent (RANDOM, LEVEL1, LEVEL2, LEVEL3, Online opponent) and then press the game start button will start the match.
  • 1 game consists of 5 rounds, 1 round consists of 100 turns.

The code above only holds onTurnStart and onTurnEnd. Leave the other four hooks (onGameStart, onRoundStart, onRoundEnd, onGameEnd) empty. All six must be present for the code to run.

Results come from 60 games (300 rounds) against each opponent, and a test in the repository re-checks them against the real rule engine. Every opponent except LEVEL 1 carries some randomness, so results vary; “wins every game” and “loses every game” mean 95% or more out of 60.