The playing field is represented by two arrays: one contains just the
buttons, since these are not going to change, and one contains the
actual state of a field, which is going to change:
Three utility functions, untouched, mines and flags, check wether is a state is untouched (neither cleared nor flagged), and count the number of mines or flags on a field; we do not show them here.
Now, the simple part is leaving and taking flags.
If the the field is Cleared which means it was explored earlier the mines are left unchanged. Mines are simply returned. If the field is Unexplored and flagged we set it unflagged and assign the zeroImg to its Button and vice versa. However, when dropping a flag we have make sure that there are not more flags on the field than mines.
The more complex part is actually exploring the field.
The function takes the same arguments but it returns a Maybe of mines. If we try to explore a Cleared field, nothing changes. If we try to explore an Unexplored field which is flagged, we return the given argument and still nothing changes, because it is inconvenient to accidently click a flag and get killed. If we try to open an Unexplored field which is a mine the function returns Nothing, and we have lost. And at last, when every other case is weeded out, we peek inside an Unexplored, nonflagged nomine field.
peek takes a list of coordinates to check. Initially this should be exactly one coordinate, namely the one we try to explore right now. adjMines calculates the number of mines around the field we explore; adjacents is a utility function which takes a positition and returns the list of its adjacent positions.
We assign the corresponding image to the button's photo and change its relief to flat (note how we compose configurations with (>>=)). If the number of mines in the adjacent fields is 0 we can savely explore all of these. So rest, the list of coordinates still to explore is united with the coordinates of the adjecent fields which are still untouched. If we forgot to apply this filter the exploration would go on forever exploring the same fields over and over again, but this way the program explores all safe fields, creating empty areas surrouned by numbers on the playfield (see Fig. 12, left).
Figure 12: hsMines after one lucky click, and a few lucky clicks later.
And just in case you don't believe this for real I finished the game ;-) (Fig. 12, right).
The excurse through the hsMines source is over for now. There is still a couple of interessting functions (such as createMines) left to explore. Have fun.