excellent post.<p>can i make a (hopefully useful) comment about programming style - something that someone shared with me a long time ago when reading my code that i have found to be very valuable over the years?<p>it can be incredibly beneficial (for readability, catching logic errors, etc.) to "exit early" from "if" statements. meaning, if you find that you're nesting "ifs" more than a couple of levels deep, the code <i>may</i> be a candidate for flattening.<p>so - your handleClick function could be rewritten (with stuff removed) as:<p><pre><code> var handleClick = function( id )
{
if ( gameOver ) return;
if ( ctrlIsPressed )
{
// do stuff...
return;
}
if ( cell.opened || cell.flagged ) return;
if ( cell.mined )
{
// do stuff...
return;
}
// else do stuff...
if ( cell.neighborMineCount > 0 )
{
// ...
return;
}
// else do final stuff...
}
</code></pre>
i may have missed something, but hopefully you get the point. this simple refactoring reduced the depth of the if statements from ~5 to 1. ...many of the other functions could be flattened just like this.<p>...and how do you know when something can be flattened?<p>if there is no code after the if statement and the end of the function - just swap the logic and return early.<p>e.g., this:<p><pre><code> var handleClick = function( id )
{
if ( !gameOver )
{
// ...lots of code and if statements...
}
// ...but no code after the block before returning from the function...
}
</code></pre>
...turns into this:<p><pre><code> var handleClick = function( id )
{
if ( gameOver ) return; // NOTE: logic check change...
// ...do the stuff in the block here...
}
</code></pre>
...and this is also a great pattern for checking input variables (and returning or throwing an exception) at the top of the function, ensuring that the code following it has valid input parameters.<p>since you're sharing your coding projects on your blog (which are excellent) - hopefully you can share this tidbit about coding style with your readers and they'd find it as useful as i have.