Solving Minesweeper on paper using an SMT (integer) solver
Sunday 25 September 2022
An Article by Clive England, CEng, MBCS
See Original and updates on https://gannett-hscp.blogspot.com September 2022
Continuing the series of solving puzzles using an integer SMT solver we look now at the paper version of the Minesweeper puzzle. Originally Minesweeper was an active game shipped with various versions of Windows operating systems. This version is static as published in newspapers. See Minesweeper link for more information about the active game.
This popular logic puzzle is published in the i newspaper. The puzzle offers a rectangular grid with numeric clues from which the locations of hidden mines must be deduced. The initial clue numbers show the quantity of mines adjacent to the clue square. The numbers are generated by counting the hidden mines one step in any direction (kings move). No edge wraparound is allowed. No mines are located under clue squares.
Encoding
The puzzle is simply encoded into text then a script is used to generate the underlying logic of the puzzle. These logic lines are then passed to an SMT solver for analysis and resolution. Microsoft's Z3 and MathSAT solvers are used. The above puzzles are encoded as follows.
#iMine iMine_220917.txt
.0..00...2...1..
...3..3....2..0.
2....1....43.1..
3.......3.3.....
.3..2..3.3...3.1
..1.....2....3..
0....0..2..1.1..
....1.0.....1..1
.2.0...1..3.....
...0..0.0..3.22.
1.1.3....13.....
......2.....3..2
#iMine iMine_test03.txt
0...0
..1..
0...0
The puzzle logic for iMine_test03.txt is generated from the encoding as follows:
After some pre-amble to set the solvers into “linear integer” mode a value is declared for each of the empty “.” squares.
The range of that value then limited to 0 or 1. In the results of the solver a 1 indicates the presences of a mine in that square. The numbering of the values is critical to the simplicity and generation of the logic to solve the problem.
Each cell in each row is numbered sequentially but there is a jump in numbers between the sequential rows.
#iMine iMine_test03_Cell_numbers.txt
V0 V1 V2 V3 V4
V9 V10 V11 V12 V13
V18 V19 V20 V21 V22
The jump in value numbering is to avoid wrap around at the row edges. For example the first cell on the second row is V9, to check the cell to left of V9 the logic generation script checks to see if V8 exists. As V8 is not defined the cell is treated as on the edge and V8 is not included in the logic definition. The same applies on the right hand edge of Row 1, where counting from cell V0, V4 is not defined as it is a clue square and V5 is not defined as being off the edge of the board. The second row starts with V9.
Words after a ; on the logic line are comments and are ignored.
A value V000 is defined and set to value zero to assist with the case where the contents of an empty cell are defined by just one clue cell.
(set-logic LIA)
(set-option :produce-models true)
(set-option :produce-assignments true)
(declare-const V000 Int)
(assert (= 0 V000))
(declare-const V1 Int) ; Row 1
(assert (or (= 1 V1) (= 0 V1)))
(declare-const V2 Int)
(assert (or (= 1 V2) (= 0 V2)))
(declare-const V3 Int)
(assert (or (= 1 V3) (= 0 V3)))
(declare-const V9 Int) ; Row 2
(assert (or (= 1 V9) (= 0 V9)))
(declare-const V10 Int)
....
(declare-const V21 Int)
(assert (or (= 1 V21) (= 0 V21)))
The main logic of the puzzle is generated, one line for each of the numeric clue squares. Each of the potential mine squares has to be 0 or 1 with the total number of 1s in the surrounding 8 squares being the same as the provided clue. Mines cannot be under clue squares.
(assert (or (= 1 V21) (= 0 V21)))
(assert ( = 0 ( + V000 V1 V9 V10 ))) ; sqr=0
(assert ( = 0 ( + V000 V3 V12 V13 ))) ; sqr=4
(assert ( = 1 ( + V000 V1 V2 V3 V10 V12 V19 V20 V21 ))) ; sqr=11
(assert ( = 0 ( + V000 V9 V10 V19 ))) ; sqr=18
(assert ( = 0 ( + V000 V12 V13 V21 ))) ; sqr=22
After testing it was found that some boards generate logic such as
(assert ( = 1 ( + V11 ))) ; sqr=10
giving an SMT error
(error "ERROR: + takes at least 2 arguments (1 given) (line: 256)")
The was fixed by this defining V000 being value 0 and then generating the logic line
(assert ( = 1 ( + V000 V11 ))) ; sqr=10
(check-sat)
(get-value ( V1 V2 V3 V9 V10 V12 V13 V19 V20 V21 ))
(exit)
The above logic is provided to the SMT logic solver Mathsat5 ( or Microsoft’s 3 ) and the results are obtained.
sat
( (V1 0)
(V2 1)
(V3 0)
(V9 0)
(V10 0)
(V12 0)
(V13 0)
(V19 0)
(V20 0)
(V21 0) )
The results are read, alongside re-reading the puzzle file, to generate answer display table in html. The Red “<->” squares indicate the placement of a hidden mine. Green “.” squares are empty, clue squares show the clue value.
Result validation
Using the results from the solver each of the clue number squares are checked to see if the final solution is validated.
To check the validation one of the provided answer values is changed and .
$ ./iMine_smt.pl < iMine_220917.txt | ~/CodeProjects/solver_m5 | sed 's/(V43 0)/(V43 1)/'|
./iMine_smt.pl -f iMine_220917.txt > iMine_220917.html
Two dreamboards
Paper Versus active game
. | . | . |
. | . | . |
. | 1 | 1 |
. | 2 | . |
. | 3 | . |
. | 2 | . |
. | 1 | 1 |
. | . | . |
There are two possible valid answers from the clues provided, the one given by the solver suitable for the paper game
and the one shown in the active game solution.
Some Minesweeper cartoons here.
References
Programming Z3 Sudoku section from Section 8.1 page 139
Building a Sudoku Solver with SAT,
A SAT-based Sudoku Solver,
Sudoku as a SAT Problem,
Optimized CNF Encoding for Sudoku Puzzles
Mathsat5 solver
Usage for the Minesweeper to SMT generation utility
Usage: Minesweeper {options} < puzzle.txt or
Minesweeper {options} -f puzzle.txt < SolverOutput
-v N :Be verbose to level N ( use v=1 for detailed output )
-f puzzle.txt :puzzle file needed when reading Solver output use STDIN otherwise
Programs reads STDIN looking for either puzzleFile format lines or Solver output lines
If the input is in puzzleFile format the program will generate solver input lines.
If the input is in Solver output lines format the program will expect a -f puzzleFile paremeter.
Using both these input streams program will then generate display .html output.
Game Rules
The layout of a minefield is described using a rectangular grid with integers and gaps.
Each number indicates the proximity of mines on directly adjcent squares (8 directions)
Mines cannot be on numbered squares and there is no board wraparound.
Each Minesweeper puzzle Input as follows can be any size rectangle
#iMine iMine_220917.txt
.0..00...2...1..
...3..3....2..0.
2....1....43.1..
3.......3.3.....
.3..2..3.3...3.1
..1.....2....3..
0....0..2..1.1..
....1.0.....1..1
.2.0...1..3.....
...0..0.0..3.22.
1.1.3....13.....
......2.....3..2
or this minimal test
#iMine iMine_test03.txt
0...0
..1..
0...0
to generate an SMT2 input file.
OR Process results from solver in the following format
sat
( (V0 9)
(V1 7)
(V2 5)
(V3 3)
....
to generate an html table as output.
The Solver results are read,
alongside re-reading the puzzle file, to generate answer
display table in html. The Red “<->” squares indicate the
placement of a hidden mine. Green “.” squares are empty,
clue squares show the clue value.
The results are validated by checking each of the clue numbers
has the correct numbers of mines in the surrounding squares.
VALIDATION FAIL or VALIDATION PASS is provided.
No comments:
Post a Comment