I had fun building this and experiencing the joyful side of JS (or at least the browser ecosystem). Boarding a plane I'd had the idea of finishing a simple tetris before arrival. The game was in a working state after ~2 hours, even though I had made a few bad decisions. (it was subsequently polished, investing another few hours).
It was made with a "get things done" mindset, and the experience from dabbling with purely functional programming in Haskell was very helpful (mostly the "pure", as in "non-destructive", part).
It's nice that in Javascript we have an environment where we can code a fun game in <400 lines, without any library dependencies (not even internet connection needed) or build systems. On the downside, if it had stronger dynamic types and errors (like Python) that would have saved maybe 25% of my debugging time, probably without coding overhead.
Had you made Tetris before? Or used an external resource to see any pseudocode? Reason I'm asking is, I was doing a similar thing with Snake and it took me a bit longer (probably 4 hours) because I messed up the basic mechanics in the beginning (I didn't think of how to structure the growing body as a linked list). I want to gauge how much I suck (at least at games programming) lol.
I once spoke about it with a friend who had to do it in C. However C is a dangerous trap here, I think it gets you in the wrong mindset.
Data representation is pretty universally one of the most important things (basically the "design" part to me). Four hours is pretty quick I guess. Snake might be more difficult (but an array or llist + snake direction + board map should be straightforward). I'd done chess that week and the representation is also doable unless thinking about AI or history or... which is when I quickly go bikeshedding. Multiple different representations for different tasks (and transforming in between) might be a way to go.
I made Snake in 103 lines of ClojureScript for a talk once: https://github.com/pate/cljs-snake (LOC excludes whitespace and links to repo). Comes in under 100 LOC if you strip out the aesthetics.
It is pretty cool. Feels very much like a smalltalk-ish environment. A WebGL context is a single HTML tag and a couple of lines of code away. However you can still get the productivity boosts from an ML-like language... there are options. And ES6 supports some patterns of FP out of the box (though it is made better with small library support).
Maybe checkout Bucklescript, Purescript, or Elm for the next one :)
One of my rituals of taking a long trip is to finish a small coding project before I land. Sudoku, minesweeper, tetris, forward-propagating constraint solvers... it's a nice practice. Thanks for sharing yours!
Just because you minify and obfuscate this code doesn't somehow make it better or let you win the "contest".
I can walk through the submitter's code and understand what's happening clearly. It's fairly well structured and easy enough to read. This is 20x more valuable than any code that is produced using uncommented edge features for a perceived 5% gain. (Note that I'm making up these numbers to illustrate a point.)
"Clever" code. shudder It's confusing to read for anybody not used to it, particularly as you need to set the "initial" value to the "actual initial value"+1.
In other words, it's a crappy way to write `i-- > 0`
Note that it's not logically equivalent to
`for (var i = 5; i > 0; i--)`
because in this case the `i--` operation is applied after the body of the loop.
Try it in your browser:
for (var i = 5; i-- > 0;) { console.log(i); } //4,3,2,1
for (var i = 5; i > 0; i--) { console.log(i); } //5,4,3,2,1
This is why I actually like this syntax (and get fun out of provoking "shudder" comments).
- Can use the same limits as in ascending iteration
- Can do decrementing in for loop (no extra line)
- The arrow unambiguously signals that the iteration is correct :-)
nice, as a web developer i wanted to try my hands on making a game. which turned out to be much harder than i thought, and also see if i could do any thing with c lang, never wrote a program more than ~15 lines of code in c, so i build a tetris game, using SDL lib.
funny thing is i also represented shapes like you did as 0 or 1 on plane, but then changed to x,y list of blocks.
Nice, I like writing things under constraint; especially without internet and manuals. Seems to take away a lot of stress and open up creativity, at least it does for me [0]. I am flying to AUS soon which will have me without internet for around 21 hours again and I will try another constraint game at that time.
There's quite a few details about the official authentic tetris guidelines here, looks like it's probably reverse-engineered. https://tetris.wiki/Tetris_Guideline
I think you could optimize quite a bit of this. If you made your shape objects more robust, even just {x,y,on}, instead of doing all of those nested for loops, you could start leveraging array methods like filter to only select the ones where on === 1, then do some sort of matrix transform to swap out that x,y coord in the 4x4 with the shape you're replacing.
Either way, cool game! Pretty neat you could do that in sub 400 lines of code.
The reason why I'm (sort of) proud of this is exactly that I managed to not get hung up with such considerations and just do the obvious things. It's not a problem to scan through 200 blocks (of which often 50% will be habitated) once every 100ms or so).
If there is any need for optimization, then it would probably be to avoid DOM inefficiencies and opting for canvas or another environment.
Very neat. I was about to report a bizarre bug -- `a/d` for rotating pieces worked on my laptop keyboard but not my USB-connected keyboard -- but then I realized caps-lock was turned-on my connected keyboard. Still probably wouldn't hurt to make the conditional case-insensitive
I think the rotations feel wrong. If I get a Z piece, rotating twice should get me back where I started. Instead it's shifted sideways one space. I have to shift 4 times to get back.
The scheme used here is a 4x4 block (the minimum required to accomodate all pieces) and rotations by 90 degrees. You can rotate both cw and ccw, this works for undoing rotation of all pieces.
I had fun building this and experiencing the joyful side of JS (or at least the browser ecosystem). Boarding a plane I'd had the idea of finishing a simple tetris before arrival. The game was in a working state after ~2 hours, even though I had made a few bad decisions. (it was subsequently polished, investing another few hours).
It was made with a "get things done" mindset, and the experience from dabbling with purely functional programming in Haskell was very helpful (mostly the "pure", as in "non-destructive", part).
It's nice that in Javascript we have an environment where we can code a fun game in <400 lines, without any library dependencies (not even internet connection needed) or build systems. On the downside, if it had stronger dynamic types and errors (like Python) that would have saved maybe 25% of my debugging time, probably without coding overhead.