code • words • emotions

Daniel Janus’s blog

2048: A close look at the source

2 April 2014

Dust has now mostly settled down on 2048. Yet, in all the deluge of variants and clones that has swept through Hacker News, little has been written about the experience of modifying the game. As I too have jumped on the 2048-modding bandwagon, it’s time to fill that gap, because, as we shall see, the code more than deserves a close look.

I’ll start with briefly describing my variant. It’s called “words oh so great” (a rather miserable attempt at a pun on “two-oh-four-eight”) and is a consequence of a thought I had, being an avid Scrabble player, after seeing the 3D and 4D versions: “what if we mashed 2048 and Scrabble together?” The answer just lended itself automatically.

Letters instead of number tiles, that was obvious. And you use them to form words. It is unclear how merging tiles should work: merging two identical tiles, as in the original, just wouldn’t make sense here, so drop the concept of merging and make the tiles disappear instead when you form a word. In Scrabble, the minimum length of a word is two, but allowing two-letter words here would mean too many words formed accidentally, so make it at least three. And 16 squares sounds like too tight a space, so increase it to 5x5. And there you have the modified rules.

I cloned the Git repo, downloaded an English word list (EOWL), and set out to work. It took me just over three hours from the initial idea to putting the modified version online and submitting a link to HN. I think three hours is not bad, considering that I’ve significantly changed the game mechanics. And, in my opinion, this is a testimony to the quality of Gabriele Cirulli’s code.

The code follows the MVC pattern, despite not relying on any frameworks or libraries. The model is comprised of the Tile and Grid classes, laying out the universe for the game as well as some basic rules governing it, and the GameManager that implements the game mechanics: how tiles move around, when they can merge together, when the game ends, and so on. It also uses a helper class called LocalStorageManager to keep the score and save it in the browser’s local storage.

The view part is called an “actuator” in 2048 parlance. The HTMLActuator takes the game state and updates the DOM tree accordingly. It also uses a micro-framework for animations. The controller takes the form of a KeyboardInputManager, whose job is to receive keyboard events and translate them to changes of the model.

The GameManager also contains some code to tie it all together — not really a part of the model as in MVC. Despite this slight inconsistency, the separation of concerns is very neatly executed in 2048’s code; I would even go so far as to say that it could be used as a demonstration in teaching MVC to people.

The only gripe I had with the code is that it violates the DRY principle in several places. Specifically, to change the board size to 5x5, I had to modify as many as three places: the HTML (it contains the initial definition for the DOM, including 16 empty divs making up the grid, which is unfortunate — I’d change it to set up the DOM at runtime during initialization); the model (instantiation of GameManager); and the .scss file from which the CSS is generated.

While on this topic, let me add that 2048’s usage of SASS is a prime example of its capabilities. It is very instructive to see how the sizing and positioning of the grid, and also styling for the tiles down to the glow, is done programmatically. I was aware of the existence of SASS before, but never got around to explore it. Now, I’m sold on it.

To sum up: 2048 rocks. And it’s fun to modify. Go try it.