 
          
        
        Columns, the classic competitor to Tetris. Left and right arrow keys move; up cycles the order of the falling gems. Line up three matching colors in a row. Get combos and chains to score lots of point…
e='var c=6,f=12,g=24,h\ni=["red","#f80f00f808"],j=document.getEleById("c");j.widtW44height=288;|o=j5Context("2d"),p={},q,s,t,u=0,v;function w(){if(p["0,3"]){+;%}s=0;t=3;q=[];for(^aa<3;a++)q[a]=i[Math.random()*6>>0]}	_x(a,b,d){o.beginP-();o.fillStyle=darc(h+b*g,h+a,0,7,false-()} 	Wy¶Ć++Đ--\rXŔ0"TČuV9)\nÌ in p){b=a.spliı,İd=pÝ;d&&x(b[0],b[1]Ç}<Ąx(s-aŖČ A÷){return a>=f||b<0>=c||]+h+b]-1\r2\nOBï	\ra(k,z¶mÌmÈr¹m];ǒrl=mÙe=+lÐn1];e+=k;n+=z;l=exne	r=Yl]&&	e	d.push(m,l,e)}}}ņ0Ļȯa(1,0)0,11ļ-d[b];){u+=v*=2;p[++]]ɸĵd§} setIˉrval(ĂʲA(++ː)Ě	ʜs,b=t,d;d=q.shiftɫ)p[--ůɭ.=5;Ŕ;)\nǏcǏÅ;b<f-1;){d=b=a͞kƮať¸ċ!p[k̺ĝd];bÌ}͟}ʭ},50Đ	ϖonkeydown=	Õa){aʅwhich-3όÎh¢=-1||1)nA(è	(t=b)||!a&&q.unñq.pop());v;	; ';L=820;C='charCodeAt';d="";for(i=0;i<L;i++)if(e[i]<" ")for(l=e[C](i++),o=e[C](i);l--;)d+=d[d.length-o];else d+=e[i]
eval(d)
ZT0ndmFyIGM9NixmPTEyLGc9MjQsaARcbmk9WyJyZWQiLCIjZjgwBQdmBQcwBwcwZgQHODA4Il0saj1kb2N1bWVudC5nZXRFbGUEC0J5SWQoImMiKTtqLndpZHQDVzQ0AwxoZWlnaHQ9Mjg4OwR8bz1qBDVDb250ZXh0KCIyZCIpLHA9e30scSxzLHQsdT0wLHY7ZnVuY3Rpb24gdygpe2lmKHBbIjAsMyJdKXsEKzsDJX1zPTA7dD0zO3E9W107Zm9yKAReYQMVYTwzO2ErKylxW2FdPWlbTWF0aC5yYW5kb20oKSo2Pj4wXX0JX3goYSxiLGQpe28uYmVnaW5QAy0oKTtvLmZpbGxTdHlsZT1kAw5hcmMoaCtiKmcsaCthBAYsMCw3LGZhbHNlCC0oKX0gCVd5A8K2B8SGKysIxJAtLVxyWATFlDAiBxNUBMSMdQNWOSlcbsOMIGluIHApewQMYj1hLnNwbGkDxLEsA8SwZD1wA8OdO2QmJngoYlswXSxiWzFdA8OHfQQ8DMSEeChzLWEDxZYExIwDHgjCoEEEw7cpe3JldHVybiBhPj1mfHxiPDADBT49Y3x8A10rA2grYl0FDC0xXHIOMgcOXG5PQgPDrwlccmEoayx6BsK2bQXDjG0Lw4hyA8K5bV07A8eScgYRbD1tDMOZZT0rbATDkG4ECDFdO2UrPWs7bis9ejtsPWUFeG4LFGUJFHI9A1lsXSYmBQllAwlkLnB1c2gobSxsLGUpfX19BsWGMAPEuwPIr2EoMSwwKQMHMCwxBAcxBAcFxLwDCy0DDGRbYl07KXt1Kz12Kj0yO3BbAxErK11dA8m4B8S1ZAPCp30gc2V0SQPLiXJ2YWwoCMSCBsqyQSgrKwPLkCkDxJoJypxzLGI9dCxkO2Q9cS5zaGlmdAPJqylwWy0tCMWvA8mtBS49NTsDxZQ7KVxux49jBcePBBADw4U7YjxmLTE7A8KSKXtkPWIFPWEFzZ5rAw4Gxq5hBMWlA8K4A8SLIXBbawTMugMGA8SdZF07YgUHA8OMfQPNn30Dyq19LDUwA8SQCc+Wb25rZXlkb3duPQnDlWEpe2EDyoV3aGljaC0zBs+MA8OOA2gDwqI9LTF8fAMHMSkDbkEoA8OoAwkodD1iKXx8IWEmJnEudW4Gw7FxLnBvcCgpKTsEdjsDfwQJOyAnO0w9ODIwO0M9J2NoYXJDb2RlQXQnO2Q9IiI7Zm9yKGk9MDtpPEw7aSsrKWlmKGVbaV08IiAiKWZvcihsPWVbQ10oaSsrKSxvPWVbQ10oaSk7bC0tOylkKz1kW2QubGVuZ3RoLW9dO2Vsc2UgZCs9ZVtpXQ0KZXZhbChkKQ0K//
// columns.js
//
// js1k contest entry
//
// Copyright (c) 2010 Patrick Walton
//
var PLAYFIELD_WIDTH = 6;
var PLAYFIELD_HEIGHT = 12;
var GEM_SIZE = 24;
var GEM_RADIUS = 12;
var CANVAS_WIDTH = 144;
var CANVAS_HEIGHT = 288;
var COLORS = [ "red", "#f80", "#ff0", "#0f0", "#00f", "#808" ];
var canvas = document.getElementById("c");
canvas.width = CANVAS_WIDTH;
canvas.height = CANVAS_HEIGHT;
var ctx = canvas.getContext('2d');
var playfield = {};
var fallingColumn;
var fallingColumnR, fallingColumnC;
var score = 0, bonus;
function rand(n) {
    return (Math.random() * n) >> 0;
}
function sendNewColumn() {
    if (playfield["0,3"])
        playfield = {}, score = 0;
    fallingColumnR = 0;
    fallingColumnC = 3;
    fallingColumn = [];
    for (var i = 0; i < 3; i++)
        fallingColumn[i] = COLORS[rand(6)];
}
function drawGemAt(r, c, color) {
    ctx.beginPath();
    ctx.fillStyle = color;
    ctx.arc(GEM_RADIUS + c * GEM_SIZE, GEM_RADIUS + r * GEM_SIZE, GEM_RADIUS,
        0, 7, !1);
    ctx.fill();
}
function render() {
    // Erase the playfield.
    canvas.width++;
    canvas.width--;
    ctx.fillStyle = "#000";
    ctx.fillText(score, 0, 9);
    for (var pos in playfield) {
        var pt = pos.split(",");
        var color = playfield[pos];
        if (color)
            drawGemAt(pt[0], pt[1], color);
    }
    for (var i = 0; i < 3; i++)
        drawGemAt(fallingColumnR - i, fallingColumnC, fallingColumn[i]);
}
function fallingPieceCollidesWithPlayfieldAt(r, c) {
    return (r >= PLAYFIELD_HEIGHT || c < 0 || c >= PLAYFIELD_WIDTH ||
        playfield[r + "," + c] || playfield[(r-1) + "," + c] ||
        playfield[(r-2) + "," + c]);
}
// Carry out the effects of gravity!
function fall() {
    for (var c = 0; c < PLAYFIELD_WIDTH; c++) {
        for (var r = 0; r < PLAYFIELD_HEIGHT - 1; r++) {
            var pos = r + "," + c;
            var nextPos = (r+1) + "," + c;
            if (playfield[pos] && !playfield[nextPos]) {
                playfield[nextPos] = playfield[pos];
                playfield[pos] = 0;
                r = 0;
            }
        }
    }
}
function checkForMatches() {
    var i = 0, marked = [];
    function check(roffset, coffset) {
        var pos1;
        for (pos1 in playfield) {
            var color1 = playfield[pos1];
            if (color1) {
                var pt = pos1.split(",");
                var r = +pt[0], c = +pt[1];
                r += roffset, c += coffset;
                var pos2 = r + "," + c;
                r += roffset, c += coffset;
                var pos3 = r + "," + c;
                if (color1 == playfield[pos2] && color1 == playfield[pos3])
                    marked.push(pos1, pos2, pos3);
            }
        }
    }
    check(1, 0);    // - horizontal
    check(0, 1);    // | vertical
    check(1, 1);    // \ diagonal
    check(1, -1);   // / diagonal
    while (marked[i]) {
        score += bonus *= 2;
        playfield[marked[i++]] = 0;
    }
    return marked[0];
}
function tick() {
    if (fallingPieceCollidesWithPlayfieldAt(++fallingColumnR,
            fallingColumnC)) {
        // Anchor the falling column in place.
        // TODO: check for game over
        var r = fallingColumnR, c = fallingColumnC;
        var gem;
        while ((gem = fallingColumn.shift()))
            playfield[--r + "," + c] = gem;
        bonus = 5;
        while (checkForMatches())
            fall();
        sendNewColumn();
    }
    render();
}
function onKeyDown(ev) {
    var code = ev.which - 38;
    var newC = fallingColumnC + code;
    ((code == -1 || code == 1) &&
        !fallingPieceCollidesWithPlayfieldAt(fallingColumnR, newC) &&
        (fallingColumnC = newC)) ||
        (!code && fallingColumn.unshift(fallingColumn.pop()));
    render();
}
setInterval(tick, 500);
document.onkeydown = onKeyDown;
sendNewColumn();
render();