2048/ links/


2048/ is my deterministic version of Gabriele Cirulli's 2048 game derived from a game called 1024, itself derived from Three. Click on the link to see the full credentials.

I present here some details that can be used to publish on your website a version that keep high scores, with the replay associated with it. Since it is deterministic and there is no random involved, no cheating is possible: people can check the replay.

First, we need to convert most efficiently the moves in a string. We could use compression algorithms implemented in javascript before sending to the server, but it turns out for most games (and maybe all of them) the compressed version takes even more space, so we just try to encode the moves in the smaller amount of characters possible.

There is four possible moves at each step, which amounts to two bits. We can fill up to eight bits a character, but that usually yields encoding problems. We can try only six bits, giving three moves per characters, using one of the base 64 schemes. Several signs should be avoided, the "+" is one of them (because GET and POST requests encode spaces as plus signs, so they are interpreted in this way) and the default scheme uses a "+". We don't really consider that this encoding of moves should be a standard, so we just take our own encoding:

var table64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-/";
To convert a list of moves to a string, we iterate on the string. One good thing is we don't need to bother about padding, as a too long sequence will not be interpreted further:
var string_of_moves = function(moves) {
  r = "";
  for(i = 0; i+2 < n; i += 3) {
    s = 0;
    for(j = 0; j < 3; j++)
      s = s*4 + moves[i+j]%4;
    r += table64[s];
  return r;
The code for unmarshaling back to a list of moves is very simple as well. Note that in javascript you don't have euclidean division by default, so you can use little tricks to recover it: when x is a floating-point number, x|0 returns the corresponding integer, the one with the smallest absolute value. Of course, on integer numbers this operation, (bitwise or with 0 bits) is the identity function, so there is no problem here. No further trikcs in the following code:
var moves_of_string = function(s) {
  v = [];
  for(i = 0; i < s.length; i++) {
    k = table64.indexOf(s[i]);
    v.push(k/16%4|0, k/4%4|0, k%4);
  return v;