Skip to content

emilbob/Game-theory

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

The Standoff

A repeated two-player battle-of-the-sexes game. Two players repeatedly choose moves and only score when their choices line up — but they each prefer a different match to win. The challenge is reading your rival and steering them toward your outcome over many rounds.

The Game

X Y Z
X 150,50 0,0 0,0
Y 0,0 50,150 0,0
Z 0,0 0,0 100,100

Each cell is the points scored by Player A and Player B respectively for a combination of choices. Columns are Player A's move, rows are Player B's.

Example: if both players choose X, Player A gains 150 points and Player B gets 50.

Players only score when they match (the diagonal), but their interests conflict over which match. Crucially, every match splits the same 200-point pie: Z divides it fairly (100/100), while X and Y split it 150/50 in one player's favour. A miss destroys the pie entirely (0/0).

Because fighting can't grow the pie — only shift who gets it, while risking the whole thing — the fair Z is the smart default. This is the classic battle of the sexes: both want to coordinate, neither wants to give in. The edge comes from reading your opponent and pushing for the 150 only when they'll actually concede.

In the web version you face one of seven secret AI strategies, hidden until the end. A "suspects" panel narrows down who it could be as you watch them play, and naming your rival correctly at the end earns a points bonus — so reading the opponent literally pays off.

ZK Mode (educational)

The web app has an optional ZK Mode toggle backed by a Noir zero-knowledge circuit (circuits/standoff). It is a learning exercise, not a feature the game needs. In a single-player browser game the bot runs on your own machine and you could just read its code, so hiding it cryptographically solves no real problem here. ZK Mode exists to explore how commit-and-prove works in a familiar setting; the transferable part is the working Noir + Barretenberg proving pipeline, which would matter in a setting where the bot is run by an untrusted third party (a server, an opponent, an on-chain contract) that you can't inspect.

How it works

  1. Commit. At game start the bot picks a hidden strategy id and a random salt, and publishes a Pedersen commitment hash(strategy_id, salt). This locks in its identity without revealing it — it can't change its story later.
  2. Prove each move. After every round the circuit takes the commitment plus the public game state (the bot's role, the round number, the human's move history, and the move the bot just played) as public inputs, and the strategy_id + salt as private inputs. It proves two things: the private id/salt hash to the published commitment, and replaying that committed strategy over the public history produces exactly the move that was played.
  3. Verify. The proof is checked in the browser; a per-round badge shows verified / failed. Crucially the strategy id stays secret throughout — you learn that the move was honest, never which strategy it was, so the end-game guessing challenge survives.

The circuit covers six of the seven bots. Random/Dice is excluded because its move is a coin flip, not a function of the public history — there is nothing deterministic to prove. To keep ZK Mode from leaking information, its opponent pool is restricted to those six, so a commitment always exists and its presence reveals nothing.

See circuits/standoff/README.md (the circuit) and web/src/zk/README.md (the web wiring) for specifics, encodings, and how to run the tests.

Releases

Packages

Used by

Contributors

Languages