Hacker News new | past | comments | ask | show | jobs | submit login
Minesweeper in Clojure (sneakycode.net)
134 points by tosh on Nov 2, 2018 | hide | past | favorite | 32 comments



As an alternative design, I'd have gone with a data structure more like:

    #:minesweeper{:size    [w h]
                  :bombs   #{[x y] ...}
                  :flags   #{[x y] ...}
                  :guesses ([x y] ...)}


Yes that is pretty smart. One of my game design friends mentioned the same thing after I showed him the code. I sometimes feel I am still living in that oo mindset


I wrote Snake in 100 lines of ClojureScript for a talk at UCT a few years ago and used that shape of data structure: http://theronic.github.io/cljs-snake/

For anything more complex, I immediately reach for DataScript as a client-side Datalog DB.


Ha. I made a similar thing trying out p5 for the first time. https://sneakypeet.github.io/data-snake/


I did the same exercise a few months ago! Using a little React wrapper I wrote for myself:

https://github.com/Lokeh/lilac.town/blob/master/src/lilactow...

https://lilac.town/games/sweeper


the dots between squares are trippy


Lol, design is not my forte. I tried!

Btw, really great write up - I think you did a great job explaining the process of solving problems in Clojure.


Thank you. I think your design is stellar. I'm keen to go through your code too. Since moving to clojure I have found myself reading much more source code


As a next challenge, can you ensure the board is solvable without guessing? You have to delay generating it until the user has done that first click, but there are some other constraints as well.

Also, you probably want to stop clicks on marked squares from exploding the mine.


I kept right-clicking to flag the mines and didn't understand what was happening.

edit: [Shift] + Click to flag.


Shift-click flags the mines according to the description


Yeah shift click should do the trick


oh yes. I did not think of that. generating on first click should not be to difficult. what are the other constraints?


A convinent source of information about this is going to be Simon Tatham's excellent puzzle suite. Most the puzzles are built to ensure a solution without guessing.

https://www.chiark.greenend.org.uk/~sgtatham/puzzles/doc/min...

https://www.chiark.greenend.org.uk/~sgtatham/puzzles/

They're all open source and I believe available on iOS as well as android for free for mobile users too.


You can’t have enclosed areas that contain mines, there’s probably a few others.

The easiest thing to do is to write a solver which will iteratively mark squares it knows to contain a mine, or knows don’t contain a mine. If the solver can find all the mines the board is solvable. Only present the user with boards that your solver can solve.


Not parent: if you click a square and it says 7/6 then sometimes (next to a corner) you can only guess, you can't deduce the correct square to flag. There are others.


Long-press to flag would be handy on mobile.


I second this, otherwise the approach is really cool!


Do you reccomened Clojure over Haskell to learn ?


I learned Haskell first, and I thought it was a valuable learning experience. Laziness and type driven development give you a different perspective on solving problems. That said, I find Clojure to be both simpler and more pragmatic than Haskell. It requires knowing less concepts to use effectively, it encourages interactive development, and it leverages two of the biggest ecosystems by targeting the JVM and Js environments. I would recommend learning Clojure unless you feel strongly about having pervasive static typing.


Here's a video of the creator of Clojure explaining his preference for dynamic vs static languages, and how he came to the choice of making Clojure dynamic, that may help inform your decision:

https://youtu.be/2V1FtfBDsLU


I recommend Haskell over Clojure, because it will really expand and bend your mind. (I take as context your asking this question.)

Then, I recommend Common Lisp over Clojure, because that has a lot of things that are uncommon even decades after standardization.

Finally, for a practical, day-to-day driver language, Clojure is really good. It's a personal go-to for any server side coding I have to do. (I rarely do front end work and have no preferences there beyond Unity if it is a game.)


My personal experience is that most programmers either like or don't like type systems. If you don't I would highly recommend Clojure, if you do I would highly recommend Haskell.


And then there's this bunch of us that are not as dogmatic and appreciate both.

And there's also Typed Clojure, but that might not be the best experience starting out.


If you come from a javascript background, clojure would probably feel more natural


As others have said, it’s a question of what you want to get from learning.

Haskell primarily tries to answer the question, “What are static type systems capable of, and what new relationships can we achieve between code representation and code execution?”

Clojure primarily tries to answer the question, “How can we write programs more efficiently in the (relatively) short term?”


Clojure answers the question "How far can you go if your data is just immutable maps, lists and sets?"

The answer is, pretty damn far.


Learn both. If you have no functional programming experience then learning clojure first should help you get comfortable with higher order functions and other functional paradigms before diving into the type theory side of things with Haskell.


I wrote a little comparison of Haskell and Clojure a few years ago here:

https://sdegutis.com/blog/2015-02-10-haskell

And some of the cons of Haskell in that article may be addressed by these extensions:

https://sdegutis.com/blog/2015-03-17-haskell-extensions


>Compared to Clojure Rich borrowed almost all of Clojure’s standard library from Haskell. Destructuring in Clojure also looks like it came directly from Haskell.

wat? is this really true?


Um, destructuring is a very old concept in Lisp circles.

http://www.lispworks.com/documentation/lw50/CLHS/Body/m_dest...

Don't know if Rich first got the idea from Lisp or not, but it seems likely since he did a bunch of development in Common Lisp (generating C++, of all things :-D ) ages ago.

I don't remember if I heard him talk about that in the "Expert to Expert" video ( https://www.youtube.com/watch?v=wASCH_gPnDw ), or in "Simple Made Easy" ( https://www.youtube.com/watch?v=34_L7t7fD_U ). I think it was the former, but both of those are worth watching multiple times. It's also entirely possible that it was in an entirely different video of his -- but it was him.

I've yet to be disappointed in any of his talks, so if I'm wrong about the exact one, just keep watching any of his talks on YouTube till you find it. xD


Anecdotally...I'd say "hell no". I programmed in Haskell before Clojure, and starting out I was never like "this is dynamic Hasell!!" or something. The standard library never gave me Haskell vibes whatsoever. Functional programming? Sure. I don't think anyone has the market cornered on "map" or "filter".




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: