Sitemap

Building an AI Minesweeper Bot: From Constraint Solvers to LLM Reasoning

8 min readFeb 23, 2026

--

Research: {alanh0}

If you’re doing vibe-coding, you can just ignore the previous post about telegram bot development, ask Claude Code to do it for you :D

Anyway, an autonomous Minesweeper bot that combines classical algorithms with LLM reasoning to play the game from beginner to expert difficulty. It uses a layered solver pipeline, real-time browser automation, and a live dashboard — all orchestrated through a Node.js backend.

Here’s how it works.

Press enter or click to view image in full size

Why Add an LLM? Minesweeper Bots Already Exist

Minesweeper bots aren’t new. Open-source solvers using constraint satisfaction and probability estimation have existed for years, and they’re already near-optimal — the math is well understood. So why bring an LLM into this?

The short answer: this isn’t really about Minesweeper.

Minesweeper is a convenient testbed because it has clear rules, measurable outcomes, and a mix of deterministic logic and genuine uncertainty. The interesting question isn’t “can an LLM play Minesweeper?” — it’s “how do you build a system where an LLM collaborates with traditional algorithms, and when does that actually help?”

In real-world applications, you often have a pipeline where most decisions can be handled by rules or heuristics, but some edge cases need judgment. Think fraud detection, medical triage, content moderation — systems where 90% of cases are clear-cut but the remaining 10% benefit from something more flexible. The LLM layer in this bot is a prototype of that pattern: algorithmic solvers handle everything they can, and the LLM only gets consulted on ambiguous positions where the algorithm’s confidence is low.

The other motivation is observability. When the bot makes a move, you can see why — which solver layer made the decision, what the confidence was, and if the LLM was involved, what it was thinking. This kind of transparent decision pipeline is more useful in practice than a black-box model that just outputs moves.

So while the LLM doesn’t dramatically improve Minesweeper win rates (more on that later), the architecture — layered solvers with LLM as a fallback, real-time reasoning visibility, benchmarking across configurations — is the actual point.

The Problem

Minesweeper seems simple on the surface, but solving it efficiently is NP-complete. While many cells can be deduced logically, some positions are genuinely ambiguous — you’re forced to guess. The bot handles the deterministic cases perfectly and attempts smarter guesses when logic alone isn’t enough.

Architecture Overview

The system has four main parts:

  • Browser automation — Playwright controls a Chromium instance, clicking cells and reading the board state from the DOM
  • Solver pipeline — A layered approach that escalates from fast deterministic logic to probabilistic analysis to LLM consultation
  • Dashboard — An Express + WebSocket server with a real-time control panel showing a live screencast, board grid, solver log, and session stats
  • Local game — A self-hosted Minesweeper game, so the bot can play offline without external dependencies
┌─────────────┐      ┌──────────────┐     ┌─────────────┐
│ Dashboard │ ===> │ Express + WS │====>│ Game Loop │
│ (Browser) │ <=== | Server │<====│ │
└─────────────┘ └──────────────┘ └──────┬──────┘

┌────────────────────┤
▼ ▼
┌─────────────┐ ┌──────────────┐
│ Playwright │ │ Solver │
│ (Chromium) │ │ Pipeline │
└─────────────┘ └──────────────┘

The Solver Pipeline

Every turn, the bot reads the board and runs through four solver layers in sequence. It stops at the first layer that produces moves.

Layer 1: Deduction

The fastest and most reliable layer. It applies two simple rules iteratively:

  • Flag Rule: If a numbered cell’s remaining mine count equals its closed neighbors, all closed neighbors are mines.
  • Reveal Rule: If a numbered cell’s mine count is fully satisfied by flags, all remaining closed neighbors are safe.

These rules chain — flagging a cell might make another cell’s constraints solvable. The solver loops until no new moves are found. Every move has 100% confidence.

Layer 2: Constraint Satisfaction (CSP)

When single-cell deduction can’t make progress, the CSP solver looks at groups of cells together. It:

  1. Builds constraints from each numbered border cell (e.g., “exactly 2 of these 4 cells are mines”)
  2. Decomposes the frontier into connected components using union-find
  3. Enumerates all valid mine configurations per component via backtracking
  4. Any cell that’s safe in ALL configurations → reveal. Mine in ALL → flag.

This catches patterns that deduction misses, like the classic 1–2–1 configuration. The backtracking is bounded by component size to keep it fast.

Layer 3: Probability Estimation

When neither deduction nor CSP finds certain moves, we need to guess. The probability solver:

  • Uses CSP enumeration results to compute exact mine probabilities for border cells
  • Falls back to local constraint averaging for cells the CSP couldn’t cover
  • Estimates interior cell probabilities using the global remaining mine count
  • Returns the safest cell as the best guess

Layer 4: LLM Consultation

Here’s where it gets interesting. When the best guess has less than 85% confidence, the bot optionally consults an LLM (via Ollama) for a second opinion. The prompt includes:

  • A text representation of the board
  • The top candidate cells with their safety percentages
  • Instructions to analyze patterns and constraints
Current board state:
0 1 2 3 4 5 6 7 8
---------------------------
0| . . . 1 1 .
1| . . 2 1 1 2 .
2| . . 1 1 2 F .
...

The algorithmic solver found these candidate cells ranked by estimated safety:
(row=0, col=0): 82.3% safe
(row=1, col=1): 79.1% safe
(row=0, col=8): 71.5% safe

The LLM returns a JSON response with its pick and reasoning. If the suggestion is valid (correct coordinates, targeting a closed cell), the bot uses it. Otherwise, it falls back to the probability-based guess.

Reading the Board

The bot reads the board by scanning the DOM. Each cell has an ID like #cell_3_5 (column 3, row 5) and a CSS class that encodes its state:

  • hd_closed — unrevealed
  • hd_flag — flagged
  • hd_type0 through hd_type8 — opened, showing adjacent mine count
  • hd_type10 / hd_type11 / hd_type12 — mine states (revealed, exploded, wrong flag)

A single page.evaluate() call reads all cell states into a structured Board object that the solvers consume.

The Local Game

A self-hosted game with the minesweeper structure.

The local game is a single HTML file with vanilla JavaScript:

  • First click is always safe (mines are placed after)
  • Supports click (reveal), right-click (flag), and double-click (chord)
  • Uses SVG assets for the classic Minesweeper look — 7-segment LED counters, HD cell skins, and the iconic smiley face

Live Dashboard

The control panel streams the browser view via CDP screencast and displays:

  • Live screencast — real-time view of the browser playing
  • Board grid — a styled representation of the bot’s internal board state
  • Solver log — every move with its strategy, coordinates, confidence, and reasoning
  • LLM consultation — when the LLM is consulted, the prompt and response are shown in expandable sections
  • Session stats — games played, win rate, total moves, LLM calls

The dashboard also has a Benchmark tab for running N games automatically and a Matrix tab showing win rates across difficulty/model combinations.

Screencast Challenges

Getting the screencast to stay in sync with the solver was surprisingly tricky. CDP’s Page.screencastFrame only fires when the browser compositor generates new frames. During auto-play, Playwright's CDP commands can starve the frame pipeline.

The fix: take explicit screenshots at key moments (game start, game end) and broadcast them directly as screencast frames. This guarantees the user sees the fresh board before the first move, and the final state (sunglasses face on win, revealed mines on loss) after the last move.

Post-Game Analysis

After each game (when LLM is enabled), the bot generates a post-game summary. It sends the final board state, game stats, and strategy breakdown to the LLM and asks for a brief commentary. The quality of these summaries varies wildly depending on the model — larger models give useful observations about the strategy mix, while smaller ones tend to produce generic filler. It’s a nice-to-have, not essential.

Benchmarking

The benchmark system runs N games at a configured difficulty and tracks:

  • Win/loss counts and rates
  • Move counts and duration
  • Strategy breakdown (how many moves came from each solver layer)
  • LLM call counts

Results are stored in SQLite and displayed in a comparison matrix. This makes it easy to compare logic-only performance against different LLM models.

Results and Honest LLM Assessment

On beginner (9x9, 10 mines), the logic-only solver wins roughly 80–90% of games. Most losses come from genuine 50/50 guesses that no algorithm can resolve.

On expert (30x16, 99 mines), the win rate drops to around 20–30%. Expert boards have far more ambiguous positions, and each guess carries more risk because the mine density is higher.

Press enter or click to view image in full size

The LLM Didn’t Really Help

Let me be blunt: local LLMs don’t meaningfully improve win rates. I tested with several Ollama models — gemma3:27b, llama3, mistral — and the results were disappointing across the board.

The core problem is that local models struggle with spatial reasoning over a text grid. When the bot sends a board state like:

  0|  .  .  .  1           1  .
1| . . 2 1 1 2 .

The model needs to parse row/column coordinates, understand adjacency relationships, count constraints, and cross-reference them — all from a text representation. Most local models at the 7B-27B parameter range can’t do this reliably. Common failure modes:

  • Invalid coordinates — suggesting cells that are already open or out of bounds
  • Ignoring the probability data — the prompt includes algorithmically computed safety percentages, but the model often picks a worse cell
  • Hallucinated reasoning — confidently explaining patterns that don’t exist on the board
  • JSON parse failures — returning malformed responses that the bot has to discard

The probability solver already computes the mathematically optimal guess. An LLM can only improve on this if it spots a pattern the algorithm missed — which requires genuine spatial reasoning ability that local models currently lack.

What Could Actually Improve It

Stronger API models. Claude, GPT-4, or Gemini Pro would likely do better at spatial reasoning over text grids. Their larger context windows and stronger instruction-following make coordinate parsing more reliable. The trade-off is cost and latency — each consultation takes an API call, and Minesweeper generates many ambiguous positions per game.

Visual input. Instead of a text grid, sending a screenshot of the board to a multimodal model (GPT-4V, Claude with vision, Gemini) could work better. Humans solve Minesweeper visually, and vision models might pick up on spatial patterns more naturally than parsing text coordinates.

Fine-tuned specialist model. Training a small model specifically on Minesweeper board states and optimal moves could outperform both general-purpose LLMs and the probability solver. The training data is easy to generate — play millions of games, record every ambiguous position, and label each with the actual outcome.

Monte Carlo simulation. Instead of LLM consultation, running thousands of random game completions from the current state and picking the cell that leads to the most wins would be mathematically rigorous. This is what competitive Minesweeper solvers actually do. It’s slower than a single probability estimate but far more accurate for complex board positions.

Hybrid CSP + Monte Carlo. Use the CSP solver for exact probabilities on small components, and Monte Carlo sampling for large components that exceed the CSP backtracking budget. This would give near-optimal play without any LLM dependency.

The honest takeaway: the algorithmic solver (deduction + CSP + probability) does the real work. The LLM layer is more of a demonstration of how you’d integrate language models into a decision pipeline than a practical improvement. For competitive Minesweeper solving, Monte Carlo simulation would be the next step.

Tech Stack

  • TypeScript — ES modules throughout
  • Playwright — browser automation and CDP screencast
  • Express + WebSocket — real-time dashboard
  • better-sqlite3 — game history and benchmark results
  • Ollama — local LLM inference (optional)

Demo

--

--

VXRL
VXRL

Written by VXRL

VXRL Team is founded by group of enthusiastic security researchers, providing information security services and contribute to the community. https://www.vxrl.hk