Hacker News new | past | comments | ask | show | jobs | submit login
Writing Tetris in Clojure (codethat.wordpress.com)
71 points by mblakele on Sept 11, 2011 | hide | past | favorite | 20 comments



Somewhat related: Tetris in Clojure and Penumbra[1]

[1]: https://github.com/ztellman/penumbra/blob/master/test/exampl...


That's much better. But they're still writing programs in 250-300 lines of code using fancy libraries in a higher-level language that would take around 100 lines of simple and direct C code.



I am absolutely sure you can write Tetris in 100 lines of C. Would you be able to maintain it in half a year? Would anyone except you at the moment of writing be able to understand it? I wrote this implementation in January, found it and understood again in one go. There is even no comments in the source file. The Clojure code is mostly self-documenting (sure thing, you still have to write comments for bigger projects). And yes, I also liked the OpenGL version more. It is very nice except some logic being based on try..catch blocks.


> Would you be able to maintain it in half a year? Would anyone except you at the moment of writing be able to understand it?

A C programmer? Yes and yes.


As the author of the OpenGL Tetris implementation, I have to agree that the use of exceptions for flow control is a little cringe-worthy. I've been meaning to clean that up since I wrote it over two years ago, and still haven't gotten around to it. Oh well.


If you can write in 100 lines of C, I can write in a 100 lines of Clojure. What's your point?


I actually know and appreciate Clojure rather well. This isn't really about Clojure; I just think Tetris and similar kinds of programs are ideally suited to C and its level of abstraction.


Having written some C in my life I'm not following your line of reasoning.


Any attempt at imposing more than C-level abstraction onto a program like Tetris results in needlessly overcomplicated code that fails the 'simple and direct' test.


I don't see any such complications in the Clojure code. Your C code fails to demonstrate anything more "simple and direct".


Come on. With the GUI?


Let's call it 150 or so with a simple framebuffer and keyboard interface. And that's with lines of code that are a lot less semantically dense than either of the two Tetris programs in Clojure that were posted.


Since people generally underestimate the amount of code a certain task needs:

Can you demonstrate this? Or, can you show at least a plausible proof-of-concept?


Here's my quick stab at it: https://gist.github.com/1210351

I haven't tested it. I made sure it compiles and gave it a few looks over. There are likely going to be bugs but fixing them wouldn't lengthen the program.

    cat tetris.cpp | sed '/^\s*$/d' | wc -l
     162
That's not far off from my 150 estimate including rendering and input code.


Here's another really old Tetris sample for pygame I wrote half a decade ago (174 non-blank lines):

http://web.archive.org/web/20060208230531/http://www.cryptop...

Looking at it now, the code has some warts. It was written on an airplane ride and I just noticed I mistakingly left out S and Z tetrominoes. Oops! It's also interesting to compare the difference in block representations with my C program; I definitely think my C representation (offsets rather than masks) is cleaner. With the Python mask representation, I use a nested list transpose to take care of rotations: list(reversed(zip(*shape))). While that's a neat APL-style idiom, Python isn't really giving me any leverage over C. For example, for clearing rows in Python I use list slice lvalues. Those are useful, but here C gets the job done just as conveniently with memmove and bzero.

Anyway, it could be a lot better, but it's still simpler than most of the tutorial-style game samples littering the net.


Add the OpenGL calls and your program will not be shorter than the Clojure program in any way that is interesting.


Its not really fair to ask the C code to include OpenGL calls -- a pretty verbose API -- to compare it against the Clojure code which has default access to the Java Swing library, and GUI widgets.

Looking at the game logic in both examples, I'm convinced by psykotic. Both programs are fine, but the Clojure one doesn't seem to add any extra higher level cleanliness or abstraction, over the plain old C code.

Not to say that this holds in general, as code bases grow; or to take from the original tutorial in any way; just that I agree with that for a simple game like tetris, you don't see any benefit of the higher level abstractions, as implemented here.

Also, you have to give psykotic some credit for putting the time into writing a quick proof of concept to back up the opinion expressed!


I am glad we are agreed it would still be shorter. It would also by my standards be simpler and more direct. But I'm not out to convince you or anyone else of that. Make up your own minds.

You're defining the term "in any way that is interesting" according to your prejudices and I am defining it according to mine. Let's leave it at that.

Zach's program is a lot nicer than what was originally posted. But please take a look at my program and tell me where additional abstractions would noticeably improve semantic and syntactic clarity. I can't find anything. The only thing that suggests itself is the recurring 'for (vector *v = t.v; v < t.v + 4; v++)' idiom. It's annoying to write bare-handed for loops, but I don't lose sleep over it.


I would love to see that in ClojureScript.




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

Search: