[HN Gopher] Exercise: Minesweeper in 100 lines of Ruby
       ___________________________________________________________________
        
       Exercise: Minesweeper in 100 lines of Ruby
        
       Author : damir
       Score  : 90 points
       Date   : 2024-07-20 18:45 UTC (1 days ago)
        
 (HTM) web link (radanskoric.com)
 (TXT) w3m dump (radanskoric.com)
        
       | igor47 wrote:
       | Cool! Mine sweeper is a really fun easy game to implement. I did
       | a version in Python a few years ago:
       | https://github.com/igor47/sweeper but mine is closer to 500 lines
        
         | darthg0d wrote:
         | Ditto. I did the same with GoLang a couple of years back, but
         | didn't aim for clean/terse code: https://github.com/jedib0t/go-
         | mines
        
           | BogdanOlar wrote:
           | Same, in Rust, just as an exercise to get familiar with GUIs.
           | So I ended implementing it twice, once with `iced`:
           | https://github.com/BogdanOlar/iced-minesweep-rs , and with
           | `egui`: https://github.com/BogdanOlar/egui-minesweep-rs ,
           | using the common `minefield-rs` library:
           | https://github.com/BogdanOlar/minefield-rs
           | 
           | It's a really fun exercise, and a good way to practice new
           | skills. Highly recommend it.
        
       | henning wrote:
       | The stupid thing about object-oriented programming and modern
       | software is that code like this would never make it through code
       | review on an "agile" team.
       | 
       | - "Oh, why are you doing procedural case statements? that's a
       | SOLID anti-pattern, please refactor to polymorphism"
       | 
       | - "Oh, why is the Ascii Renderer class meddling in cell mine
       | logic? `cell.neighbour_mines.zero? ? "_" : cell.neighbour_mines`
       | should be its own method in a `Mine` class that is properly
       | tested"
       | 
       | You're never allowed to just write code that solves a problem. It
       | never ends. Your team has unlimited authority to slow you down
       | with completely useless "feedback" that does not help anyone.
        
         | episteme wrote:
         | And those would be valid comments within a production system
         | maintained by a team. If you think code written as a play
         | exercise and as part of professional software environments
         | should be the same then you need to start listening to your
         | team.
        
         | breckenedge wrote:
         | Sounds like a pretty dysfunctional team, not due to code review
         | or agile.
         | 
         | When I've found myself on teams like this, as a junior engineer
         | I just did what was asked to get along and get experience. As a
         | senior engineer, I often looked for a new job. As a staff
         | engineer, I push back with as much politeness as I can.
         | 
         | Many engineers out there have traded getting it done for
         | perfection. That's not good judgement.
        
         | wagthedog wrote:
         | I'm a senior, worked with Ruby for a long time. There's nothing
         | wrong with this code, it's just Ruby, using some of its new
         | features (which all look pretty organic, style-wise). It's been
         | obvious to me for a while: good languages have a fair balance
         | of paradigms. While Ruby is more OOP than others (everything is
         | an object) it also has some fairly nice functional features
         | that are, in the context of the language, are actually fairly
         | easy to comprehend even by junior devs.
         | 
         | I'm beginning to think that the true reason for Ruby losing
         | popularity is because some find it somewhat difficult to wrap
         | their heads around it, but I don't know why -- some people
         | maybe have a completely different mental model and processes in
         | their heads? For me, from day one I got my hands on the
         | language it seemed perfectly natural. Now I program in several
         | languages with various features and properties
         | (compiled/interpreted, strong/weak types, procedural vs OOP vs
         | functional) -- all I can say is it is joy to write programs in
         | Ruby. About the only things I dislike about it are the
         | following: 1) they could've come up with better ways to signal
         | code-block boundaries (keyword `end` is used with way too many
         | different constructions) and, recently, 2) Type implementation
         | where types are declared in separate files, which is probably
         | sub-optimal. For (2), however, I do understand why it is the
         | way it is: they needed something that would not break an
         | already more or less complex argument definition rules (named
         | arguments, default values for named arguments, etc.) and also
         | something that was a layer on top of the language and not so
         | much part of the language itself -- so maybe it's better this
         | way?
         | 
         | Btw, anyone used types in Ruby? Any tips? I'm still avoiding
         | this, wondering if it'd be a boilerplate and a constant
         | annoyance and waste of time. But does anyone think there is a
         | legitimate way to use it and benefit from it in Ruby (language
         | being interpreted and not compiled)?
        
           | teaearlgraycold wrote:
           | Types are why I stopped using Ruby. TypeScript may not be
           | elegant, but it's got a great type system.
        
       | twobitshifter wrote:
       | don't you have to be able to flag the mines?
        
         | msephton wrote:
         | Indeed, it's an important omission.
        
         | RodgerTheGreat wrote:
         | Flagging mines is a nice convenience/usability feature, but if
         | you're aiming for minimalism, the game can be considered
         | complete when mine locations are the only un-revealed tiles.
        
         | IncreasePosts wrote:
         | If you're a beginner you do.
        
       | akdfax wrote:
       | Very nice syntax. Ruby is definitely underappreciated at the
       | moment.
        
       | pooriar wrote:
       | I'm currently implementing my favorite 2 player board game -
       | Raptor - in Ruby, and this article is giving me great ideas for
       | how to structure it better. Thanks so much to the author for
       | writing this up!
        
       | RodgerTheGreat wrote:
       | I had a go at an implementation of my own in Lil, using an
       | imperative style rather than OOP. I tried to loosely follow the
       | organization as shown here, but opted for a very different board
       | representation, and I included some niceties like displaying
       | board legends to aid in choosing the proper coordinates.
       | 
       | https://github.com/JohnEarnest/Decker/blob/main/examples/lil...
       | 
       | I'm really not convinced that OOP simplifies or clarifies this
       | type of program.
        
         | codesnik wrote:
         | I'd too probably write it in Ruby using classes basically just
         | as modules and not much else. It's totally fine using simple
         | arrays and hashes in Ruby for data structures. For example,
         | unlike in many other languages, board could be just a hash of
         | booleans addressed by "tuples", like @board = {[x1, y1] =>
         | true, [x2, y2] => true}, which makes neighbours check trivial,
         | while board will be sufficiently compact.
        
       | raymond_goo wrote:
       | I raise you 49 lines of typescript
       | 
       | https://stackblitz.com/edit/gridgame-minesweeper?file=index....
        
         | fuzzy_biscuit wrote:
         | Not a great analog since the gridgame dependency being pulled
         | in is already over 200 lines.
        
       | waf wrote:
       | Fun exercise! I found that the Ruby in this post resembles modern
       | C# (probably because Ruby is a gold standard in readability, and
       | in the last 5 years or so C# has been making big strides in
       | readability). I've recreated the Ruby code mostly line-for-line
       | in C# and posted it here:
       | https://gist.github.com/waf/5c6a04899e8250cb9a89406b978c9bcc
       | 
       | It mapped from Ruby to C# really well. The only concept I had to
       | add was a `BoardCell` base type for the `Mine` and `Empty` types
       | so we could return either `Mine` or `Empty` in a typesafe way.
       | Everything else matched conceptually 1-1.
       | 
       | It's 118 lines total, with 18 lines of whitespace, so 100 lines
       | exactly. I figure the original Ruby code was also not counting
       | whitespace so it's a fair comparison. I tried to not use any
       | "code golf tricks" that would minimize line count. It's a full
       | program; it could be copy/pasted into a modern .NET 8 project and
       | run without any additional setup.
       | 
       | Note, I posted this same comment on the original blog post, but
       | I've posted it here too as it might be interesting for HN folks.
        
         | neonsunset wrote:
         | Thank you for making a C# variant, with K&R braces it's just
         | 102 lines, and 1.5 MB binary (quite a few un-strippable
         | baseline bits like integer formatting) when AOT compiled with 9
         | preview, we've come a long way...
        
       | oneeyedpigeon wrote:
       | Warning to Mac users: you'll need at least ruby 2.7 to run this
       | because it uses a feature called 'argument forwarding'. Looks
       | like the latest ruby installed on macOS 15 is 2.6.
       | 
       | I eventually got it working with a combination of techniques from
       | [this stackoverflow
       | post](https://stackoverflow.com/questions/8730676/how-can-i-
       | switch...) but it's not left my system in the cleanest of states.
        
         | AlchemistCamp wrote:
         | radanskoric's sibling comment is correct (but flagged).
         | 
         | Most Ruby devs I know are on Macs and none of them are running
         | the ancient version Apple installs. Just like with most other
         | languages, even JavaScript, you'll want to get a current or
         | recent version.
         | 
         | Either use a version manager like RVM (popular) or ASDF (my
         | favorite tool since it handles nearly all languages). You can
         | also install Ruby with Homebrew, but I don't recommend using
         | Homebrew for managing programming languages since you may want
         | different versions on different projects.
        
           | Jtsummers wrote:
           | It's not flagged, it's dead. Their comments and submissions
           | are all auto-killed. My guess is it's because their account
           | had one comment in 2015, no activity until 2022, and then a
           | submission. Everything from that submission in February 2022
           | on is dead (not [flagged][dead], just [dead]).
           | 
           | radanskoric: You should reach out to the mods (contact link
           | at the bottom of almost every page here) and ask to have your
           | account un-banned.
        
           | dialsMavis wrote:
           | rbenv is another great Ruby version manager.
        
       | wkjagt wrote:
       | Very fun stuff, and nice post.
       | 
       | Reminds me of my 2048 game clone in Ruby in about 100 lines
       | (https://github.com/wkjagt/2048)
       | 
       | And I just saw that I did this - oh god - 9 years ago. Time goes
       | way too fast.
        
       ___________________________________________________________________
       (page generated 2024-07-21 23:14 UTC)