Back to the paper

Checkerboard Reveal

Skill-spread 0.72 · Cascades skip every other cell, leaving a hidden lattice.

Mines left
40
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

A generated reveal strategy. The flood-fill from an empty cell only propagates through cells that share the clicked cell's (row + column) parity, so a cascade opens a checkerboard: every other cell in the cleared region stays hidden. Opposite-parity cells at the border are revealed as numbered hints but never used to spread the flood. Skilled players read the exposed checkerboard layer to deduce the interleaved hidden cells; random play just wastes clicks. Standard 8-neighbor adjacency, single life.

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 CheckerboardReveal(RevealStrategy):
    """Cascade that only propagates through cells sharing the clicked cell's
    (r + c) parity. Opposite-parity neighbors are revealed as a border but never
    used as seeds, leaving an interleaved hidden lattice."""

    def reveal(self, board, r, c):
        cell = board.grid[r][c]
        parity = (r + c) % 2
        if cell.adjacent_mines > 0:
            cell.is_revealed = True
            return [(r, c)]

        queue = deque([(r, c)])
        visited = {(r, c)}
        revealed = []
        while queue:
            cr, cc = queue.popleft()
            curr = board.grid[cr][cc]
            if curr.is_revealed or curr.is_flagged or curr.is_mine:
                continue
            curr.is_revealed = True
            revealed.append((cr, cc))
            if curr.adjacent_mines == 0:
                for nr, nc in board.neighbors(cr, cc):
                    if (nr, nc) in visited:
                        continue
                    if (nr + nc) % 2 == parity:          # same parity: keep flooding
                        visited.add((nr, nc))
                        queue.append((nr, nc))
                    else:                                 # opposite parity: reveal, no cascade
                        nb = board.grid[nr][nc]
                        if not nb.is_revealed and not nb.is_flagged and not nb.is_mine:
                            visited.add((nr, nc))
                            nb.is_revealed = True
                            revealed.append((nr, nc))
        return revealed

More mechanics to play

5×5 Radius + Drifting MinesClues count mines over a 5×5 region while mines wander each turn.Telegraphed MinesA rotating subset of mines flashes a warning each turn.Ranked Neighborhood InfoClues show comparative rank, not absolute mine counts.Ripple RevealReveals expand in rings that halt at the first numbers.