Now that we’ve got a prototype of our Minesweeper game nailed down, let’s take a moment to do some design. A hand-wavy “eh, make it like the Windows version” has been all we’ve needed to get this far, but it’s now time to figure out, with slightly more specificity, where we’re going.
Playfield Actions
I wanted to keep the interface as simple as possible, and had hoped to allow only a single action on the playfield: uncovering a cell. Unfortunately, playtesting proved this infeasible; we must allow two actions:
- Uncovering a cell
- Flagging a cell (as a potential mine)
Both actions will be triggered by touching a cell, so we’ll need some way to differentiate them. I’ve opted to go with a modal approach; we’ll try to use a UISegmentedControl
in the UR corner of the playfield’s nav. bar to toggle between the two modes.
As for what each action will do, well, it depends on whether the touched cell is mined, covered, and/or flagged: Attempting to uncover an already uncovered or flagged cell has no effect. Uncovering a mined cell ends the game. Uncovering any other cell reveals the total number of mines in its 8 neighboring cells.
Mined | Covered | Flagged | Effect |
---|---|---|---|
Yes | Yes | Yes | No Effect |
Yes | Yes | No | Ends Game |
Yes | No | Yes | No Effect |
Yes | No | No | No Effect |
No | Yes | Yes | No Effect |
No | Yes | No | Show Count |
No | No | Yes | No Effect |
No | No | No | No Effect |
Attempting to flag an uncovered cell will have no effect, while flagging a flagged cell will remove the flag, and flagging an unflagged cell will add a flag.
Mined | Covered | Flagged | Effect |
---|---|---|---|
Yes | Yes | Yes | Remove Flag |
Yes | Yes | No | Add Flag |
Yes | No | Yes | No Effect |
Yes | No | No | No Effect |
No | Yes | Yes | Remove Flag |
No | Yes | No | Add Flag |
No | No | Yes | No Effect |
No | No | No | No Effect |
Status Indicators
In addition to the playfield itself, we’ll need to display some additional information to the player:
- Number of mines on the board
- Number of flags placed
- Elapsed time
- Status (in-progress, solved, or failed)
I’m going to try to stuff all this information into the title of the playfield’s nav. bar, in the form of a string like this:
H:MM:SS FF/NN
where:
H:MM:SS
is the elapsed timeFF
is the number of placed flagsNN
is the number of mines
We’ll indicate the status of the game with either a default blue (in-progress), green (solved) or red (failed) nav. bar.
Meta
Now that we’ve sorted out how the “game” part of our game will work, it’s time to sketch out the design of its environment: How will a player start, pause, and resume games? How will high scores be tracked?
Well, let’s make the main menu of the program a UITableView
. This table will contain an editable list of puzzles created by the user, sorted by creation date (most-recent first). Each row of the table will display:
- Puzzle size and mine count, e.g. “30×16 (99)” or “16×16 (40)”
- Elapsed time and status
The “status” will display either “Solved” or “Failed” for complete puzzles, or a percentage for in-progress puzzles. The percentage will be calculated by taking the ratio of uncovered cells to unmined cells. A player will display a puzzle by tapping its row. A player will return to the main menu by touching the “back” button on the puzzle’s nav. bar; this will also save the puzzle state to disk/flash.
Puzzles will be added with a “+” button in the UR corner of the main menu’s nav. bar. This button will bring up a modal screen with 3 pre-defined puzzle sizes, as well as UI elements which allow the user to define a custom puzzle. Custom puzzles must be between 2×2 and 500×500 cells large, and have between 1 and (width-1)*(height-1) mines. Puzzles will be generated pseudo-randomly. No special provision will be made to ensure that a user’s first touch is “safe”.
High scores will be accessed via a button in the UL corner of the main menu’s nav. bar. This button will display a UITableView
, listing each size of solved puzzle, and the best time for clearing that size. Rows will be sorted by width, then by height, then by number of mines.
Timers
Minesweeper is fundamentally a timed game, and our version will therefore keep track of the total time an unsolved puzzle is displayed. When a user returns to the main menu from a puzzle, the timer for that puzzle will be effectively paused. When a user clears the last unmined cell in a puzzle, its status will be updated, and its timer stopped. If a user uncovers a mine, the puzzle’s status will be updated, and its timer stopped.
Conveniences
There are two more features I’d like to add for the user’s convenience: auto-clear and auto-save. “Auto-clear” will automatically attempt to uncover all the neighbors of any uncovered cell with no neighboring mines. “Auto-save” will automatically save the current puzzle’s state (if any) when the program terminates.
Money
A final consideration: How will we charge money for this app? While the purpose of this project isn’t really to generate revenue, I think this is a valuable thought experiment.
I’m inclined to try the “freemium” route, since AAPL has given it their blessing by enabling in-app purchases for free applications. I think the right approach is to “lock” the expert (30×16/99) and custom puzzle levels in the basic version, let users download that for free, and offer a $0.99 “unlock” in-app purchase.
Since I haven’t worked with in-app purchases before, I’m sure this will be an interesting learning experience.