{
  "id": "P047",
  "slug": "minesweeper",
  "key": "P047-minesweeper",
  "title": "Minesweeper",
  "summary": "Open every cell without a mine on a field of up to 12 x 16: numbers count the mines around a cell, cells with none around open their neighbours by themselves, and flags mark the mines you are sure of. The mines are laid after the first move - never on that cell or next to it - from a seed, so the same seed lays the same field.",
  "entry": "main.eml",
  "ui": "terminal",
  "readme": "# P047 - Minesweeper\n\nOpen every cell of the field that holds no mine. An open cell shows how many\nmines lie in the eight cells around it; a cell with none around it opens its\nneighbours by itself. Flag the cells you are sure hold a mine - a flagged\ncell cannot be opened by mistake. Open a mine and the game is over.\n\n- `main.eml` - the menu, reading a cell as a row and a column, the game's\n  messages, and a new game of any size from 5 x 5 to 12 x 16\n- `field.eml` - the field: laying the mines, counting around a cell,\n  opening a cell and everything it spreads to, and drawing the field\n- `rng.eml` - random numbers written in EML, the generator of P008\n\nHow each part works:\n\n- The mines are laid when the first cell is opened, anywhere but on that\n  cell and the cells around it, so the first move always opens an area. They\n  are picked by a partial Fisher-Yates shuffle of the allowed cells, so\n  every set of cells is equally likely. The random numbers come from EML\n  code, not Python's random module, so a seed lays the same mines on every\n  machine.\n- Opening a cell with no mine around it spreads, as in the corpus case\n  `flood-fill`: each cell is marked open before it is visited, so none is\n  counted twice. Here it spreads to all eight neighbours, stops at cells\n  that have mines around them (they open, showing their number), and never\n  opens a flagged cell.\n- On the field `.` is a closed cell, `F` a flag, `-` an open cell with no\n  mine around it and `1` to `8` the mines around. When the game is over the\n  mines show as `*`, and a flag on a cell without a mine as `x`.\n- The game is won when every cell without a mine is open; flags are not\n  needed for that. The game counts your openings; flags do not count.\n\nWhat is checked: menu choices 1 to 5; a cell as a row and a column inside\nthe field, separated by a space or a comma; a cell that is already open or\nflagged; a game that is over. A new game takes 5 to 12 rows, 5 to 16\ncolumns, 1 mine up to the cells minus the nine kept clear, and a seed from\n0 to 999999999. An empty answer cancels.\n\nSessions: `sessions/basic.in` plays the default field (seed 2026) to the\nend. The first opening, in the middle, spreads over 25 cells, and four more\nspread over 14, 8, 8 and 6. Two flags go on mines, there is a look at the\nfield, and then ten single cells are opened. The field is cleared after 15\nopenings and shown once more with its mines.\n\n`sessions/bad-input.in` gives:\n- menu choices 0 and x;\n- a flag before the first opening, which stops that cell from being opened\n  until the flag is taken off;\n- an empty cell, then 0 0, 10 1, a b and 3, then 5,5 with a comma;\n- opening and flagging a cell that is already open;\n- a wrong flag and a right one, then a mine: the field shows every mine,\n  and the wrong flag as x;\n- opening and flagging after the game is over;\n- a new game that first gets rows 4, 13 and x, columns 17, mines 0 and 17\n  and seed -1, and then a 5 x 5 field with 16 mines. That is the most there\n  can be, so the first opening, in the middle, clears the field at once;\n- a new game that is cancelled.\n\nBuilt on the verified corpus case `flood-fill` (filling a region of a grid\nfrom one cell, marking each cell before spreading from it).\n",
  "modules": [
    {
      "name": "main.eml",
      "eml": "# P047 minesweeper: open every cell without a mine. A number tells how many\n# of the eight cells around hold one; flag the cells you are sure of. The\n# mines are laid after the first cell is opened, never on it or next to it,\n# and the same seed always lays the same mines.\nimport field\nimport rng\n\ndef trim(s):\n    0 => i\n    len(s) => j\n    while i < j and s[i] == \" \":\n        i + 1 => i\n    while j > i and s[j - 1] == \" \":\n        j - 1 => j\n    return s[i:j]\n\ndef words(s):\n    [] => out\n    \"\" => word\n    for c in s + \" \":\n        if c == \" \" or c == \",\":\n            if word != \"\":\n                out + [word] => out\n            \"\" => word\n        else:\n            word + c => word\n    return out\n\ndef number(s):\n    if s == \"\" or len(s) > 9:\n        return -1\n    0 => n\n    for c in s:\n        if not (c in \"0123456789\"):\n            return -1\n        n * 10 + int(c) => n\n    return n\n\ndef counted(n, word):\n    if n == 1:\n        return \"1 \" + word\n    return str(n) + \" \" + word + \"s\"\n\ndef show(game, reveal):\n    for line in field.drawn(game[0], reveal):\n        line ^0\n    game[0] => f\n    (\"Mines \" + str(game[1]) + \", flags \" + str(field.flag_count(f)) + \".\") ^0\n\ndef start(rows, cols, mines, seed):\n    (\"A field of \" + str(rows) + \" x \" + str(cols) + \" with \" + str(mines) + \" mines, seed \" + str(seed) + \".\") ^0\n    # [field, mines, the generator, over, openings - the cells the player\n    # opened; flags are not counted]\n    return [field.new_field(rows, cols), mines, rng.Rng(seed), False, 0]\n\ndef ask_cell(game, prompt):\n    # [row, column] counting from 0, or [] when the answer is empty.\n    game[0] => f\n    while True:\n        trim(input(prompt)) => answer\n        if answer == \"\":\n            return []\n        words(answer) => ws\n        if len(ws) == 2:\n            number(ws[0]) => r\n            number(ws[1]) => c\n            if r >= 1 and r <= f[0] and c >= 1 and c <= f[1]:\n                return [r - 1, c - 1]\n        (\"Type a row from 1 to \" + str(f[0]) + \" and a column from 1 to \" + str(f[1]) + \", like 3 4.\") ^0\n\ndef reveal(game):\n    if game[3]:\n        \"This game is over - start a new one.\" ^0\n        return game\n    ask_cell(game, \"open (row column)> \") => cell\n    if len(cell) == 0:\n        \"Cancelled.\" ^0\n        return game\n    game[0] => f\n    cell[0] => r\n    cell[1] => c\n    if f[3][r][c]:\n        \"That cell is open already.\" ^0\n        return game\n    if f[4][r][c]:\n        \"That cell is flagged - take the flag off first.\" ^0\n        return game\n    if len(f[2]) == 0:\n        field.lay_mines(f, game[1], r, c, game[2])\n    field.open_cell(f, r, c) => opened\n    game[4] + 1 => game[4]\n    if opened == -1:\n        True => game[3]\n        show(game, True)\n        (\"Boom - row \" + str(r + 1) + \", column \" + str(c + 1) + \" was a mine. Game over after \" + counted(game[4], \"opening\") + \".\") ^0\n        return game\n    show(game, False)\n    if field.closed_safe(f) == 0:\n        True => game[3]\n        (\"Cleared - every safe cell is open, after \" + counted(game[4], \"opening\") + \".\") ^0\n    elif opened > 1:\n        (str(opened) + \" cells opened.\") ^0\n    return game\n\ndef flag(game):\n    if game[3]:\n        \"This game is over - start a new one.\" ^0\n        return game\n    ask_cell(game, \"flag (row column)> \") => cell\n    if len(cell) == 0:\n        \"Cancelled.\" ^0\n        return game\n    game[0] => f\n    if f[3][cell[0]][cell[1]]:\n        \"That cell is open - there is nothing to flag.\" ^0\n        return game\n    not f[4][cell[0]][cell[1]] => f[4][cell[0]][cell[1]]\n    show(game, False)\n    return game\n\ndef ask_size(prompt, low, high):\n    while True:\n        trim(input(prompt + \" (\" + str(low) + \" to \" + str(high) + \")> \")) => answer\n        if answer == \"\":\n            return -1\n        number(answer) => n\n        if n >= low and n <= high:\n            return n\n        (\"Type a number from \" + str(low) + \" to \" + str(high) + \".\") ^0\n\ndef new_game(game):\n    ask_size(\"rows\", 5, 12) => rows\n    if rows == -1:\n        \"Cancelled.\" ^0\n        return game\n    ask_size(\"columns\", 5, 16) => cols\n    if cols == -1:\n        \"Cancelled.\" ^0\n        return game\n    ask_size(\"mines\", 1, rows * cols - 9) => mines\n    if mines == -1:\n        \"Cancelled.\" ^0\n        return game\n    ask_size(\"seed\", 0, 999999999) => seed\n    if seed == -1:\n        \"Cancelled.\" ^0\n        return game\n    start(rows, cols, mines, seed) => game\n    show(game, False)\n    return game\n\n\"== Minesweeper ==\" ^0\n\"Open every cell without a mine. A number counts the mines in the eight cells around it.\" ^0\nstart(9, 9, 10, 2026) => game\nshow(game, False)\nTrue => running\nwhile running:\n    \"\" ^0\n    \"1) open  2) flag  3) show  4) new game  5) quit\" ^0\n    trim(input(\"choice> \")) => choice\n    if choice == \"1\":\n        reveal(game) => game\n    elif choice == \"2\":\n        flag(game) => game\n    elif choice == \"3\":\n        show(game, game[3])\n    elif choice == \"4\":\n        new_game(game) => game\n    elif choice == \"5\":\n        False => running\n    else:\n        \"Pick a number from 1 to 5.\" ^0\n\"Bye.\" ^0\n",
      "python": "import field\nimport rng\n\ndef trim(s):\n    i = 0\n    j = len(s)\n    while i < j and s[i] == \" \":\n        i = i + 1\n    while j > i and s[j - 1] == \" \":\n        j = j - 1\n    return s[i:j]\n\ndef words(s):\n    out = []\n    word = \"\"\n    for c in s + \" \":\n        if c == \" \" or c == \",\":\n            if word != \"\":\n                out = out + [word]\n            word = \"\"\n        else:\n            word = word + c\n    return out\n\ndef number(s):\n    if s == \"\" or len(s) > 9:\n        return -1\n    n = 0\n    for c in s:\n        if not c in \"0123456789\":\n            return -1\n        n = n * 10 + int(c)\n    return n\n\ndef counted(n, word):\n    if n == 1:\n        return \"1 \" + word\n    return str(n) + \" \" + word + \"s\"\n\ndef show(game, reveal):\n    for line in field.drawn(game[0], reveal):\n        print(line)\n    f = game[0]\n    print(\"Mines \" + str(game[1]) + \", flags \" + str(field.flag_count(f)) + \".\")\n\ndef start(rows, cols, mines, seed):\n    print(\"A field of \" + str(rows) + \" x \" + str(cols) + \" with \" + str(mines) + \" mines, seed \" + str(seed) + \".\")\n    return [field.new_field(rows, cols), mines, rng.Rng(seed), False, 0]\n\ndef ask_cell(game, prompt):\n    f = game[0]\n    while True:\n        answer = trim(input(prompt))\n        if answer == \"\":\n            return []\n        ws = words(answer)\n        if len(ws) == 2:\n            r = number(ws[0])\n            c = number(ws[1])\n            if r >= 1 and r <= f[0] and c >= 1 and c <= f[1]:\n                return [r - 1, c - 1]\n        print(\"Type a row from 1 to \" + str(f[0]) + \" and a column from 1 to \" + str(f[1]) + \", like 3 4.\")\n\ndef reveal(game):\n    if game[3]:\n        print(\"This game is over - start a new one.\")\n        return game\n    cell = ask_cell(game, \"open (row column)> \")\n    if len(cell) == 0:\n        print(\"Cancelled.\")\n        return game\n    f = game[0]\n    r = cell[0]\n    c = cell[1]\n    if f[3][r][c]:\n        print(\"That cell is open already.\")\n        return game\n    if f[4][r][c]:\n        print(\"That cell is flagged - take the flag off first.\")\n        return game\n    if len(f[2]) == 0:\n        field.lay_mines(f, game[1], r, c, game[2])\n    opened = field.open_cell(f, r, c)\n    game[4] = game[4] + 1\n    if opened == -1:\n        game[3] = True\n        show(game, True)\n        print(\"Boom - row \" + str(r + 1) + \", column \" + str(c + 1) + \" was a mine. Game over after \" + counted(game[4], \"opening\") + \".\")\n        return game\n    show(game, False)\n    if field.closed_safe(f) == 0:\n        game[3] = True\n        print(\"Cleared - every safe cell is open, after \" + counted(game[4], \"opening\") + \".\")\n    elif opened > 1:\n        print(str(opened) + \" cells opened.\")\n    return game\n\ndef flag(game):\n    if game[3]:\n        print(\"This game is over - start a new one.\")\n        return game\n    cell = ask_cell(game, \"flag (row column)> \")\n    if len(cell) == 0:\n        print(\"Cancelled.\")\n        return game\n    f = game[0]\n    if f[3][cell[0]][cell[1]]:\n        print(\"That cell is open - there is nothing to flag.\")\n        return game\n    f[4][cell[0]][cell[1]] = not f[4][cell[0]][cell[1]]\n    show(game, False)\n    return game\n\ndef ask_size(prompt, low, high):\n    while True:\n        answer = trim(input(prompt + \" (\" + str(low) + \" to \" + str(high) + \")> \"))\n        if answer == \"\":\n            return -1\n        n = number(answer)\n        if n >= low and n <= high:\n            return n\n        print(\"Type a number from \" + str(low) + \" to \" + str(high) + \".\")\n\ndef new_game(game):\n    rows = ask_size(\"rows\", 5, 12)\n    if rows == -1:\n        print(\"Cancelled.\")\n        return game\n    cols = ask_size(\"columns\", 5, 16)\n    if cols == -1:\n        print(\"Cancelled.\")\n        return game\n    mines = ask_size(\"mines\", 1, rows * cols - 9)\n    if mines == -1:\n        print(\"Cancelled.\")\n        return game\n    seed = ask_size(\"seed\", 0, 999999999)\n    if seed == -1:\n        print(\"Cancelled.\")\n        return game\n    game = start(rows, cols, mines, seed)\n    show(game, False)\n    return game\n\nprint(\"== Minesweeper ==\")\nprint(\"Open every cell without a mine. A number counts the mines in the eight cells around it.\")\ngame = start(9, 9, 10, 2026)\nshow(game, False)\nrunning = True\nwhile running:\n    print(\"\")\n    print(\"1) open  2) flag  3) show  4) new game  5) quit\")\n    choice = trim(input(\"choice> \"))\n    if choice == \"1\":\n        game = reveal(game)\n    elif choice == \"2\":\n        game = flag(game)\n    elif choice == \"3\":\n        show(game, game[3])\n    elif choice == \"4\":\n        game = new_game(game)\n    elif choice == \"5\":\n        running = False\n    else:\n        print(\"Pick a number from 1 to 5.\")\nprint(\"Bye.\")\n"
    },
    {
      "name": "field.eml",
      "eml": "# P047 minesweeper - the field. A field is [rows, cols, mines, open, flags]:\n# mines[r][c] is True where a mine lies (an empty list until the first cell\n# is opened), open and flags are grids of True/False.\n\ndef grid(rows, cols, value):\n    [] => g\n    for r in [1:rows]:\n        g + [[value] * cols] => g\n    return g\n\ndef new_field(rows, cols):\n    return [rows, cols, [], grid(rows, cols, False), grid(rows, cols, False)]\n\ndef around(f, r, c):\n    # The cells next to (r, c), across corners too.\n    [] => out\n    for dr in [0:2]:\n        for dc in [0:2]:\n            r + dr - 1 => y\n            c + dc - 1 => x\n            if (dr != 1 or dc != 1) and y >= 0 and y < f[0] and x >= 0 and x < f[1]:\n                out + [[y, x]] => out\n    return out\n\ndef lay_mines(f, count, r0, c0, rng):\n    # Mines go anywhere but the first cell opened and the cells around it, so\n    # the first move always opens an area. A partial Fisher-Yates shuffle\n    # picks `count` of the allowed cells, each set of cells equally likely.\n    [] => allowed\n    for r in [0:f[0] - 1]:\n        for c in [0:f[1] - 1]:\n            if abs(r - r0) > 1 or abs(c - c0) > 1:\n                allowed + [[r, c]] => allowed\n    grid(f[0], f[1], False) => mines\n    for k in [0:count - 1]:\n        k + rng.below(len(allowed) - k) => j\n        allowed[j] => pick\n        allowed[k] => allowed[j]\n        pick => allowed[k]\n        True => mines[pick[0]][pick[1]]\n    mines => f[2]\n\ndef count_around(f, r, c):\n    0 => n\n    for cell in around(f, r, c):\n        if f[2][cell[0]][cell[1]]:\n            n + 1 => n\n    return n\n\ndef open_cell(f, r, c):\n    # Opens (r, c). Returns the number of cells opened, or -1 for a mine. A\n    # cell with no mine around it opens its neighbours too, and so on - the\n    # spreading of the corpus case flood-fill: a cell is marked before it is\n    # visited, so none is counted twice. Here it spreads to all eight\n    # neighbours, never into a flagged cell, and keeps a list of cells still\n    # to visit instead of calling itself.\n    if f[2][r][c]:\n        True => f[3][r][c]\n        return -1\n    0 => opened\n    [[r, c]] => todo\n    True => f[3][r][c]\n    while len(todo) > 0:\n        todo[len(todo) - 1] => cell\n        todo[0:len(todo) - 1] => todo\n        opened + 1 => opened\n        if count_around(f, cell[0], cell[1]) == 0:\n            for nb in around(f, cell[0], cell[1]):\n                if not f[3][nb[0]][nb[1]] and not f[4][nb[0]][nb[1]]:\n                    True => f[3][nb[0]][nb[1]]\n                    todo + [nb] => todo\n    return opened\n\ndef closed_safe(f):\n    # How many cells without a mine are still closed.\n    0 => n\n    for r in [0:f[0] - 1]:\n        for c in [0:f[1] - 1]:\n            if not f[3][r][c] and not f[2][r][c]:\n                n + 1 => n\n    return n\n\ndef flag_count(f):\n    0 => n\n    for row in f[4]:\n        for x in row:\n            if x:\n                n + 1 => n\n    return n\n\ndef drawn(f, reveal):\n    # The field as lines: . closed, F flag, - an open cell with no mine\n    # around, 1-8 the mines around. With reveal (the game is over) the mines\n    # show as *, and a flag on a cell without a mine as x.\n    \"    \" => header\n    for c in [1:f[1]]:\n        header + \" \" + str(c % 10) => header\n    [header] => lines\n    for r in [0:f[0] - 1]:\n        str(r + 1) => label\n        while len(label) < 3:\n            \" \" + label => label\n        label + \" \" => line\n        for c in [0:f[1] - 1]:\n            \".\" => ch\n            if f[3][r][c]:\n                if f[2][r][c]:\n                    \"*\" => ch\n                else:\n                    count_around(f, r, c) => n\n                    \"-\" => ch\n                    if n > 0:\n                        str(n) => ch\n            elif f[4][r][c]:\n                \"F\" => ch\n                if reveal and len(f[2]) > 0 and not f[2][r][c]:\n                    \"x\" => ch\n            elif reveal and len(f[2]) > 0 and f[2][r][c]:\n                \"*\" => ch\n            line + \" \" + ch => line\n        lines + [line] => lines\n    return lines\n",
      "python": "def grid(rows, cols, value):\n    g = []\n    for r in range(1, rows+1):\n        g = g + [[value] * cols]\n    return g\n\ndef new_field(rows, cols):\n    return [rows, cols, [], grid(rows, cols, False), grid(rows, cols, False)]\n\ndef around(f, r, c):\n    out = []\n    for dr in range(0, 3):\n        for dc in range(0, 3):\n            y = r + dr - 1\n            x = c + dc - 1\n            if (dr != 1 or dc != 1) and y >= 0 and y < f[0] and x >= 0 and x < f[1]:\n                out = out + [[y, x]]\n    return out\n\ndef lay_mines(f, count, r0, c0, rng):\n    allowed = []\n    for r in range(0, f[0]):\n        for c in range(0, f[1]):\n            if abs(r - r0) > 1 or abs(c - c0) > 1:\n                allowed = allowed + [[r, c]]\n    mines = grid(f[0], f[1], False)\n    for k in range(0, count):\n        j = k + rng.below(len(allowed) - k)\n        pick = allowed[j]\n        allowed[j] = allowed[k]\n        allowed[k] = pick\n        mines[pick[0]][pick[1]] = True\n    f[2] = mines\n\ndef count_around(f, r, c):\n    n = 0\n    for cell in around(f, r, c):\n        if f[2][cell[0]][cell[1]]:\n            n = n + 1\n    return n\n\ndef open_cell(f, r, c):\n    if f[2][r][c]:\n        f[3][r][c] = True\n        return -1\n    opened = 0\n    todo = [[r, c]]\n    f[3][r][c] = True\n    while len(todo) > 0:\n        cell = todo[len(todo) - 1]\n        todo = todo[0:len(todo) - 1]\n        opened = opened + 1\n        if count_around(f, cell[0], cell[1]) == 0:\n            for nb in around(f, cell[0], cell[1]):\n                if not f[3][nb[0]][nb[1]] and not f[4][nb[0]][nb[1]]:\n                    f[3][nb[0]][nb[1]] = True\n                    todo = todo + [nb]\n    return opened\n\ndef closed_safe(f):\n    n = 0\n    for r in range(0, f[0]):\n        for c in range(0, f[1]):\n            if not f[3][r][c] and not f[2][r][c]:\n                n = n + 1\n    return n\n\ndef flag_count(f):\n    n = 0\n    for row in f[4]:\n        for x in row:\n            if x:\n                n = n + 1\n    return n\n\ndef drawn(f, reveal):\n    header = \"    \"\n    for c in range(1, f[1]+1):\n        header = header + \" \" + str(c % 10)\n    lines = [header]\n    for r in range(0, f[0]):\n        label = str(r + 1)\n        while len(label) < 3:\n            label = \" \" + label\n        line = label + \" \"\n        for c in range(0, f[1]):\n            ch = \".\"\n            if f[3][r][c]:\n                if f[2][r][c]:\n                    ch = \"*\"\n                else:\n                    n = count_around(f, r, c)\n                    ch = \"-\"\n                    if n > 0:\n                        ch = str(n)\n            elif f[4][r][c]:\n                ch = \"F\"\n                if reveal and len(f[2]) > 0 and not f[2][r][c]:\n                    ch = \"x\"\n            elif reveal and len(f[2]) > 0 and f[2][r][c]:\n                ch = \"*\"\n            line = line + \" \" + ch\n        lines = lines + [line]\n    return lines\n"
    },
    {
      "name": "rng.eml",
      "eml": "# P047 minesweeper - random numbers written in EML: the linear congruential\n# generator of P008 (number guessing), with the constants of the C\n# standard's example rand(). Python's random module is not used, so a seed\n# gives the same mines on every machine, and the interpreter can check a\n# whole session byte for byte.\n\nclass Rng:\n    def __init__(self, seed):\n        seed % 2147483648 => self.state\n\n    def step(self):\n        (1103515245 * self.state + 12345) % 2147483648 => self.state\n        return self.state\n\n    def below(self, n):\n        # A number from 0 to n - 1, taken from the high bits of the state: the\n        # low bits of this generator repeat with short periods. Dividing by\n        # 65536 is exact in a float for a state below 2^31.\n        return int(self.step() / 65536) % n\n",
      "python": "class Rng:\n    def __init__(self, seed):\n        self.state = seed % 2147483648\n    def step(self):\n        self.state = (1103515245 * self.state + 12345) % 2147483648\n        return self.state\n    def below(self, n):\n        return int(self.step() / 65536) % n\n"
    }
  ],
  "sessions": [
    {
      "name": "bad-input",
      "input": "0\nx\n2\n5 5\n1\n5 5\n2\n5 5\n1\n\n1\n0 0\n10 1\na b\n3\n5,5\n1\n5 5\n2\n5 5\n2\n1 2\n2\n3 5\n1\n1 1\n1\n2\n3\n4\n4\n13\nx\n5\n17\n5\n0\n17\n16\n-1\n7\n1\n3 3\n4\n\n3\n5\n",
      "screen": "== Minesweeper ==\nOpen every cell without a mine. A number counts the mines in the eight cells around it.\nA field of 9 x 9 with 10 mines, seed 2026.\n     1 2 3 4 5 6 7 8 9\n  1  . . . . . . . . .\n  2  . . . . . . . . .\n  3  . . . . . . . . .\n  4  . . . . . . . . .\n  5  . . . . . . . . .\n  6  . . . . . . . . .\n  7  . . . . . . . . .\n  8  . . . . . . . . .\n  9  . . . . . . . . .\nMines 10, flags 0.\n\n1) open  2) flag  3) show  4) new game  5) quit\nchoice> 0\nPick a number from 1 to 5.\n\n1) open  2) flag  3) show  4) new game  5) quit\nchoice> x\nPick a number from 1 to 5.\n\n1) open  2) flag  3) show  4) new game  5) quit\nchoice> 2\nflag (row column)> 5 5\n     1 2 3 4 5 6 7 8 9\n  1  . . . . . . . . .\n  2  . . . . . . . . .\n  3  . . . . . . . . .\n  4  . . . . . . . . .\n  5  . . . . F . . . .\n  6  . . . . . . . . .\n  7  . . . . . . . . .\n  8  . . . . . . . . .\n  9  . . . . . . . . .\nMines 10, flags 1.\n\n1) open  2) flag  3) show  4) new game  5) quit\nchoice> 1\nopen (row column)> 5 5\nThat cell is flagged - take the flag off first.\n\n1) open  2) flag  3) show  4) new game  5) quit\nchoice> 2\nflag (row column)> 5 5\n     1 2 3 4 5 6 7 8 9\n  1  . . . . . . . . .\n  2  . . . . . . . . .\n  3  . . . . . . . . .\n  4  . . . . . . . . .\n  5  . . . . . . . . .\n  6  . . . . . . . . .\n  7  . . . . . . . . .\n  8  . . . . . . . . .\n  9  . . . . . . . . .\nMines 10, flags 0.\n\n1) open  2) flag  3) show  4) new game  5) quit\nchoice> 1\nopen (row column)> \nCancelled.\n\n1) open  2) flag  3) show  4) new game  5) quit\nchoice> 1\nopen (row column)> 0 0\nType a row from 1 to 9 and a column from 1 to 9, like 3 4.\nopen (row column)> 10 1\nType a row from 1 to 9 and a column from 1 to 9, like 3 4.\nopen (row column)> a b\nType a row from 1 to 9 and a column from 1 to 9, like 3 4.\nopen (row column)> 3\nType a row from 1 to 9 and a column from 1 to 9, like 3 4.\nopen (row column)> 5,5\n     1 2 3 4 5 6 7 8 9\n  1  . . . . . . . . .\n  2  . . . . . . . . .\n  3  . . . . . . . . .\n  4  . . . 2 1 1 1 . .\n  5  . . 2 1 - - 1 . .\n  6  . . 1 - - 1 1 . .\n  7  . . 1 - - 1 . . .\n  8  . . 1 1 - 2 . . .\n  9  . . . 1 - 1 . . .\nMines 10, flags 0.\n25 cells opened.\n\n1) open  2) flag  3) show  4) new game  5) quit\nchoice> 1\nopen (row column)> 5 5\nThat cell is open already.\n\n1) open  2) flag  3) show  4) new game  5) quit\nchoice> 2\nflag (row column)> 5 5\nThat cell is open - there is nothing to flag.\n\n1) open  2) flag  3) show  4) new game  5) quit\nchoice> 2\nflag (row column)> 1 2\n     1 2 3 4 5 6 7 8 9\n  1  . F . . . . . . .\n  2  . . . . . . . . .\n  3  . . . . . . . . .\n  4  . . . 2 1 1 1 . .\n  5  . . 2 1 - - 1 . .\n  6  . . 1 - - 1 1 . .\n  7  . . 1 - - 1 . . .\n  8  . . 1 1 - 2 . . .\n  9  . . . 1 - 1 . . .\nMines 10, flags 1.\n\n1) open  2) flag  3) show  4) new game  5) quit\nchoice> 2\nflag (row column)> 3 5\n     1 2 3 4 5 6 7 8 9\n  1  . F . . . . . . .\n  2  . . . . . . . . .\n  3  . . . . F . . . .\n  4  . . . 2 1 1 1 . .\n  5  . . 2 1 - - 1 . .\n  6  . . 1 - - 1 1 . .\n  7  . . 1 - - 1 . . .\n  8  . . 1 1 - 2 . . .\n  9  . . . 1 - 1 . . .\nMines 10, flags 2.\n\n1) open  2) flag  3) show  4) new game  5) quit\nchoice> 1\nopen (row column)> 1 1\n     1 2 3 4 5 6 7 8 9\n  1  * x . . . . . . .\n  2  . . . * . . . . .\n  3  . . . . F . . . .\n  4  . . * 2 1 1 1 * .\n  5  . . 2 1 - - 1 . *\n  6  . * 1 - - 1 1 . .\n  7  . . 1 - - 1 * . .\n  8  . . 1 1 - 2 . . .\n  9  . . * 1 - 1 * . .\nMines 10, flags 2.\nBoom - row 1, column 1 was a mine. Game over after 2 openings.\n\n1) open  2) flag  3) show  4) new game  5) quit\nchoice> 1\nThis game is over - start a new one.\n\n1) open  2) flag  3) show  4) new game  5) quit\nchoice> 2\nThis game is over - start a new one.\n\n1) open  2) flag  3) show  4) new game  5) quit\nchoice> 3\n     1 2 3 4 5 6 7 8 9\n  1  * x . . . . . . .\n  2  . . . * . . . . .\n  3  . . . . F . . . .\n  4  . . * 2 1 1 1 * .\n  5  . . 2 1 - - 1 . *\n  6  . * 1 - - 1 1 . .\n  7  . . 1 - - 1 * . .\n  8  . . 1 1 - 2 . . .\n  9  . . * 1 - 1 * . .\nMines 10, flags 2.\n\n1) open  2) flag  3) show  4) new game  5) quit\nchoice> 4\nrows (5 to 12)> 4\nType a number from 5 to 12.\nrows (5 to 12)> 13\nType a number from 5 to 12.\nrows (5 to 12)> x\nType a number from 5 to 12.\nrows (5 to 12)> 5\ncolumns (5 to 16)> 17\nType a number from 5 to 16.\ncolumns (5 to 16)> 5\nmines (1 to 16)> 0\nType a number from 1 to 16.\nmines (1 to 16)> 17\nType a number from 1 to 16.\nmines (1 to 16)> 16\nseed (0 to 999999999)> -1\nType a number from 0 to 999999999.\nseed (0 to 999999999)> 7\nA field of 5 x 5 with 16 mines, seed 7.\n     1 2 3 4 5\n  1  . . . . .\n  2  . . . . .\n  3  . . . . .\n  4  . . . . .\n  5  . . . . .\nMines 16, flags 0.\n\n1) open  2) flag  3) show  4) new game  5) quit\nchoice> 1\nopen (row column)> 3 3\n     1 2 3 4 5\n  1  . . . . .\n  2  . 5 3 5 .\n  3  . 3 - 3 .\n  4  . 5 3 5 .\n  5  . . . . .\nMines 16, flags 0.\nCleared - every safe cell is open, after 1 opening.\n\n1) open  2) flag  3) show  4) new game  5) quit\nchoice> 4\nrows (5 to 12)> \nCancelled.\n\n1) open  2) flag  3) show  4) new game  5) quit\nchoice> 3\n     1 2 3 4 5\n  1  * * * * *\n  2  * 5 3 5 *\n  3  * 3 - 3 *\n  4  * 5 3 5 *\n  5  * * * * *\nMines 16, flags 0.\n\n1) open  2) flag  3) show  4) new game  5) quit\nchoice> 5\nBye.\n",
      "interpreter": "equal"
    },
    {
      "name": "basic",
      "input": "1\n5 5\n2\n1 1\n1\n1 6\n1\n3 1\n1\n7 9\n1\n8 1\n2\n6 2\n3\n1\n1 2\n1\n1 3\n1\n1 4\n1\n2 3\n1\n3 3\n1\n3 4\n1\n4 9\n1\n5 8\n1\n6 1\n1\n8 7\n3\n5\n",
      "screen": "== Minesweeper ==\nOpen every cell without a mine. A number counts the mines in the eight cells around it.\nA field of 9 x 9 with 10 mines, seed 2026.\n     1 2 3 4 5 6 7 8 9\n  1  . . . . . . . . .\n  2  . . . . . . . . .\n  3  . . . . . . . . .\n  4  . . . . . . . . .\n  5  . . . . . . . . .\n  6  . . . . . . . . .\n  7  . . . . . . . . .\n  8  . . . . . . . . .\n  9  . . . . . . . . .\nMines 10, flags 0.\n\n1) open  2) flag  3) show  4) new game  5) quit\nchoice> 1\nopen (row column)> 5 5\n     1 2 3 4 5 6 7 8 9\n  1  . . . . . . . . .\n  2  . . . . . . . . .\n  3  . . . . . . . . .\n  4  . . . 2 1 1 1 . .\n  5  . . 2 1 - - 1 . .\n  6  . . 1 - - 1 1 . .\n  7  . . 1 - - 1 . . .\n  8  . . 1 1 - 2 . . .\n  9  . . . 1 - 1 . . .\nMines 10, flags 0.\n25 cells opened.\n\n1) open  2) flag  3) show  4) new game  5) quit\nchoice> 2\nflag (row column)> 1 1\n     1 2 3 4 5 6 7 8 9\n  1  F . . . . . . . .\n  2  . . . . . . . . .\n  3  . . . . . . . . .\n  4  . . . 2 1 1 1 . .\n  5  . . 2 1 - - 1 . .\n  6  . . 1 - - 1 1 . .\n  7  . . 1 - - 1 . . .\n  8  . . 1 1 - 2 . . .\n  9  . . . 1 - 1 . . .\nMines 10, flags 1.\n\n1) open  2) flag  3) show  4) new game  5) quit\nchoice> 1\nopen (row column)> 1 6\n     1 2 3 4 5 6 7 8 9\n  1  F . . . 1 - - - -\n  2  . . . . 2 1 - - -\n  3  . . . . . 1 1 1 1\n  4  . . . 2 1 1 1 . .\n  5  . . 2 1 - - 1 . .\n  6  . . 1 - - 1 1 . .\n  7  . . 1 - - 1 . . .\n  8  . . 1 1 - 2 . . .\n  9  . . . 1 - 1 . . .\nMines 10, flags 1.\n14 cells opened.\n\n1) open  2) flag  3) show  4) new game  5) quit\nchoice> 1\nopen (row column)> 3 1\n     1 2 3 4 5 6 7 8 9\n  1  F . . . 1 - - - -\n  2  1 1 . . 2 1 - - -\n  3  - 1 . . . 1 1 1 1\n  4  - 1 . 2 1 1 1 . .\n  5  1 2 2 1 - - 1 . .\n  6  . . 1 - - 1 1 . .\n  7  . . 1 - - 1 . . .\n  8  . . 1 1 - 2 . . .\n  9  . . . 1 - 1 . . .\nMines 10, flags 1.\n8 cells opened.\n\n1) open  2) flag  3) show  4) new game  5) quit\nchoice> 1\nopen (row column)> 7 9\n     1 2 3 4 5 6 7 8 9\n  1  F . . . 1 - - - -\n  2  1 1 . . 2 1 - - -\n  3  - 1 . . . 1 1 1 1\n  4  - 1 . 2 1 1 1 . .\n  5  1 2 2 1 - - 1 . .\n  6  . . 1 - - 1 1 2 1\n  7  . . 1 - - 1 . 1 -\n  8  . . 1 1 - 2 . 2 -\n  9  . . . 1 - 1 . 1 -\nMines 10, flags 1.\n8 cells opened.\n\n1) open  2) flag  3) show  4) new game  5) quit\nchoice> 1\nopen (row column)> 8 1\n     1 2 3 4 5 6 7 8 9\n  1  F . . . 1 - - - -\n  2  1 1 . . 2 1 - - -\n  3  - 1 . . . 1 1 1 1\n  4  - 1 . 2 1 1 1 . .\n  5  1 2 2 1 - - 1 . .\n  6  . . 1 - - 1 1 2 1\n  7  1 1 1 - - 1 . 1 -\n  8  - 1 1 1 - 2 . 2 -\n  9  - 1 . 1 - 1 . 1 -\nMines 10, flags 1.\n6 cells opened.\n\n1) open  2) flag  3) show  4) new game  5) quit\nchoice> 2\nflag (row column)> 6 2\n     1 2 3 4 5 6 7 8 9\n  1  F . . . 1 - - - -\n  2  1 1 . . 2 1 - - -\n  3  - 1 . . . 1 1 1 1\n  4  - 1 . 2 1 1 1 . .\n  5  1 2 2 1 - - 1 . .\n  6  . F 1 - - 1 1 2 1\n  7  1 1 1 - - 1 . 1 -\n  8  - 1 1 1 - 2 . 2 -\n  9  - 1 . 1 - 1 . 1 -\nMines 10, flags 2.\n\n1) open  2) flag  3) show  4) new game  5) quit\nchoice> 3\n     1 2 3 4 5 6 7 8 9\n  1  F . . . 1 - - - -\n  2  1 1 . . 2 1 - - -\n  3  - 1 . . . 1 1 1 1\n  4  - 1 . 2 1 1 1 . .\n  5  1 2 2 1 - - 1 . .\n  6  . F 1 - - 1 1 2 1\n  7  1 1 1 - - 1 . 1 -\n  8  - 1 1 1 - 2 . 2 -\n  9  - 1 . 1 - 1 . 1 -\nMines 10, flags 2.\n\n1) open  2) flag  3) show  4) new game  5) quit\nchoice> 1\nopen (row column)> 1 2\n     1 2 3 4 5 6 7 8 9\n  1  F 1 . . 1 - - - -\n  2  1 1 . . 2 1 - - -\n  3  - 1 . . . 1 1 1 1\n  4  - 1 . 2 1 1 1 . .\n  5  1 2 2 1 - - 1 . .\n  6  . F 1 - - 1 1 2 1\n  7  1 1 1 - - 1 . 1 -\n  8  - 1 1 1 - 2 . 2 -\n  9  - 1 . 1 - 1 . 1 -\nMines 10, flags 2.\n\n1) open  2) flag  3) show  4) new game  5) quit\nchoice> 1\nopen (row column)> 1 3\n     1 2 3 4 5 6 7 8 9\n  1  F 1 1 . 1 - - - -\n  2  1 1 . . 2 1 - - -\n  3  - 1 . . . 1 1 1 1\n  4  - 1 . 2 1 1 1 . .\n  5  1 2 2 1 - - 1 . .\n  6  . F 1 - - 1 1 2 1\n  7  1 1 1 - - 1 . 1 -\n  8  - 1 1 1 - 2 . 2 -\n  9  - 1 . 1 - 1 . 1 -\nMines 10, flags 2.\n\n1) open  2) flag  3) show  4) new game  5) quit\nchoice> 1\nopen (row column)> 1 4\n     1 2 3 4 5 6 7 8 9\n  1  F 1 1 1 1 - - - -\n  2  1 1 . . 2 1 - - -\n  3  - 1 . . . 1 1 1 1\n  4  - 1 . 2 1 1 1 . .\n  5  1 2 2 1 - - 1 . .\n  6  . F 1 - - 1 1 2 1\n  7  1 1 1 - - 1 . 1 -\n  8  - 1 1 1 - 2 . 2 -\n  9  - 1 . 1 - 1 . 1 -\nMines 10, flags 2.\n\n1) open  2) flag  3) show  4) new game  5) quit\nchoice> 1\nopen (row column)> 2 3\n     1 2 3 4 5 6 7 8 9\n  1  F 1 1 1 1 - - - -\n  2  1 1 1 . 2 1 - - -\n  3  - 1 . . . 1 1 1 1\n  4  - 1 . 2 1 1 1 . .\n  5  1 2 2 1 - - 1 . .\n  6  . F 1 - - 1 1 2 1\n  7  1 1 1 - - 1 . 1 -\n  8  - 1 1 1 - 2 . 2 -\n  9  - 1 . 1 - 1 . 1 -\nMines 10, flags 2.\n\n1) open  2) flag  3) show  4) new game  5) quit\nchoice> 1\nopen (row column)> 3 3\n     1 2 3 4 5 6 7 8 9\n  1  F 1 1 1 1 - - - -\n  2  1 1 1 . 2 1 - - -\n  3  - 1 2 . . 1 1 1 1\n  4  - 1 . 2 1 1 1 . .\n  5  1 2 2 1 - - 1 . .\n  6  . F 1 - - 1 1 2 1\n  7  1 1 1 - - 1 . 1 -\n  8  - 1 1 1 - 2 . 2 -\n  9  - 1 . 1 - 1 . 1 -\nMines 10, flags 2.\n\n1) open  2) flag  3) show  4) new game  5) quit\nchoice> 1\nopen (row column)> 3 4\n     1 2 3 4 5 6 7 8 9\n  1  F 1 1 1 1 - - - -\n  2  1 1 1 . 2 1 - - -\n  3  - 1 2 3 . 1 1 1 1\n  4  - 1 . 2 1 1 1 . .\n  5  1 2 2 1 - - 1 . .\n  6  . F 1 - - 1 1 2 1\n  7  1 1 1 - - 1 . 1 -\n  8  - 1 1 1 - 2 . 2 -\n  9  - 1 . 1 - 1 . 1 -\nMines 10, flags 2.\n\n1) open  2) flag  3) show  4) new game  5) quit\nchoice> 1\nopen (row column)> 4 9\n     1 2 3 4 5 6 7 8 9\n  1  F 1 1 1 1 - - - -\n  2  1 1 1 . 2 1 - - -\n  3  - 1 2 3 . 1 1 1 1\n  4  - 1 . 2 1 1 1 . 2\n  5  1 2 2 1 - - 1 . .\n  6  . F 1 - - 1 1 2 1\n  7  1 1 1 - - 1 . 1 -\n  8  - 1 1 1 - 2 . 2 -\n  9  - 1 . 1 - 1 . 1 -\nMines 10, flags 2.\n\n1) open  2) flag  3) show  4) new game  5) quit\nchoice> 1\nopen (row column)> 5 8\n     1 2 3 4 5 6 7 8 9\n  1  F 1 1 1 1 - - - -\n  2  1 1 1 . 2 1 - - -\n  3  - 1 2 3 . 1 1 1 1\n  4  - 1 . 2 1 1 1 . 2\n  5  1 2 2 1 - - 1 2 .\n  6  . F 1 - - 1 1 2 1\n  7  1 1 1 - - 1 . 1 -\n  8  - 1 1 1 - 2 . 2 -\n  9  - 1 . 1 - 1 . 1 -\nMines 10, flags 2.\n\n1) open  2) flag  3) show  4) new game  5) quit\nchoice> 1\nopen (row column)> 6 1\n     1 2 3 4 5 6 7 8 9\n  1  F 1 1 1 1 - - - -\n  2  1 1 1 . 2 1 - - -\n  3  - 1 2 3 . 1 1 1 1\n  4  - 1 . 2 1 1 1 . 2\n  5  1 2 2 1 - - 1 2 .\n  6  1 F 1 - - 1 1 2 1\n  7  1 1 1 - - 1 . 1 -\n  8  - 1 1 1 - 2 . 2 -\n  9  - 1 . 1 - 1 . 1 -\nMines 10, flags 2.\n\n1) open  2) flag  3) show  4) new game  5) quit\nchoice> 1\nopen (row column)> 8 7\n     1 2 3 4 5 6 7 8 9\n  1  F 1 1 1 1 - - - -\n  2  1 1 1 . 2 1 - - -\n  3  - 1 2 3 . 1 1 1 1\n  4  - 1 . 2 1 1 1 . 2\n  5  1 2 2 1 - - 1 2 .\n  6  1 F 1 - - 1 1 2 1\n  7  1 1 1 - - 1 . 1 -\n  8  - 1 1 1 - 2 2 2 -\n  9  - 1 . 1 - 1 . 1 -\nMines 10, flags 2.\nCleared - every safe cell is open, after 15 openings.\n\n1) open  2) flag  3) show  4) new game  5) quit\nchoice> 3\n     1 2 3 4 5 6 7 8 9\n  1  F 1 1 1 1 - - - -\n  2  1 1 1 * 2 1 - - -\n  3  - 1 2 3 * 1 1 1 1\n  4  - 1 * 2 1 1 1 * 2\n  5  1 2 2 1 - - 1 2 *\n  6  1 F 1 - - 1 1 2 1\n  7  1 1 1 - - 1 * 1 -\n  8  - 1 1 1 - 2 2 2 -\n  9  - 1 * 1 - 1 * 1 -\nMines 10, flags 2.\n\n1) open  2) flag  3) show  4) new game  5) quit\nchoice> 5\nBye.\n",
      "interpreter": "equal"
    }
  ],
  "builtOn": [
    {
      "slug": "flood-fill",
      "caseId": "099-flood-fill",
      "title": "Flood fill"
    }
  ],
  "updated": "2026-10-10"
}
