Skip to content

Instantly share code, notes, and snippets.

@veu
Last active August 29, 2015 13:57
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save veu/603535c10c8516de15cb to your computer and use it in GitHub Desktop.
Save veu/603535c10c8516de15cb to your computer and use it in GitHub Desktop.
2048 in 491 bytes of JavaScript and HTML.
<body onload="function M(c,d){for(i=H=16;i--;G|=p>>11)for(p=B[m=V(j=i%4+1)];--j?(q=B[n=V(j)])?p-q?0:h=c?0:B[p?S+=B[m]*=2:B[i++,m]=q,n]=d:L=localStorage:0;)R=Math.random}function V(x){if(x)return(D>1?4-x:x-1)<<D%2*2|i-i%4>>D%2*2;for(i=H|R()*H;B[--i%H];);B[i%H]=2<<R()+.1}(onkeyup=function(e){D=e?e.which-37:B=[];D>>2||M()|V(e?h:V());for(D=h=4;D--;)M(1);for(h=(G|h?S+' / '+(L.S>S?L.S:L.S=S):S)+'<table border>';H;P.innerHTML=h+='<th width=50 height=50>'+[B[H]])H--%4?0:h+='<tr>'})(S=G=0)"id=P>
@subzey
Copy link

subzey commented Apr 9, 2014

I think, p&& check in p&&p-q is redundant.

If I understand right, p is taken from B array, whose values may be only positive integers or undefineds. Thus, the only "falsy" value is undefined that is coerced to NaN in p-q and whole condition becomes falsy.

@veu
Copy link
Author

veu commented Apr 9, 2014

@aemkei

  • .which may work, have to try later
  • Changing it to e.which%4 would require changing the mapping and also means that all keys can be used which is kind of ugly (at least for the fully featured version).
  • Joining the two functions is likely not worth it because of longer calls and bytes needed for if/else or if and return.
  • The quotes are only two bytes whereas replacing >> everywhere would likely generate many more bytes.

@subzey You're right about p&&p-q but I'll have to check whether that breaks assumptions made in the code that follows. Not sure whether I can use it.

@subzey
Copy link

subzey commented Apr 9, 2014

for(i=H;i--;/*...*/)~i%4?0:h+='<tr>'
for(i=H;i;/*...*/)i--%4?0:h+='<tr>' // -1 byte

Upd: There's more maniacal version:

for(;H;/*...*/)H--%4?0:h+='<tr>' // -4 bytes

Although global "constant" H is changed, it doesn't affect M() and V() as in M() its value is reverted to 16 and V() is always called after M().

@veu
Copy link
Author

veu commented Apr 9, 2014

Haha, that's crazy. It's now 499 bytes with everything.

EDIT: And here's the bare-bones version with all suggested optimizations at 346 bytes.

<body onload="function V(x){if(x)return(D%3?x-1:4-x)<<2-D%2*2|i/4<<D%2*2;for(h=H|R()*H;B[--h%H];);B[h%H]=2<<R()+.1}(onkeyup=function(e,d){D=e?e.which%4:B=[];for(i=H=16;i--;)for(p=B[m=V(j=i%4+1)];--j?(q=B[n=V(j)])?p-q?0:h=B[p?B[m]*=2:B[i++,m]=q,n]=d:R=Math.random:0;);for(V(e?h:V());H--;H%4?0:d+='\n')P.innerHTML=d=[d]+[B[H]]+'\t|'})()"><pre id=P>

@veu
Copy link
Author

veu commented Apr 9, 2014

@subzey I tried that before and it doesn't work. M doesn't get called after the game's over leading to an infinite loop over the now always negative H.

@subzey
Copy link

subzey commented Apr 9, 2014

@veu, I've removed D>>2|G|| part and the code seems to be working correctly: http://jsbin.com/vigohuso/1/

@veu
Copy link
Author

veu commented Apr 9, 2014

@subzey That works if you don't care that any pressed key moves tiles and the game continues after reaching 2048. Btw, I found a way to use your output loop optimization and it's now 496 bytes.

@subzey
Copy link

subzey commented Apr 9, 2014

Oh… Right, sorry.
Btw, original game doesn't end with 2048 tile, you may pick "continue playing" and try to get 4096 or 8192

@veu
Copy link
Author

veu commented Apr 9, 2014

In that case removing |G might actually be closer to the original as it would update the highscore when you've reached the 2048 tile but would let you keep playing.

@mathiasbynens
Copy link

Use oninput instead of onkeyup. It’s not shorter but it feels much faster.

@xem
Copy link

xem commented Jul 7, 2014

Let's golf this: http://243game.com/ :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment