8 ms·
How to Build Minesweeper with JavaScript
- duiker101 7y agoThat first image really needs to be the game itself. I had such an instinct to click it as soon as I saw it and was sad when I noticed it was just an image. Overall the article is nice, if a bit dated, but at least it's a change from a new reactive library.
- dylan604 7y agoIt looks like they may have taken your advice. I came across this thread 9 hours after you, and the image was of a game in progress
- duiker101 7y agoYeah it was like that even before! I want to actually play the game! Not just see an image :)
- maynman 7y agoGood call! I agree, I think that would be better. Unfortunately the WordPress theme I'm using wouldn't let me do that by default. I'll have to do some research to see if there is a good plugin for that :)
- duiker101 7y agoThanks for considering it already! I don't really have any WP knowledge but maybe you could just slap it in an iframe?
- IvanK_net 7y agoMy friend (Math genius) made a video tutorial about writing Minesweeper in JS in a Notepad https://www.youtube.com/watch?v=OuahlosQ1m0 https://www.youtube.com/watch?v=OuahlosQ1m0 * It is in Czech :(
- ronilan 7y agoHere is my implementation from 2014 (with jquery...). Watch out. It has lots of bugs! http://www.ronilan.com/bugsweeper/ http://www.ronilan.com/bugsweeper/
- AlanSE 7y agoAwesome job implementing a single-click clearing when clicking on, say, a 2 with 2 marked mines next to it. The original Windows version where you had to double click was too cumbersome. https://github.com/AlanCoding/AlanCoding.github.io/blob/master/old/mine.html https://github.com/AlanCoding/AlanCoding.github.io/blob/mast... This was my version. I need to go re-host it somewhere, but you would not be much surprised by its functionality. My only unique feature was a wider variety of expressions of the smiley face button.
- d--b 7y agoIn a notebook: https://observablehq.com/@benjaminadk/minesweeper https://observablehq.com/@benjaminadk/minesweeper
- kraucrow 7y agoAren't people afraid of being kicked and beaten with sticks in 2019 if they build things with jQuery.
- have_faith 7y agoIt's a shame jQuery gets demonised so much, it's still a great tool to use even in 2019. Don't use it for the wrong job (web apps) and there's nothing wrong with it. It's actually strange you can meet people who learned something like React/Angular as an intro JavaScript and don't know how to do simple things outside of a framework without a tutorial.
- FreeFull 7y agoModern Javascript standards have incorporated a lot of things that have started their life in jQuery. What advantages does jQuery still have?
- rofo1 7y agoSure, when you need to update 1 single thing once, you can use vanilla js. But when you need to do more than that, you'll realize jQuery is still useful (assuming you don't use a framework or whatever). Either you will use something like jQuery or you'll reinvent by writing the methods yourself. IMO it's still relevant, despite the hype of other frameworks.
- staticvar 7y ago> But when you need to do more than that, you'll realize jQuery is still useful Such as?
- purerandomness 7y agoSee here: https://medium.com/@mattburgess/in-defence-of-jquery-4a8b20f4696b https://medium.com/@mattburgess/in-defence-of-jquery-4a8b20f... In general, jQuery is an amazing wrapper around native JS with a saner API and countless hours of different browser quirk workarounds to make sure that what you try to do works in all modern browsers and IE.
- lowdose 7y agoGoogle Chrome Labs released a very shiny typescript minesweeper on https://proxx.app https://proxx.app The source code is on Github https://github.com/GoogleChromeLabs/proxx https://github.com/GoogleChromeLabs/proxx
- slig 7y agoThanks for sharing it here. I saw Proxx on /r/WebGames last week, but didn't know it's open source.
- kaycebasques 7y agoHere’s a technical overview on it. Most interesting thing for me was how they made it accessible and feature phone support. https://web.dev/proxx-announce https://web.dev/proxx-announce Disclosure: Work on same team as the PROXX people
- lowdose 7y agoThank you for open sourcing this. Across Googles github accounts there are some amazing showcases that offer an invaluable source of inspiration. The web.dev site is awesome! I actually came across proxx after I forked the website. Eleventy seems to be a robust static site framework with nifty template options. I was a bit disappointed the actual dynamic part of the website was removed a couple of months ago during migration to eleventy. The express server, url fetching of lighthouse results & the option to save this in Firebase. For me this is the most interesting part of the website. How to setup a fetching api & Cloud Firestore with identity features. It would be awesome if devsite.js would be included for the people that want to take a peak under the hood.
- tazard 7y agoI guess this is a good time to share my implementation too. Unfortunately it's pretty much desktop only, but includes a high scores board! https://github.com/reed-jones/minesweeper_js https://github.com/reed-jones/minesweeper_js And to play it: https://minesweeper.zone/ https://minesweeper.zone/
- schwartzworld 7y agoThis was a lot of work and you should be really proud. One suggestion which could simplify things. I noticed this bit of code: var getNumberColor = function( number ) { var color = 'black'; if (number === 1) { color = 'blue'; } if (number === 2) { color = 'green'; } // etc } You mention using a switch statement, but why not just use an array and look it up by the index?
- rezistik 7y agoAnd why not just return the result instead of assigning it to something you eventually return?
- winrid 7y agoThe argument against this is usually one return statement is preferred.
- maynman 7y agoYep, that's why I chose to implement it that way. I generally prefer single return statements. Plus my day job enforces it as part of the coding convention, so force of habit too haha.
- gatherhunterer 7y agoThe initial assignment is used as a base case. Returns in a conditional statement are often used as an "escape" when you want to get out of a function (e.g. null checks). This is purely a stylistic choice whereas using constant time lookup over conditional evaluation could be argued to have some performance impact (although in this case it would not be meaningful). That said, I don't see anything about this choice that needs to be defended.
- aykutcan 7y agoWell. it is good tutorial but there is a little problem. In minesweeper mines should be generated after first open. You can't hit mine at first click it must empty or number.
- dylan604 7y agoIs this true? I remember plenty of times unsuccessfully guessing the first block to be a mine. Maybe I'm remembering incorrectly?
- sethammons 7y agoBack in ancient windows, I definitely picked poorly and died on my first click multiple times. However, it is an interesting optimization.
- WorldMaker 7y agoThe version bundled with Windows has always had a first click check to avoid mines, but a lot of clones don't. I remember back in my AOL days in the 1990s it was very much a sign of a bad clone and an immediate uninstall, though I don't recall why I went through so many clones at the time. (I think I was looking for more challenge having got tired of even "Expert Mode"? I was a strange kid.) (The best clones not only did a first click was safe build out, but also a solvability check that the first click opened enough hints that every puzzle was theoretically solvable on given hints alone.) The version included in Microsoft Entertainment Pack 1 prior to Minesweeper being bundled with Windows might not have had that check, my memory is fuzzy on that. I'd be surprised how many people remember it from the Entertainment packs before Windows 3.1. The clone that I recall most Mac users had in 90s, such as was on school computers at the time, definitely did not have a first click fix up.
- cumwolf 7y agocool tutorial, love all of the code examples. Some of that code is brutally unreadable with all of the nested statements and loops. I guess it works for the tutorial but ooof!
- marshmellman 7y agoUh oh. Since folks are posting their own implementations, here’s mine, written as an exploratory exercise for Angular2: https://github.com/jonmellman/angular2-minesweeper https://github.com/jonmellman/angular2-minesweeper https://jonmellman.com/minesweeper/ https://jonmellman.com/minesweeper/ Grimace
- BZH314 7y agoMSFT, our multiplayer Twitch Plays implementation of minesweeper, playable directly with your mouse (left click to dig, middle click to flag): MineSweeper For Twitch (MSFT) [1] ---- [1] https://www.twitch.tv/bzh314 https://www.twitch.tv/bzh314
- mikehodgson 7y agoI'm sure there's only a few ways to do it, but this code is really similar to the one I wrote back in December: https://github.com/mikehodgson/minesweeper https://github.com/mikehodgson/minesweeper It is playable here: https://sweeper.games https://sweeper.games No jQuery, just straight CSS/HTML/ES6
- wilhil 7y agoI just tried playing! You have a bug, there is no way to unmark a cell, so, when I did one incorrectly, I couldn't click on it :(
- mikehodgson 7y agoThanks for the feedback, just pushed a fix for it! :)
- dylan604 7y agoThis playable version seems to be missing the feature of auto-revealing the squares, usually a ctrl-click on a square to compare against placed flags. It's actually rule 5 from the linked page
- mikehodgson 7y agoThat feature is implementation specific, not a rule of the game. I've never used it, so I didn't bother implementing it.
- dilatedmind 7y agoI was working on a multiplayer minesweeper game in elixir and react a couple years back to try and get a better understanding of otp. https://mines.gdf3.com https://mines.gdf3.com https://github.com/slofurno/minesweepers-ex https://github.com/slofurno/minesweepers-ex https://github.com/slofurno/minesweepers-front https://github.com/slofurno/minesweepers-front Wound up spending most of my time focusing on performance. Large boards (say 4000x4000) naively represented by a map in elixir consumed too much memory and trying to render 16 million dom elements in react didn't fly. Never got around to basic ui stuff like setting player name and color, but I thought the bots were pretty cool.
- goddtriffin 7y agoAn MMO Minesweeper Royale.... Not a bad idea actually! This definitely inspires me to make my own!
- tomjohnson3 7y agoexcellent post. 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? 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 may be a candidate for flattening. so - your handleClick function could be rewritten (with stuff removed) as: 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... } 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. ...and how do you know when something can be flattened? if there is no code after the if statement and the end of the function - just swap the logic and return early. e.g., this: var handleClick = function( id ) { if ( !gameOver ) { // ...lots of code and if statements... } // ...but no code after the block before returning from the function... } ...turns into this: var handleClick = function( id ) { if ( gameOver ) return; // NOTE: logic check change... // ...do the stuff in the block here... } ...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. 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.
- sethammons 7y agoI'm a big fan of early returns; keeping cyclomatic complexity down can help readability. Idiomatic Go captures this too.
- maynman 7y agoThanks for the kind words, and thanks for sharing! That is a cool pattern. I definitely have a little too much nesting going on in that function, and it could use some refactoring. I've always felt funny about multiple return statements though, which is probably one reason why a pattern like this doesn't usually come to my mind when considering how to refactor code. I've always liked having one exit point at the end of functions because programmers naturally expect a function to return at the very end. I think minimizing the number of return statements is generally a good thing, but perhaps I have been too strict about applying that rule.
- cbau 7y agoI built a copy of Minesweeper using AngularJS for fun that may be instructive. Demo: http://ceasarbautista.com/minesweeper/ http://ceasarbautista.com/minesweeper/ Source: https://github.com/Ceasar/minesweeper https://github.com/Ceasar/minesweeper
- NohatCoder 7y agoThe game board is a well ordered grid, I can't fathom why you'd not organise it into an array. The cell object has 3 completely redundant fields. Most of the code just checks the mined parameter of cell objects, but for some reason there is also an isMined function. The code placing mines uses its own data structure to keep track of where mines have been placed, rather than the board data, and manages to be O(n^2) instead of O(n) because of that choice. Overall it is code that takes a lot of unnecessary detours.
- nojvek 7y agoOne weekend I was bored and made a React version of minesweeper. Needless to say I had a lot of fun. Emoji minesweeper: https://codepen.io/nojvek/full/KjLxdx https://codepen.io/nojvek/full/KjLxdx