CASE STUDY: #P004 25 MIN READ

How We Built Midnight Poker's AI Engine

We wanted to build a poker game where the AI actually thinks. Midnight Poker uses Monte Carlo simulations and expected value calculations to make decisions. Here's what we learned building it.

Monte Carlo (MCTS) Sklansky-Chubukov TypeScript Web Audio Synthesis Glassmorphism UI Pot Odds Logic
Midnight Poker - Table View

The Dream: Beyond Randomness

Most online browser games are built to entertain for three minutes. They use simple logic: "If I have a pair, I bet." But Texas Hold'em is a game of information asymmetry and expected value (EV). To make a game that humans would respect, the AI had to be rational.

We wanted a game where a "Casual" bot plays like a drunk vacationer in Vegas, while a "Pro" bot plays like a sharp-eyed professional in a Macao private room. Achieving this meant building a custom probability engine from the ground up.

Phase 1: The AI Brain Trust

The Monte Carlo Simulation (MCTS)

The core of our PRO difficulty is the Monte Carlo Simulator. When a player bets $500 on the Turn, the AI doesn't just look at its two cards. It pauses and "simulates" 500 different futures.

It randomly assigns cards to its opponents from the remaining deck and deals out the River card. By repeating this process 500 times, the AI arrives at its Equity—the true mathematical probability of winning the pot. It then compares this to the Pot Odds (the risk/reward ratio of the current bet).

// The core simulation loop
public calculateEquity(holeCards: Card[], community: Card[], opponentCount: number): number {
    let wins = 0;
    for (let i = 0; i < 500; i++) {
        const deck = this.getFreshShuffledDeck(holeCards, community);
        const simBoard = [...community];
        // Deal remaining board cards
        while (simBoard.length < 5) simBoard.push(deck.pop()!);
        
        // Check if AI hands wins against N random opponents
        if (this.isWinningHand(holeCards, simBoard, opponentCount, deck)) {
            wins++;
        }
    }
    return wins / 500; // Returns probability (0.0 to 1.0)
}

Sklansky-Chubukov Pre-Flop Logic

Before any cards are even on the table, the AI uses a modified version of the Sklansky-Chubukov ranking system. This isn't just a list of "good hands"; it's a dynamic scoring system that considers Position (the Dealer bonus) and Tightness. A Pro bot won't even look at 7-2 offsuit; it's a mathematical death sentence.

Phase 2: The Trench Wars (Development Post-Mortem)

In the final 48 hours before launch, we hit three bugs that almost broke the game. Here's what happened and how we fixed them.

Incident #001: The Negative Stack Paradox
The Problem: When a player went "All-in" with $340 against a $500 bet, the engine was deducting the full $500. This resulted in the player having a -160 stack. In a casino, this would be a riot; in a browser game, it was a logical deadlock.
The Fix: We implemented a clamp mechanism in the processAction method. Now, a bet can never exceed the player's currentStack + currentBet. We also added a "refill" logic where bankrupt bots are automatically topped up to $1000 at the start of a new hand to keep the game flowing.
Incident #002: Header Layout Clipping
The Problem: On narrow screens or when adding the "Home" button, the top-right header buttons (Difficulty, Rules, Sound) would stack vertically, overlapping the Poker table and making the game unplayable.
The Fix: We refactored the .header-actions CSS to use display: flex with a fixed height: 40px and align-items: center. By using a horizontal gap and semi-transparent glassmorphism backgrounds, we ensured all utility buttons remained accessible without ever obstructing the board.
Incident #003: The Iframe Prison
The Problem: When users clicked the "Home" (EXIT) button, the browser would refresh *inside* the iframe/modal, but the main website remained stuck on the game screen. Users felt "trapped."
The Fix: Redirection logic was upgraded from window.location to window.top.location.href. This breaks the iframe context and returns the user to the main site hub. We also implemented a Custom Exit Modal instead of the browser's ugly native `confirm()` to maintain the premium visual style.
"After fixing the negative stack bug, we added validation checks before every bet. Overkill? Maybe. But no more -160 chip stacks."

Phase 3: The "Midnight" Aesthetic

We went with a dark theme. Deep indigo backgrounds, gold accents, no bright casino neon. The goal was something that looks good at 2am when you're actually playing.

  • 1. Pure Glassmorphism

    Every UI element uses backdrop-filter: blur(12px). This allows the subtle movements of the poker table to be seen through the action buttons, creating a sense of depth and realism often missing in web games.

  • 2. Performance-First Sound

    We didn't just play MP3 files. We used the Web Audio API to synthesize card "swishes" and terminal-like beep tones. This results in zero latency and a significantly smaller file size for users on mobile connections.

Coda: Building with AI

This game was built using the Antigravity AI Agent (powered by Google Gemini) as a coding assistant. It handled file navigation, suggested layouts, and helped debug issues.

When I described wanting a "high-end lounge" feel, Antigravity generated around 400 lines of CSS that I then tweaked. Total dev time: about 48 hours. Would have taken longer solo, but the AI sped up the boring parts.

5,200+ Lines of Custom TS
0.02ms Logic Latency
48h Total Dev Time
Replayability

READY FOR THE RIVER?

Try the Pro difficulty. The AI runs 500 Monte Carlo simulations per decision. It's not unbeatable, but it doesn't make rookie mistakes.

PLAY MIDNIGHT POKER LEARN MORE