Cracking Minesweeper with Z3 SMT Solver
yurichev.com
yurichev.com
It basically translates the somewhat more complex rules into the simpler SAT rules using minisat. However sometimes needed a generator in python to make the rules :/. But still kinda nice to see it more visually, language looks like this in the end: http://sabrlang.org/code/mine/source.txt. It basically lists the requirements for middle, edge and corner blocks, than says where those blocks are on the "board."
Kinda fun, though arguably somewhat restrictive. One of the more fun ones I think is the rubiks cube: http://sabrlang.org/rubik/.
Planning on exploring more when I have some free time after a few weeks.
Here's a great resource for those interested in constraint programming: http://www.hakank.org
Sudoku examples: SABR: http://www.hakank.org/sabr/sudoku.tb
ASP: http://www.hakank.org/answer_set_programming/sudoku.lp
There's the built in construct of transitions which isn't in this example that is preloaded into SABR, but one could easily enough write the restraints required for this in clasp.
SABR envisions the universe as the "Board" and it has a given size consisting of elements and each element can have a specific state as defined by "Symbols". Then you can build on that to say what is legal for a theoretical set of elements, and how that set can transform over time, then you can define which of the Board elements correspond to the defined theoretical set.
Its way more opinionated than most other constraint programming languages, which can be mind bendy.
P.S - it's with bugs instead of mines just because fontawesome didn't have mines. No puns intended.
(The game state saved in local storage, very nice :))
Edit: only delayed in Safari.
I guess I should not buy lottery tickets today
I wrote that after reading this HN discussion [2] where someone was describing how they interview. They set the candidate up with a good JS development/test environment that the candidate is comfortable with, and ask them to implement as much of Minesweeper as they can in one hour. They also said no one has ever finished in that one hour.
As expected, I did not come anywhere near doing it in an hour. Wall time was about 7 hours, but I was doing other things during that, so it was about 4 hours working on Minesweeper. About an hour of that was testing and stumbling around the Mac character viewer trying to find good characters for bombs, flags, and such.
I'm kind of surprised no one has done it for the interviewer in an hour.
As I said I'm only a JS dabbler. Basically, every couple of years or so I'll have to do a little bit of basic JavaScript to do some simple DOM manipulation or form validation. That's just enough to keep me sufficiently aware of JS that I can at least do some reasonable guessing and googling.
I'd expect an actual JS programmer to be much faster than me.
Read a brief summary of whatever you are implementing, even if you are already familiar. This will help you understand the breadth of the problem.
Try to list in very broad terms the data structures you will need to store the state of the problem (e.g. for Minesweeper, a grid of tiles, and for each tile some status). Don't worry about whether you are using a list or a vector/array or sparse or dense matrices, just be as generic as possible.
List in very broad terms the logic of the problem. What states exist, what are the beginning/ending conditions (start/playing/win/loss), very roughly how states transition, etc. Again, avoid detail.
Identify the inputs and outputs of the problem, very broadly (e.g. user input, display for game board -- no mention of mouse, keyboard, HTML, or whatever).
Cycle through these phases a few times until they seem to agree.
From there, go wherever your brain takes you, progressively filling in details of your design. You probably still shouldn't start coding.
For a 1hr exercise, let's assume you've used 15 minutes for the design phase. Now you can begin coding. Start with the very core of the problem, writing data structures and logic around those data structures. Then get some way of displaying them and manipulating them so you can debug with feedback.
With a roughly functioning core, start filling in the rest of the design. Focus on what makes the biggest functional difference with the least effort first, if at all possible, but again, follow your brain. Try not to pick fonts before you've got everything running. Go piece by piece, until time is up.
--
As for what to Google, you'll need to know how to interface with your problem's input and output systems (like a browser), and maybe how to run timers or store your particular data structure, but most of the work is design, not research.
--
For a personal story, several years ago I failed a similar test in an interview. They asked, "How would you make an elevator?" I got lost in the details like what type of screw terminal to use for electrical contacts, and only later realized the value of prioritizing layers of abstraction. Breadth-first search, not depth-first, if you think of a problem space as a graph.
I didn't have time to include a game-over animation, an in-game timer, or a way to select different settings, but the core mechanics were all there.
Pygame is a very nice environment for games programming when you want to do something fairly simple.
We should build a collection of web remakes of the built-in OS games.
It has a bug in it. If you right click (place a flag) then right click (remove that flag) then left click, it places a flag instead of revealing.
Nice implementation though. :)
Is there a strategy such that it can consistently solve every minesweeper configuration?
I always assumed that the 50/50 guess was unavoidable on some maps but I don't know if that's true.
From all the commentary however, it's pretty clear that the answer is no.
+------
| 1
| 2
| 1 2 M
If you know there are three mines here, including the marked one, this is either +------
| M 1
| M 2
| 1 2 M
or +------
| M 1
| M 2
| 1 2 M
There's no way to ever get more information to resolve the ambiguity without guessing, and the mine probability in every square is 50%. This (or simple variants) is the most common late-game failure case. Similar symmetries can also occur on edges, and (though more rarely) even in the middle of the field.If you assume that you have knowledge of the 5 outside squares of a 3x3 corner (and any neighbors outside of that 3x3 corner) and that you know how many mines are left, you won't be able to fill in the rest without guessing 4.14% of the time on an Expert board. The most common failures are either three three-mine cases like the one illustrated here (0.440% likelihood each) or one of 16 four-mine cases (0.115% likelihood each). Given that there are four corners on the board, that sends your failure rate to at least 15.572% (actually higher, because you don't always know how many mines are left in one corner without clearing the other three).
If you want to fail fast, figure out if you have symmetry in the corners first.
One of those problems I always wanted to work on on my own, knowing that someone somewhere probably had a much better solution.
The creator wrote an explanation here: http://mrgris.com/projects/minesweepr/
This will be so useful for actually helping me understand how Minesweeper works - theoretical explanations just make my eyes glaze over more often than not.
- Can every minesweeper board be solved without guessing?
No:
1 ?
1 ?
- If a minesweeper game doesn't require guessing, is there an algorithm that can determine the next move?Yes. Just enumerate all combinations of mine/not-mine for every hidden cell, and look at all the boards that match the exposed clues. If there is a square that is never a mine, click it. If there isn't, the board requires guessing.
- Is there an efficient algorithm to do the above?
Most likely not. Minesweeper as a decision problem ("is there any solution to these given clues") is NP-complete. http://simon.bailey.at/random/kaye.minesweeper.pdf
Now I wonder how does the performance of this SAT solver compare to backtracking? Which one deals better with situations where guessing is required?