It’s Time to Revisit Minesweeper

Over a year ago I built a minesweeper clone using JavaScript, HTML, and CSS. To my delight and surprise, the project and associated tutorial became pretty popular and made it to the front page of Hacker News and Reddit.

Of course, along with the success came the haters.

Revisit minesweeper to own the haters

I received some criticism on various choices I made. As you should come to expect on the internet, some of it was respectful and some of it was not. However, as all the great ones do, I decided to channel the negative energy to become even better. I’m basically the Michael Jordan of independent, part-time, game tutorial creators.

I considered the feedback I received, ate some humble pie, and realized the haters were correct in many cases. There are definitely improvements that can be made to the original implementation, and I decided to revisit minesweeper to make a few of those changes. Check out the new version, which shouldn’t feel much different than the old one:

Play the new and improved minesweeper!

View the code on Github!

The two big improvements I made were removing jQuery as a dependency, and preventing losses on the first click of the game. I also started taking advantage of some of the newer additions to the language, like the “let” keyword for declaring variables.

Take a glance at the git history for this project. I copied the original files into a new directory and removed jQuery from each function until I completely eliminated the dependency from the project. I worked on preventing immediate losses once jQuery was completely gone.

Removing jQuery

Revisit minesweeper and remove jQuery

The jQuery library was great for its time, but it’s usually an unnecessary abstraction in modern browsers. Today’s browsers are much better at following the same standards, and we now have more native methods for accomplishing just about anything jQuery can do. Most of the changes I made involved replacing jQuery functions with native methods.

However, I still have a soft spot in my heart for jQuery, and I did find one situation while refactoring the code where I really missed having it: event listeners. It’s really easy to add and remove event listeners using jQuery. It keeps track of the references for you, which makes removing them all at once a simple method call that you can chain to other jQuery methods.

In vanilla JavaScript you have to be much more explicit about which event listeners you want to remove. You typically have to pass the callback function to the removeEventListener function, and this can be error prone when dealing with multiple event listeners and different levels of scope.

My first attempt at replacing the event listeners with vanilla JavaScript resulted in adding new event listeners to minesweeper cells every time the player pressed the New Game button. This caused us to process events multiple times on a single cell click. Chaos ensued. You can check out these two commits and see what it took to restore order.

Preventing a Loss on the First Click

While you’re looking at the changes in that first commit above you’ll also notice the code I added to prevent a loss on the first click. This is a feature in the original game that I did not consider when building the clone. It’s a nice feature to have because it’s pretty frustrating to lose the game on your first click on an empty board.

Here’s the general approach I used to implement this feature.

  1. Keep track of whether it’s the players first click on the board, and reset that variable each game.
  2. If it’s the player’s first click and he’s about to lose, remove the mine and randomly place it somewhere else on the board.
  3. If you moved a mine, recalculate the neighboring mine counts.

Hopefully that description makes sense when you take a look at the code, but definitely leave me a comment if you found any of it confusing.

Conclusion

I know you’ve all been waiting eagerly in anticipation for over a year for me to revisit minesweeper, so I’m really happy for you guys. You can all rest easy at night knowing that some random code has been made better. Of course, I also hope this was instructive to some of you.

As always, subscribe to see more brutal takedowns of my haters.