[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)