{
  "id": 2807679,
  "title": "22 tests passing, and my solver still told you to click a mine",
  "url": "https://urgent.news/2026/08/23/22-tests-passing-and-my-solver-still-told-you-to-click-a-mine",
  "topic": "tech",
  "section": "Tech",
  "published": "2026-08-23T14:49:13.000Z",
  "source": {
    "name": "Dev.to",
    "slug": "dev-to",
    "url": "https://dev.to/dylanhuang/22-tests-passing-and-my-solver-still-told-you-to-click-a-mine-46d8"
  },
  "original_language": "en",
  "account": "I developed a minesweeper probability solver. This tool accepts a board and returns the probability of each unknown square being a mine, helping to make the cheapest guess when logic runs out. It includes 22 unit tests that all pass. I also cross-checked the solver against an independent brute-force implementation that enumerates every legal mine placement and counts the configurations over 8,000 random boards. The maximum deviation between the two implementations was 5.551e-16, which is essentially floating-point noise. No meaningful disagreement exists between the two implementations.\n\nAfter integrating the solver into a website and testing it across about 300 games, I encountered a board where the solver reported six squares as certain mines. In reality, only two of them were mines. This incident demonstrates how a test suite can sometimes miss a severe bug.\n\nThe solver uses standard constraint counting, where each revealed number serves as a constraint: exactly K mines among N unknown neighboring squares. The solver splits constraints into connected components by shared unknowns, enumerates every legal mine configuration per component indexed by mine count, and then convolves components together, weighting each global total T by the number of ways to distribute the remaining mines among the open cells.\n\nHowever, the solver faces issues when the component's frontier grows beyond a certain size, leading to combinatorial explosion in exhaustive enumeration. In such cases, the solver falls back to a mean-field approximation, which involves iterative relaxation and estimating each cell's share of the residual. These values are not exact and carry no guarantee. When finalizing the probabilities, the solver does not record where each number came from, leading to a situation where both a genuinely safe cell and an estimated 0.9999999999 are treated as mines. This issue arises because the EPS (a tool for absorbing floating-point noise) is applied to a heuristic's output, effectively laundering an estimate into a proof.\n\nThe intended fix was to skip cells living inside approximated components while keeping certainties from exact components. However, despite this fix being measured against known mine positions across 12 Expert boards that triggered approximation, 65 of 244 claimed certainties remained incorrect. The issue is that the global budget computation is not localized. The contamination spreads beyond local approximation, affecting the entire board.",
  "summary": "I wrote a minesweeper probability solver. You hand it a board, it hands back the probability that each unknown square is a mine, so that when logic runs out and you have to guess, you at least guess the cheapest square. It has 22 unit tests. They all pass. I also cross-checked it against an independent brute-force implementation — one that enumerates every legal mine placement and counts — over…",
  "key_points": [
    "22 unit tests pass for minesweeper solver",
    "Solver reports 6 squares as mines in reality 2",
    "Test suite misses severe bug in solver"
  ],
  "editors_take": null,
  "illustration": null,
  "coverage": {
    "outlets": 1,
    "also_reported_by": []
  },
  "ai_generated": true,
  "disclaimer": "Summaries, key points and the editor’s take are written by software from other outlets’ reporting and may contain errors — always check the linked original."
}