Website logo depicts joriszwart.nl

I ❤ to create appealing stuff

Introduction

You can play it here: games/javascript-tetris-1.5kb/jstetris.html. Use cursor keys SPACE or I J K L M SPACE to control the game.

Around the time (2004) it was probably the fastest Tetris in JavaScript available.

About speed

Other versions used absolute positioned images or divs to make up the blocks. Using a <table> with CSS-styled cell borders as a grid seemed logical.

I tried different ways of accessing the table cells:

  • getElementsByTagName('td') (slow!)
  • nextSibling
  • table.rows[y].cells[x]
  • childNodes

We're talking 30-40 milliseconds here BTW, not microseconds (remember, 2004) to iterate through the cells. Accessing it by table.rows[y].cells[x] was almost as fast as nextSibling but more convenient in terms of code-size and readability :-)

The same is true for using table methods addRow and deleteRow. Less code and more speed then moving the cells individually.

About size

Nowadays you can bring it down to 1 KB or even 512 bytes, but I did not want to give up on the scoring system, preview and VIM-bindings :-) Another time maybe!

The code

The code is 45 lines and ofcourse a great messobfuscated but pretty readable if you beautify it.

<title>1½ KB Tetris</title><style>table{border:4px groove #6b0;font-size:9}td{width:1em;border:solid #fff}pre{margin:9;float:left}</style><body onkeydown=k(event)><pre id=s></pre><table id=t cellspacing=0></table><script>var d=document,W=10,H=25,s=l=0,Y,t
function a(){for(r=B.insertRow(0),x=W;x--;)r.insertCell(0).appendChild(d.createTextNode(' '))}
function T(b,R,a){for(i=4;i--;){q='defgaeimdefgaeimdefjaeibdhijibfjdhefaeijhifjabfjeifjeifjeifjeifjheifaefjheifaefjdeifaeifheijebfjdeijeibfdeijeibf'.charCodeAt(b*16+R*4+i)-96
a(q%4,q>>2)}}function D(c,Y,b,r){T(b,r,function(x,y){p=' #'+(c?'0ff00f808'.substr(b,3):'fff')
v=S[Y+y].cells[X+x]
o=v.style
o.background=p
o.border=(c?'outset':'solid')+p
v.s=c
})}function M(O,P,R){
D(0,Y,b,r)
c=4
T(b,R,function(x,y){x+=X+O
y+=Y+P
if(x<0||x>=W||y>=H||S[y].cells[x].s)c=0})
if(c){X+=O
Y+=P
r=R}D(1,Y,b,r)
return c}function C(){X=3
D(0,-1,n,0)
for(p=0,y=Y;y<H;y++){for(f=0,x=W;x--;)f|=!S[y].cells[x].s
if(!f){B.deleteRow(y)
a()
p++}}d.getElementById('s').innerHTML='Score: '+(s+=9<<p)+'\nLines: '+(l+=p)+'\n\n© MMIV Joris Zwart'
clearInterval(t)
t=setInterval(F,650-l)
b=n
n=new Date()%7
D(1,-1,n,0)
Y=1
r=0
if(!M(0,1,r)){clearInterval(t)
alert(':-(')}}function F(){if(!M(0,1,r))C()}function k(e){switch(e.which||event.keyCode){case 74:case 37:M(-1,0,r)
break
case 75:case 38:M(0,0,(r+1)%4)
break
case 76:case 39:M(1,0,r)
break
case 32:clearInterval(t)
t=setInterval(F,9)
case 73:case 40:case 77:F()}}B=d.getElementById('t')
n=new Date()%7
S=B.rows
for(y=H;y--;)a()
C()</script>
jstetris.html