THE SEVENTH RODEO

In 2013, a university student wrote an Uno bot for a C assignment.
Six AI challengers and fourteen million games later, it still hadn't lost.
Your turn.

Download the starter pack  Submit an entry

01The story so far

The bot is mgim006 — a few hundred lines of hand-tuned heuristics from ENGGEN 131, University of Auckland, 2013. The metric is the official one from the assignment: cumulative points over millions of four-player games (winner takes the sum of the losers' hands).

Since then it has faced six increasingly sophisticated AI-written challengers — scored heuristics, card counting, tempo control, probabilistic modelling. Best honest result before this year: a tie. It took an evolutionary search — thirty tuned constants, half a billion simulated games of selection pressure — to finally produce a bot that beats it. Pure reasoning never did: a fresh Claude given only the spec, one attempt, no testing, lost by 1.8 points-share and finished dead last against the field.

So that's the invitation. Write a bot — by hand, with your favourite model, however you like — and see if you can do what six challengers couldn't.

02The bar you're clearing

house · incumbent

mgim006

human, 2013
±0.00

The champion. Hand-calibrated to within one mutation of a local optimum, twelve years early.

house · champion

Ouroboros

evolved by self-play, 2026
+1.34

200 generations of eating its own tail. Never saw mgim006 until the verdict. Beat it anyway.

house · cautionary tale

Draft One

Claude, one shot, no testing
−1.16

Clean, sensible, legal — zero penalties in 40M games. Still lost. Reasoning alone doesn't calibrate weights.

Numbers are points-share margin vs mgim006 in the main-event ring, 20M games, 24 seat permutations, ≥3σ decision rule (σ ≈ 0.017pp at 20M). Anything within ±0.05pp is a tie.

03How it works

  1. Download the pack. The exact referee, the tournament engine, three sparring bots, a legal starter bot, and the full rules — one gcc command and you're simulating ~75,000 games a second.
  2. Build your bot. One C file, 2013 student rules: no globals, no statics, no malloc, no extra includes. Entry point int youralias_Play(GameState *). The interface contract is documented in mystrat.c — and yes, the whole spec is written so you can paste it straight into an LLM.
  3. Test locally. The pack's README tells you the statistics you need: differences under 0.5pp need millions of games. Don't trust a 10,000-game hunch.
  4. Submit it. Your bot runs two official rings of 20,000,000 games each against the house. Results by reply, leaderboard below.
The two rings.
Rookie ring: you · mgim006 · naive · naive — can you beat the incumbent with weak players feeding the pot?
Main event: you · mgim006 · Ouroboros · Draft One — the full table.

Beat mgim006 on points at ≥3σ in both rings: you've done what no hand-written bot ever has. Beat Ouroboros too: the top spot is yours.

04Submit

Paste your .c file into the body of an email (no attachment needed):

To: entries@seventh.rodeo
Subject: RODEO ENTRY: <your alias>
Body: your complete .c file, pasted as plain text

Open a pre-addressed email

05Leaderboard

#botauthor rookie Δ vs mgim006main Δ vs mgim006verdict
1Ouroboros houseevolution +1.29+1.34beat mgim006
2mgim006 houseMark, 2013 incumbent
3Draft One houseClaude, one shot −1.78−1.16fell short
?your botyou ?? 

Points-share difference vs mgim006, percentage points. Positive = ahead. Updated as entries are judged.

06The spec, for you or your model

Everything below is also in the pack's README. It is deliberately complete — paste it into your LLM of choice and it can write a legal bot first try. Whether that bot is any good is a different matter entirely.

RULES (exactly as the referee implements them)
- 4 players, 7 cards dealt. 108-card deck: per colour one 0, two each 1-9,
  two Skips, two Reverses, two Draw-Twos; plus 4 Wilds, 4 Wild-Draw-Fours.
- Flip until a non-wild tops the pile. Random first player and direction.
  The first flipped card's effect is NOT applied.
- You MUST play if able. Playable = wild (always) / colour match (top card's
  colour, or called colour if top is a wild) / NUMBER matching top NUMBER's
  value / special (Skip, Reverse, Draw-Two) matching top special's type.
- Skip: next misses a turn. Reverse: direction flips. Draw-Two: next draws 2,
  misses turn. Wild-Draw-Four: next draws 4, misses turn; playable anytime.
- Cannot play: return -1, draw one. Illegal return or wrongful -1 = PENALTY
  (draw 2, forfeit turn).
- Deck empty: reshuffle discards except top card.
- First to 0 cards wins immediately, scores the sum of the other three hands
  (numbers face value, specials 20, wilds 50). METRIC = cumulative points.

INTERFACE
  int youralias_Play(GameState *gameInfo);
- Return the 0-based index into yourCards of the card to play.
- Wild or Wild-Draw-Four: return colourConstant + index, e.g. GREEN + i.
  Colour constants: RED 10000, GREEN 20000, BLUE 30000, YELLOW 40000.
- Return -1 only when nothing is playable.
- GameState gives you: your hand, full discard pile, direction (LEFT means
  next player is (pos+3)%4, RIGHT means (pos+1)%4), everyone's card counts,
  every player's last called wild colour, cumulative scores.

CODE RULES (2013 student rules, enforced)
- One file, plain C89. No globals, no statics, no malloc, no extra includes,
  no I/O. All functions prefixed youralias_. Compiles with gcc -O2.