A Boulder Dash Clone in Only 20 Lines of JavaScript

June 18th, 2008

This was my very first entry for the quasi-regular, friendly 20-line JavaScript competition over at OZONE Asylum, for the month of January 2008. My entry titled “Rockford the Invincible” got the second place among some very impressive entries (I was actually a bit shocked that I got the second place).

Rockford the Invincible

In-game screenshot. Click to play!

The winning entries were:

  1. Candle Flame by Arthurio
  2. Rockford the Invincible by me
  3. Castle Wolfenstein by Mathieu “p01″ Henri

And here’s the explanation of how I managed to get placed above p01’s entry. Quoting Wrayal, that month’s topic setter and therefore judge:

[On Castle Wolfenstein] Ok…maybe this one needs a little justification. A lot of people may have expected this to win. It was a fantastic script, don’t get me wrong! (”stop it! You are doing impossible things! What if reality find out?!” ;)) In particular, I thought the map showed exactly the sort of flair that would normally win. But we know you’re capable of this ;) you’ve set yourself too high a standard :P What can I say, it was a great script, but I’d be interested to see what else could be implemented - I liked the rockford entry for example for the many simultaneous actions.

For those unfamiliar with the title, Boulder Dash is a classic game from the 80’s. I used to play it a lot on my Atari 800XL when I was a kid. Since being hooked on programming, writing Boulder Dash clones (or derivatives) has become a habitual thing that I do when I get my hands on a new programming language. A friend (who incidentally is the author of BoulderCat) recently joked about this habit being my version of “Hello, world!“.

Since I had to fit everything in 20 effective lines of JavaScript, this of course is not a complete implementation of Boulder Dash. For instance, Rockford, the main character, never dies. You can freely move around the monsters and stop falling boulders with your head. I’ve therefore called the game “Rockford the Invincible”. Just “Boulder Dash” would have been too obvious.

Here’s the JavaScript code behind the curtains. Note that some lines have comments with line numbers in them. Those are the effective lines of JavaScript, as (somewhat loosely) dictated by the line-counting rules of the contest.

            function move(src, dest) {
/*01*/          g.cells[dest].className = g.cells[src].className;
/*02*/          g.cells[src].className = "e";
/*03*/          return (g.cells[dest].ser = g.ser) != g.ser;
            }

/*04*/      window.onload = function() {
/*05*/          g = {
                    w: 15,
                    h: 15,
                    ser: 0,
                    rules: {
                        od: function() {
/*06*/                      [[0, g.w, g.w], [g.w, (v = [-1, 1][g.ci]), g.w + v], [g.w, -v, g.w - v]].every(function(vs) {
/*07*/                          return ("wod".indexOf(g.cells[i + vs[0]].className) > -1 && g.cells[g.d = i + vs[1]].className == "e" && g.cells[i + vs[2]].className == "e") ? move(i, g.d) : true;
                            });
                        },
                        trbluvcm: function(o) {
/*08*/                      ([(m = (o >> 1) - 1), 0].every(function(dv) {
/*09*/                          return (g.cells[g.d = i + [-g.w, 1, g.w, -1][nv = (g.ci + dv) & 3]].className == "e") ? move(i, g.d, g.cells[i].className = g.k.charAt(nv + o)) : true;
                            })) ? g.cells[i].className = g.k.charAt(((g.ci - m) & 3) + o) : false;
                        },
                        qfkj: function() {
/*10*/                      ("esd".indexOf(g.cells[g.d = i + (nv = [[0, 0], [-g.w, 1], [1, 2], [g.w, 1], [-1, 3]][g.mouse ? (Math.abs(g.dx = (g.mouse.x >> 4) - (i % g.w)) > Math.abs(g.dy = (g.mouse.y >> 4) - Math.floor(i / g.w)) ? (g.dx > 0 ? 2 : 4) : (g.dy > 0 ? 3 : (g.dy < 0 ? 1 : 0))) : 0])[0]].className) > -1) ? move(i, g.d, g.cells[i].className = g.k.charAt(nv[1])) : g.cells[i].className = g.k.charAt(0);
                        }
                    },
                    cells: document.getElementsByTagName("td"),
                    maze: document.getElementById("maze")
                };

/*11*/          document.getElementById("cap").onmousedown = function(event) {
/*12*/              g.mouse = {
                        x: (g.evt = window.event || event).layerX || g.evt.x,
                        y: g.evt.layerY || g.evt.y
                    };
                };

/*13*/          setInterval(function() {
/*14*/              g.maze.className = "f_" + (++g.ser & 7);

/*15*/              for (i = 0; i < g.h * g.w; i++) {
/*16*/                  for (g.k in g.rules) {
/*17*/                      (g.cells[i].ser != g.ser) ? ((g.ci = g.k.indexOf(g.cells[i].className)) > -1 ? g.rules[g.k](g.ci & 4) : false) : false;
                        }
                    }
                }, 100);
            }

/*18*/      Array.prototype.every = Array.prototype.every || function(callback, that) {
/*19*/          for (var i = 0; i < this.length && callback.call(that || this, this[i]); i++);
/*20*/          return i == this.length;
            }

 

4 Comments

  1. ptu

    Wow!

    Very impressive! Great!

  2. Azer Koçulu

    Great Work
    /*
    bence birinci senin calisman olmaliymis, eline saglik!
    */

  3. sm1

    cool

  4. Mathieu 'p01' Henri

    Well deserved 2nd place. And as I said the continuous refinements you made on the The Invincible Rockford, along with cramming the rendering and a significant part of the game logic in 20 lines were impressive. Good job.

    I’m looking forward to see how your entry evolve in this month’s contest - http://www.ozoneasylum.com/30306

Add a Comment