That 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.
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.
This 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
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.
Thanks 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.
Awesome 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.
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.
The 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.
cool 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!
It'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.
Unless you are doing things like modifying a Google-style speadsheet of 5000+ columns and rows, you won't see much of a performance loss from using jQuery.
It does add a microscopic bit of weight to your page and some milliseconds to your load time, but that's it. It's a ressource that is smaller and faster to load than the content of the page. In my opinion, this argument is meaningless. Modern SPA frameworks are slowing the web way more. Loading your jQuery scripts async will make this transparent for the user.
In the edge-cases where jQuery is slower than native JS (because of polyfills, mostly), there's nothing stopping you from using those directly.
Unless you are Netflix and micro-optimizing your homepage to the millisecond, there's no hard reason to avoid jQuery. I believe that those slight performance losses are worth the trade for the benefits of using a strong and well tested framework that has browser support and lowers development time. I'd trust non JavaScript experts to use jQuery on my projects, I can't say the same for raw JavaScript.
Trend-driven development is a pitfall. Boring technologies are where it's at.
I still use it for most websites I build. Ruby + jquery are still great!
I’ve inherited a ton of backbone, angular, react projects and it’s always a pain sourcing devs for whatever random thing a project was written in 1-8 years ago. Jquery is just jquery and you can put anyone on it.
EXCEPT I reached out to the lambda school contractor program for a work project and was pretty shocked they only do node+react.
[+] [-] duiker101|6 years ago|reply
[+] [-] dylan604|6 years ago|reply
[+] [-] dilatedmind|6 years ago|reply
https://mines.gdf3.com https://github.com/slofurno/minesweepers-ex 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|6 years ago|reply
[+] [-] mikehodgson|6 years ago|reply
It is playable here: https://sweeper.games
No jQuery, just straight CSS/HTML/ES6
[+] [-] dylan604|6 years ago|reply
[+] [-] wilhil|6 years ago|reply
[+] [-] lowdose|6 years ago|reply
[+] [-] kaycebasques|6 years ago|reply
https://web.dev/proxx-announce
Disclosure: Work on same team as the PROXX people
[+] [-] slig|6 years ago|reply
[+] [-] tomjohnson3|6 years ago|reply
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:
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:
...turns into this: ...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|6 years ago|reply
[+] [-] maynman|6 years ago|reply
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.
[+] [-] ronilan|6 years ago|reply
http://www.ronilan.com/bugsweeper/
[+] [-] AlanSE|6 years ago|reply
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.
[+] [-] NohatCoder|6 years ago|reply
Overall it is code that takes a lot of unnecessary detours.
[+] [-] d--b|6 years ago|reply
https://observablehq.com/@benjaminadk/minesweeper
[+] [-] aykutcan|6 years ago|reply
In minesweeper mines should be generated after first open. You can't hit mine at first click it must empty or number.
[+] [-] dylan604|6 years ago|reply
[+] [-] schwartzworld|6 years ago|reply
One suggestion which could simplify things. I noticed this bit of code:
You mention using a switch statement, but why not just use an array and look it up by the index?[+] [-] rezistik|6 years ago|reply
[+] [-] marshmellman|6 years ago|reply
https://github.com/jonmellman/angular2-minesweeper
https://jonmellman.com/minesweeper/
Grimace
[+] [-] tazard|6 years ago|reply
https://github.com/reed-jones/minesweeper_js
And to play it:
https://minesweeper.zone/
[+] [-] cbau|6 years ago|reply
Demo: http://ceasarbautista.com/minesweeper/
Source: https://github.com/Ceasar/minesweeper
[+] [-] nojvek|6 years ago|reply
Emoji minesweeper: https://codepen.io/nojvek/full/KjLxdx
[+] [-] BZH314|6 years ago|reply
MineSweeper For Twitch (MSFT) [1]
----
[1] https://www.twitch.tv/bzh314
[+] [-] cumwolf|6 years ago|reply
[+] [-] IvanK_net|6 years ago|reply
* It is in Czech :(
[+] [-] kraucrow|6 years ago|reply
[+] [-] have_faith|6 years ago|reply
[+] [-] Raphmedia|6 years ago|reply
It does add a microscopic bit of weight to your page and some milliseconds to your load time, but that's it. It's a ressource that is smaller and faster to load than the content of the page. In my opinion, this argument is meaningless. Modern SPA frameworks are slowing the web way more. Loading your jQuery scripts async will make this transparent for the user.
In the edge-cases where jQuery is slower than native JS (because of polyfills, mostly), there's nothing stopping you from using those directly.
Unless you are Netflix and micro-optimizing your homepage to the millisecond, there's no hard reason to avoid jQuery. I believe that those slight performance losses are worth the trade for the benefits of using a strong and well tested framework that has browser support and lowers development time. I'd trust non JavaScript experts to use jQuery on my projects, I can't say the same for raw JavaScript.
Trend-driven development is a pitfall. Boring technologies are where it's at.
[+] [-] SimianLogic2|6 years ago|reply
I’ve inherited a ton of backbone, angular, react projects and it’s always a pain sourcing devs for whatever random thing a project was written in 1-8 years ago. Jquery is just jquery and you can put anyone on it.
EXCEPT I reached out to the lambda school contractor program for a work project and was pretty shocked they only do node+react.