Back to the paper

5×5 Radius + Drifting Mines

Skill-spread 0.71 · Clues count mines over a 5×5 region while mines wander each turn.

Mines left
40
Lives
3
Moves
0
Agent playback
Difficulty

Left-click reveals · right-click flags (long-press on mobile). Or hand it to an agent above and watch it play — PAFG is the paper's fixed symbolic solver, PAFG-LLM is the mechanic-adapted one.

The mechanic

The highest-lift mechanic in the archive — it best illustrates how far a generated variant can drift from canonical Minesweeper while staying playable. Two mechanics compose: adjacency is widened to a 5×5 (radius-2) neighborhood so every clue counts mines over 24 surrounding cells, and mines drift — each turn every unflagged mine has a 30% chance of wandering into an adjacent empty cell. Flagging a mine pins it in place, which keeps flagging meaningful as a deduction tool. You start with 3 health because the moving hazards make a single life unforgiving.

How to read the board

The rule in code

The generated mechanic this game runs. The browser engine is an algorithm-faithful port of it.

class Radius2MooreNeighborhood(Neighborhood):
    """24 cells in a 5x5 box — every clue counts mines over this whole region."""

    def offsets(self):
        return [(dr, dc)
                for dr in range(-2, 3)
                for dc in range(-2, 3)
                if (dr, dc) != (0, 0)]


class DriftingMines(MineBehavior):
    """Each turn, every unflagged mine has drift_prob chance of walking into an
    adjacent unrevealed, unflagged, non-mine cell. Flagged mines stay pinned."""

    DEFAULT_DRIFT_PROB = 0.3

    def on_post_action(self, board, game, action):
        moved = False
        mines = [(r, c)
                 for r in range(board.config.rows)
                 for c in range(board.config.cols)
                 if board.grid[r][c].is_mine and not board.grid[r][c].is_flagged]
        for (r, c) in mines:
            if self._rng.random() >= self.drift_prob:
                continue
            candidates = [(nr, nc) for nr, nc in board.neighbors(r, c)
                          if not board.grid[nr][nc].is_revealed
                          and not board.grid[nr][nc].is_flagged
                          and not board.grid[nr][nc].is_mine]
            if candidates:
                dst = self._rng.choice(candidates)
                if board.move_mine((r, c), dst):
                    moved = True
        if moved:
            board.recompute_adjacency()

More mechanics to play

Telegraphed MinesA rotating subset of mines flashes a warning each turn.Ranked Neighborhood InfoClues show comparative rank, not absolute mine counts.Checkerboard RevealCascades skip every other cell, leaving a hidden lattice.Ripple RevealReveals expand in rings that halt at the first numbers.