In the game of Monorail, it is a more valuable to be skilled at fixing broken solutions than skilled at deducing correct solutions.
I made the iOS puzzle game Monorail. Before publishing the game, I thought I had figured out the best way to solve the puzzles. Users surprised me with a better strategy, and this experience has changed the way I write computer programs and think about the business of startups.
The object of Monorail puzzles is to complete a closed-circuit loop through all the stations (dots) by drawing rails. The loop must pass through each station exactly once and close back on itself, like an actual monorail system might in a city.
My strategy for solving these puzzles was to reason carefully about every rail before putting it down. The game was specifically designed to be amenable to this strategy: each puzzle has only one possible solution-path given the starting conditions, which makes it possible to deduce each rail placement until you have solved a puzzle.
For example, you can observe that in a solution path, each station connects to exactly two neighboring stations. (One rail in, one rail out). Thus, since a corner station has only two neighbors, you know that it must connect to those two.
I developed layers upon layers of elaborate methods to deduce what rails must be placed on the board. I solved puzzles by using logical reasoning, placing rails one-by-one until I have completed the path.
Better Strategy: Iterate-and-Repair
When I shipped the game, I used Flurry to track a bunch of statistics about puzzle-completion time because I was worried the puzzles would be too difficult. After looking at the stats, however, I found that many users were whipping through puzzles I thought I had designed to be super difficult. How? They found a superior strategy.
I found some of the best monorail solvers and observed them. They would:
- Start by guessing random paths and just drawing whatever comes to mind.
- Fix mistakes.
- If things ever look hopelessly messed up, then press the CLEAR button and start over.
I call this the Iterate-and-Repair strategy.
It turns out to be easier and faster to iterate from an existing but wrong solution, than to deduce a correct solution from scratch. Even if you have to occassionally press the “clear” button to start over.
This realization inspired me to be more headstrong when writing computer programs. I now put more emphasis on iteration and refactoring from a reasonable starting point, rather than trying to figure out the best possible design ahead of time. If the code gets totally screwed up, I press the metaphorical clear button and use what I’ve learned to devise a new and better starting point.
I even used Iterate-and-Repair to write this blog post! “Good writing is rewriting.”
If this whole post is obvious to you, then congratulations, you are already an Iterate-and-Repair kind of problem-solver. To me, this was kind of a revelation. I started out as more of a Careful-Logical-Deduction kind of guy. I think this was influenced by my undergraduate education in mathematics at MIT, where so much emphasis is placed on logical reasoning and certitude. Indeed, I’ve observed that many of my MIT friends who play monorail tend toward Careful-Logical-Deduction.
Now I’m more of an Iterate-and-Repair kind of guy, and I think I’m a better puzzle-solver, better programmer, and a better startup founder for being so.