Under the Hood

How the Hearts AI Works: Determinized Monte-Carlo

Published September 12, 2026 · LK Forge

13
tricks scored each deal
26
penalty points in play (hearts + Q♠)
moon
shooting it flips your 26 to 0
0
servers — runs in your browser

The opponents on LK Forge Hearts face a problem the chess engine never does: they can't see your cards. Hearts is a hidden-information game, so a search that assumes it knows the position would be searching a fiction. The Hard engine handles this with a classic technique — determinized Monte-Carlo.

Turn one hidden game into many open ones

The idea is to guess, repeatedly, and average. The engine takes the cards it has seen — its own hand and everything played so far — and deals the unseen cards out into a complete, plausible hand for everyone. That "determinized" world is a normal open game it can solve. It does this many times with different plausible deals, plays each one to the end, and scores the result. The card that gives the lowest expected points across all those imagined games is the one it plays.

1 · SAMPLE 2 · PLAY OUT 3 · AVERAGE Deal the unseen cards many plausible ways Play each imagined game to the last trick, score it Pick the card with the lowest expected points lkforge.com

Determinized Monte-Carlo: replace one hidden game with many complete guesses, solve each, and average. The guesses cancel out; a genuinely good card wins.

// determinized Monte-Carlo card choice (schematic)
function chooseCard(view) {
  const total = new Map();
  for (let s = 0; s < SAMPLES; s++) {
    const world = dealUnseen(view, rng);        // one plausible full deal
    for (const card of legalCards(view))
      total.set(card, (total.get(card) || 0) + playout(world, card));  // points if we play it
  }
  return minBy(total);                           // lowest average points
}

Why guessing works

It seems strange that averaging over wrong guesses gives a good move — but any single deal might flatter a bad card by luck, and the next deal punishes it. Over enough samples those flukes wash out, and the card that is genuinely safe against the range of hands you might hold floats to the top. It is the same reasoning behind our measured study of a determinized-MC card engine, where we ran the method thousands of games deep.

It understands the moon

Hearts has a twist that wrecks naive point-counting: shooting the moon. Take all 26 penalty points and your 26 becomes 0 while everyone else gets 26. Because the engine scores each playout after that moon adjustment, stopping your moon — or going for its own when the cards line up — is not a special case bolted on; it is just another outcome the average already accounts for.

Three levels. Beginner plays loose cards; Medium plays a solid heuristic game (leading low, ducking the Queen); Hard runs the determinized Monte-Carlo search. Hearts rewards reading a range rather than a single hand — which is exactly what sampling many deals does.

That is the whole engine: turn a hidden hand into many open ones, play each out, average, and let the moon fall out of the scoring. Curious how this method holds up under measurement? Read luck vs skill in a card-game AI, or why none of our games are chatbots in Real Game AI, Not a Chatbot.

FAQ

How does the Hearts AI decide its moves?

At the Hard level it uses determinized Monte-Carlo: it deals the unseen cards many plausible ways, plays each imagined game to the end, and picks the card with the lowest expected points. Playouts are scored after the shoot-the-moon adjustment, so it both defends the moon and can shoot it. The whole search runs in a background worker thread in your browser, so nothing is sent to a server.

How can the AI play well when it can't see the other hands?

The AI doesn't need to see them — it guesses. Determinized Monte-Carlo replaces one hidden situation with many complete, plausible ones (deals consistent with the cards played so far), solves each as if it were an open hand, and averages the verdicts. Across enough samples the guesses cancel out and a genuinely good card rises to the top.

What is shooting the moon and does the AI understand it?

Shooting the moon is taking all 26 penalty points in a deal, which flips your 26 to 0 and gives everyone else 26. Because the engine scores each playout after that moon adjustment, it treats stopping an opponent's moon — and going for its own when the cards allow — as just another outcome the average accounts for. No special-case code is needed; the same scoring handles offense and defense alike.

Does the Hearts AI use a neural network?

No — the Hearts AI is a classical search — determinized Monte-Carlo over the shipped rules engine. There is no machine-learned model and no server. Everything runs in your browser.

Take on three sampling opponents.

Play Hearts →