Crea un simple clon del juego 2048

53

2048 es un juego increíblemente divertido y adictivo en el que el objetivo es crear un mosaico con 2048 en él.

Aquí hay una breve descripción del juego:


Al presionar una tecla de flecha se deslizarán todos los bloques en el escenario en esa dirección. Por ejemplo, si xrepresenta un bloque, y presionó la flecha hacia arriba en este caso:

...x
.x..
..x.
xx..

Entonces el tablero se convertiría

xxxx
.x..
....
....

Además, los bloques están numerados, comenzando en 2. Si dos de los mismos bloques numerados se mueven juntos, se fusionarán en el siguiente número. Por ejemplo, presionando "arriba" en este tablero:

.2..
..22
.2..
....

Crearía esto:

.422
....
....
....

Y luego, después de presionar "derecha", se volvería ..44, y por lo tanto presionar nuevamente hacia la derecha crearía un bloque "8", y así sucesivamente.

Cada turno, se crea un nuevo bloque "2" en un cuadrado abierto al azar. (En realidad, no siempre es un "2", pero por simplicidad sigamos así). Si no quedan movimientos posibles (es decir, el tablero está lleno y no puedes fusionar nada), el juego se pierde, y si se crea un bloque 2048, ¡tú ganas!


¡Tu desafío es recrear este juego, golfizado!

  • Para casos extremos, como presionar "derecha" en este tablero:

    ....
    .222
    ....
    ....
    

    debe fusionar las fichas más cercanas al borde de la tecla de flecha presionada. Por ejemplo, esto se convertiría ..24, porque el segundo y tercer "2" s son los más cercanos al borde derecho.

  • Si el jugador presiona un movimiento no válido (como "arriba" en un tablero como 2.2. / .... / .... / ....), debe ignorar el movimiento.

  • Los movimientos se pueden aceptar de cualquier manera, como hacer clic, teclas de flecha ULRD, etc.

  • Todos los mosaicos deben tener la misma forma: un mosaico "1024" debe tener el mismo tamaño que un mosaico "2".

  • Los azulejos deben estar separados de alguna manera. Por ejemplo, |1024| 2|1024|1024|es un ejemplo válido de una fila (suponiendo que los mosaicos son cuadrados), mientras 1024 210241024que no lo es.

  • Debes generar "ganas" si el jugador crea una ficha de 2048, o "pierdes" si no quedan movimientos válidos.

  • Este es el , ¡así que el código más corto en bytes ganará!

Pomo de la puerta
fuente
En lugar de aceptar filas de caracteres individuales (primeros cinco ejemplos) y / o mosaicos separados (último), ¿por qué no asignar poderes ascendentes de dos a caracteres individuales para normalizar la salida?
millinon
@millinon Porque se supone que es lo más similar posible al juego real de 2048 (haría que el título no tuviera sentido), y eliminaría parte del desafío.
Pomo de la puerta
1
" Si no quedan posibles fusiones, el juego se pierde " ¿No debería haber un "y el tablero está lleno" en alguna parte?
Peter Taylor
¿El espacio es suficiente como separador de baldosas?
John Dvorak
55
Es curioso cómo todas tus búsquedas obtienen una tonelada de votos, pero no muchas respuestas.
TheDoctor

Respuestas:

7

APL (Dyalog APL) , 153 150 167 156 bytes

C←⎕UCS
'you ',{2048∊⍵:'win'
(z/∊n)[?+/z0=∊n←⍵]←2
⎕←4↑¨⍕¨n
1∊(⍉2=⌿n),(2=/n),0=n:∇{⍵≡r←R⍣¯1{4↑C(C¨2/¨t)⎕R(C¨,¨2×t2*⍳11)C⍵~0}¨(R←↓⍉∘⌽⍣⎕)⍵:∇⍵⋄r}n
'lose'}4 40

Solicitudes de movimiento; 0 = Izquierda, 1 = Arriba 2 = Derecha, 3 = Abajo

Pruébalo en línea!

Sin golf, con espacios en blanco

C  UCS
'you ', {
    2048  ⍵: 'win'
    n  
    z  0 = n
    (z / n)[? +/z]  2
      4 ↑¨ ⍕¨n
    1  (⍉ 2 =⌿ n) , (2 =/ n) , 0 = n:  {
        R←↓⍉∘⌽⍣⎕
        r  R⍣¯1 {
            t  2 * 11
            4  C (C¨ 2 t)⎕R(C¨  2 × t) C  ~ 0
         R 
          r:  
        r
    } n
    'lose'
} 4 40

Explicación

Las líneas en blanco indican una nueva línea, mientras que los bloques de líneas pertenecen a una sola línea.

C ← ⎕UCSasigne la conversión a / desde puntos UCS al nombre C (para C odepoint)

'you ',"usted" antepuso al resultado de la función {...

2048 ∊ ⍵: 'win' si el argumento (el tablero) contiene 2048, entonces devuelve "win"

n ← ⍵asignar el argumento correcto a n (para que pueda modificarse en el lugar)

z ← 0 = ∊n z obtiene la lista booleana donde z aplanado es 0

(z / ∊n) z filtra el n aplanado (para obtener solo los ceros)
[? +/z]use un número aleatorio entre 1 y el recuento de ceros (la suma de la z booleana ) para seleccionar qué posición que contiene cero
← 2obtiene un 2

⎕ ←dar salida a
4 ↑¨cada
⍕¨nrepresentación de cadena extendida-a-longitud-4 (con espacios) de cada número

1 ∊si se encuentra alguno de los siguientes;
(⍉2=⌿n)igualdades verticales por pares (transpuestas para ser concatenables)
,o (concatenadas a)
(2=/n)igualdades horizontales por pares
,o (concatenados a)
0=nceros
:entonces:
llame a esta función en el resultado de la función {...

R ← R (para R ows of R otated) es
el
⍉∘⌽⍣⎕ indicador de división en filas para la entrada numérica, luego gira (literalmente espejo horizontalmente, luego transpone) el argumento (el tablero) –90 ° veces el número ingresado

r ← r (for r esult) obtiene
R⍣¯1el inverso de R (gira hacia atrás, luego combina las filas en la matriz) aplicado al resultado de la función {...

t ← 2 * ⍳11 t obtiene 2¹, 2², 2³, ... 2¹¹

4↑pad con ceros a la derecha hasta que la longitud 4
Cconvierta los siguientes caracteres UCS en puntos de código
(C¨2/¨t)⎕R(C¨,¨2×t)regex reemplace los pares de cada t con 2 veces cada t , pero primero convierta los números a los caracteres UCS correspondientes para que la expresión regular funcione
C ⍵~0el argumento (tablero) sin ceros (compactados a la izquierda), luego convertidos a puntos de código UCS

[fin de la función] aplicado a cada una de
U↓las filas (pero combínelas después) de
R ⍵ R aplicado al argumento (el tablero)

⍵ ≡ r:si el argumento (el antiguo estado del tablero) es idéntico a r (nuevo estado del tablero), entonces:
∇⍵llame a esta función en el argumento no modificado (porque el usuario realizó un movimiento no válido), de lo contrario

rreturn r (el nuevo estado del tablero)

} n[fin de la función] aplicado a n (el nuevo estado de la placa), de lo contrario

'lose' volver "perder"

} 4 4 ⍴ 0 [fin de función] aplicado a una tabla de ceros de 4 por 4 (el estado inicial)

Adán
fuente
20

GolfScript, 323 caracteres

1,16*{16,{1$=!},.,rand=)/()2++\[]*+4/{.['-----']4*'+'*'++'1/*n+:^\{'|''     ':X'|'+4*n++:Y.@{X\`+-5>'|'\+}%'|'+n+Y+Y+^+}%+puts}:P~"wasd":Q{1$.@{Q\?[{zip}{}{-1%zip-1%}{{-1%}%}]=\1$~{0-[{.2$={+)}*}*0...]4<{1|(}%}%\~}:^~=!},:F{0{;'"#{'9.?rand';STDIN.getc()}"'++~.F\?0<}do^[]*.2048?0<.!{'you win'@@}*}{'you lose'@@*0}if}do 4/P;

Las teclas que tiene que usar son wasdpero puede cambiar la constante en el código a las teclas que desee. Ignora con gracia cualquier clave desconocida o movimiento ilegal. Lamentablemente, debe presionar enter después de cada tecla.

Ejemplo 2048ascii

Solución de 256 caracteres

1,16*{16,{1$=!},.,rand=)/())+\[]*+4/{.{{.9>7*+48+}%n+}%puts}:P~"wasd":Q{1$.@{Q\?[{zip}{}{-1%zip-1%}{{-1%}%}]=\1$~{0-[{.2$={;21+}*}*0...]4<{20%}%}%\~}:^~=!},:F{0{;'"#{'9.?rand';STDIN.getc()}"'++~.F\?0<}do^[]*.10?0<.!{'you win'@@}*}{'you lose'@@*0}if}do 4/P;

Aquí la salida es logarítmica hexadecimal, es decir, 0significa ., 1para 2,2 para 4, 3para 8... Bpara 2048. Como todos conocemos los hexadecimales y los poderes de dos, esto no debería ser una limitación en absoluto.

Ejemplo de ejecución (primeros movimientos):

0000
0000
0010
0000
w
0011
0000
0000
0000
a
2000
0000
0001
0000
s
0000
0000
0100
2001
d
0000
0000
1001
0021
w
1022
0000
0001
0000
a
1301
0000
1000
0000
s
0000
1000
0000
2301
d
0000
1001
0000
0231
Howard
fuente
Sin embargo, los azulejos deben estar separados, pero es un buen trabajo.
Teun Pronk
@TeunPronk Estoy trabajando en ello. Lamentablemente se rompe el buen poder de dos puntos.
Howard
77
+ ilimitado por ser exactamente 256 caracteres
SztupY
yay ... 2 ^ 7 caracteres !!
Mukul Kumar
1
¡Agradable! No sabía cómo hacer una entrada en golfscript antes. Personalmente, me gusta más la solución de 256 caracteres, más fácil de leer. Y yo diría que las fichas están separadas porque cada ficha tiene solo 1 carácter. nunca hay ambigüedad alguna.
Claudiu
12

J - 240 230 216 Char

Esto cuenta la nueva línea final, porque la necesitas para comenzar a ejecutar el juego en la consola. Juega escribiendo uno de udlry luego presionando Enter. Los movimientos que no hacen nada al tablero se manejan correctamente, pero el programa se enojará con usted si le da una mala entrada.

'you ',>lose`win{~$:@".@('o b=:2 t}^:(1-b-:])s ',' b',~1!:1@1:)`w@.((w=:2048 e.,)+(s d-:s u=:l d=:r(&.|:))*s r-:(s=:[:p(2(=/(0,+/^:)@{.,}.),)/@p=:\:=&0)l=:&.|.r=:"1)(o=:[2:1!:2~4<@":"0])b=:2(t=:(?&#{])[:I.0=,)}4 4$0

La versión legible y la explicación son un poco demasiado grandes para caber cómodamente en la publicación: puede encontrar una reseña en este enlace .

Uso:

   'you ',>lose`win{~$:@".@('o b=:2 t}^:(1-b-:])s ',' b',~1!:1@1:)`w@.((w=:2048 e.,)+(s d-:s u=:l d=:r(&.|:))*s r-:(s=:[:p(2(=/(0,+/^:)@{.,}.),)/@p=:\:=&0)l=:&.|.r=:"1)(o=:[2:1!:2~4<@":"0])b=:2(t=:(?&#{])[:I.0=,)}4 4$0
+----+----+----+----+
|   0|   0|   0|   0|
+----+----+----+----+
|   2|   0|   0|   0|
+----+----+----+----+
|   0|   0|   0|   0|
+----+----+----+----+
|   0|   0|   0|   0|
+----+----+----+----+
r
+----+----+----+----+
|   0|   0|   0|   0|
+----+----+----+----+
|   0|   0|   0|   2|
+----+----+----+----+
|   0|   0|   0|   0|
+----+----+----+----+
|   0|   2|   0|   0|
+----+----+----+----+
u
+----+----+----+----+
|   0|   2|   0|   2|
+----+----+----+----+
|   0|   0|   0|   0|
+----+----+----+----+
|   0|   0|   0|   0|
+----+----+----+----+
|   0|   0|   0|   2|
+----+----+----+----+
d
+----+----+----+----+
|   0|   0|   0|   0|
+----+----+----+----+
|   2|   0|   0|   0|
+----+----+----+----+
|   0|   0|   0|   0|
+----+----+----+----+
|   0|   2|   0|   4|
+----+----+----+----+
l
+----+----+----+----+
|   0|   0|   0|   0|
+----+----+----+----+
|   2|   0|   0|   0|
+----+----+----+----+
|   0|   0|   2|   0|
+----+----+----+----+
|   2|   4|   0|   0|
+----+----+----+----+
d
+----+----+----+----+
|   0|   0|   0|   0|
+----+----+----+----+
|   0|   0|   0|   0|
+----+----+----+----+
|   0|   2|   0|   0|
+----+----+----+----+
|   4|   4|   2|   0|
+----+----+----+----+
r
+----+----+----+----+
|   0|   0|   0|   0|
+----+----+----+----+
|   0|   0|   0|   2|
+----+----+----+----+
|   0|   0|   0|   2|
+----+----+----+----+
|   0|   0|   8|   2|
+----+----+----+----+
d
+----+----+----+----+
|   0|   0|   0|   0|
+----+----+----+----+
|   0|   0|   0|   0|
+----+----+----+----+
|   0|   2|   0|   2|
+----+----+----+----+
|   0|   0|   8|   4|
+----+----+----+----+
Algoritmo de tiburón
fuente
Excelente. Desafortunadamente, el tamaño de los cuadrados difiere cuando los contenidos cambian y ese fue un requisito establecido en la pregunta.
Howard
@Howard soy de la persuasión de que hacer que las baldosas sean rígidamente cuadradas es mucho más feo que dejarlas, pero ahí está, está arreglado.
algorithmshark
9

Mathematica, 484 caracteres

Muy feo.

m@l=#//.{{x___,0,a_/;a>0,y___}:>{x,a,0,y},{x___,a_/;a>0,a_,y___}:>{x,2 h@a,0,y}}/.h@a_:>a&;{m@u,m@d,m@r}=Composition[#,m@#2,#]&@@@{{Thread,l},{Reverse,u},{Thread,d}};a=ReplacePart[#,RandomChoice@Position[#,0]->2]&;g=a@ConstantArray[0,{4,4}];EventHandler[Dynamic[GraphicsGrid@Map[Graphics@Text@#&,g,{2}]],(#2<>"ArrowKeyDown":>If[g!=m[#]@g,g=a[m[#]@g];Which[And@@(g==m[#]@g&/@{u,l,r,d}),Print@"you lose",!FreeQ[g,2048],Print@"you win"]])&@@@{{l,"Left"},{r,"Right"},{u,"Up"},{d,"Down"}}]

Controlado por las teclas de flecha.

ingrese la descripción de la imagen aquí


Sin golf:

move[Left] = # //. {{x___, 1, a_ /; a > 1, y___} :> {x, a, 1, y},
      {x___, a_ /; a > 1, a_, y___} :> {x, 2 Hold@a, 1, y}} /. 
    Hold@a_ :> a &;
move[Up] = Composition[Transpose, move[Left], Transpose];
move[Down] = Composition[Reverse, move[Up], Reverse];
move[Right] = Composition[Transpose, move[Down], Transpose];
addTile = ReplacePart[#, RandomChoice@Position[#, 1] -> 2] &;
keyDown = If[grid != move[#][grid], grid = addTile[move[#][grid]];
    Which[And @@ (grid == move[#][grid] & /@ {Left, Right, Up, Down}),
      status = "Can't move...",
     ! FreeQ[grid, 2048], status = "2048!"]] &;
grid = addTile@ConstantArray[1, {4, 4}];
status = "";
EventHandler[Dynamic[ArrayPlot[Log2@grid/11,
   ColorFunction -> "StarryNightColors",
   ColorFunctionScaling -> False,
   Mesh -> All,
   Epilog -> {MapIndexed[
      Text[Style[#1, "Section"] //. 1 -> "", #2 - {0.5, 0.5}] &, 
      Transpose@Reverse@grid, {2}],
     Text[Style[status, "Section"], {2, 2}]}]],
 {"LeftArrowKeyDown" :> keyDown[Left],
  "RightArrowKeyDown" :> keyDown[Right],
  "UpArrowKeyDown" :> keyDown[Up],
  "DownArrowKeyDown" :> keyDown[Down]}]

ingrese la descripción de la imagen aquí

alephalpha
fuente
2
¡Me gusta la apariencia del no golfista!
tomsmeding
7

Delphi XE3 (Waaay para muchos {susurros} 2.979 bytes -> 4.560 bytes sin golf)

Me gusta llamar a esto "2048 code the novel".
Usé más bytes de los que me gustan pero funciona y fue divertido hacerlo.

Todavía voy a intentar hacerlo más corto más adelante.

Juego en progreso

El juego

Golfed

uses System.SysUtils,Windows;type TDir=(dUp,dDown,dLeft,dRight,dInv);const t='_____________________________';er='|      |      |      |      |';nr='| %s | %s | %s | %s |';br='|______|______|______|______|';fn='%d';procedure mycls;var S:String;H:DWORD;CO:_COORD;begin H:=GetStdHandle(STD_OUTPUT_HANDLE);CO.X:=0;CO.Y:=0;SetConsoleCursorPosition(H,CO);S:=StringOfChar(Chr(32),2000);Writeln(S);SetConsoleCursorPosition(H,CO);end;var a:array[1..4,1..4]of integer;c,rx,ry,i,j:int8;m:string;GameOver,gs:boolean;function hz:boolean;var b,q:int8;begin for b:=1to 4do for q:=1to 4do if a[b,q]=0 then exit(true);end;function HM:boolean;var b,q:int8;begin if hz then exit(true);for b:=1to 4do for q:=1to 4do begin c:=a[b,q];if c in [a[b-1,q],a[b+1,q],a[b,q-1],a[b,q+1]] then result:=true;end;end;procedure rn(out n,m:int8);var z:int8;begin z:=0;repeat n:=Random(4)+1;m:=Random(4)+1;z:=z+1;until(a[n,m]=0)and(z>=3);end;function gn(n:integer):string;begin if n=0 then exit('    ');Result:=IntToStr(n).PadLeft(4,' ');end;procedure pm(d:TDir;score:boolean);var b,q,z:int8;begin case d of dUp:for z:=1to 3do for b:=1to 4do for q:=1to 3do begin if score then begin if a[q,b]=a[q+1,b] then begin a[q,b]:=a[q,b]+a[q+1,b];a[q+1,b]:=0;end;end else if a[q,b]=0 then begin a[q,b]:=a[q+1,b];a[q+1,b]:=0;end;end;dDown:for z:=1to 3do for b:=1to 4do for q:=2to 4do begin if score then begin if a[q,b]=a[q-1,b] then begin a[q,b]:=a[q,b]+a[q-1,b];a[q-1,b]:=0;end;end else if a[q,b]=0 then begin a[q-1,b]:=a[q,b];a[q-1,b]:=0;end;end;dLeft:for z:=1to 3do for q:=1to 4do for b:=1to 3do begin if score then begin if a[q,b]=a[q,b+1] then a[q,b]:=a[q,b]+a[q,b+1];a[q,b+1]:=0;end else if a[q,b]=0 then begin a[q,b]:=a[q,b+1];a[q,b+1]:=0;end;end;dRight:for z:=1to 3do for q:=1to 4do for b:=2to 4do begin if score then begin if a[q,b]=a[q,b-1] then begin a[q,b]:=a[q,b]+a[q,b-1];a[q,b-1]:=0;end;end else if a[q,b]=0 then begin a[q,b]:=a[q,b-1];a[q,b-1]:=0;end;end;end;end;function gd(s:string):TDir;begin s:=lowercase(s);if s='u'then exit(dUp);if s='d'then exit(dDown);if s='l'then exit(dLeft);if s='r'then exit(dRight);exit(dInv)end;procedure dg;var z:int8;begin writeln(t);for z:=1to 4do begin writeln(er);Writeln(Format(nr,[gn(a[z,1]),gn(a[z,2]),gn(a[z,3]),gn(a[z,4])]));Writeln(br);end;end;function hw:boolean;var b,q:int8; begin for b:=1to 4do for q:=1to 4do if a[b,q]=2048 then result:=true;end;function dm:boolean;var d:Tdir;begin d:=gd(m);if d=dInv then if not gs then exit(false)else exit(true);pm(d,false);pm(d,true);pm(d,false);exit(true);end;begin gs:=true;m:='';for j:=1to 4do for i:=1to 4do begin a[i,j]:=0;end;rx:=0;ry:=0;rn(rx,ry);a[rx,ry]:=2;repeat if (dm) then begin if hz then begin rn(rx,ry);a[rx,ry]:=2;end;gs:=false;end;mycls;GameOver:=true;if hw then WriteLn('You have won!')else if HM then begin GameOver:=false;dg;writeln('Direction: [U]=up, [D]=Down, [L]=Left, [R]=Right');readln(m);end else WriteLn('Game Over, no more possible moves :('#13#10'Try again next time')until GameOver;readln;end.

Sin golf

uses
  System.SysUtils,Windows;
type
  TDir=(dUp,dDown,dLeft,dRight,dInv);
const
  t='_____________________________';
  er='|      |      |      |      |';
  nr='| %s | %s | %s | %s |';
  br='|______|______|______|______|';
  fn='%d';
procedure mycls;
var
  S:String;
  H:DWORD;
  CO:_COORD;
begin
  H:=GetStdHandle(STD_OUTPUT_HANDLE);
  CO.X:=0;
  CO.Y:=0;
  SetConsoleCursorPosition(H,CO);
  S:=StringOfChar(Chr(32),2000);
  Writeln(S);
  SetConsoleCursorPosition(H,CO);
end;
var
  a:array[1..4,1..4]of integer;
  c,rx,ry,i,j:int8;
  m:string;
  GameOver,gs:boolean;
function hz:boolean;
var b,q:int8;
begin
  for b:=1to 4do
    for q:=1to 4do
      if a[b,q]=0 then exit(true);
end;
function HM:boolean;
var b,q:int8;
begin
  if hz then exit(true);
  for b:=1to 4do
    for q:=1to 4do
    begin
      c:=a[b,q];
      if c in [a[b-1,q],a[b+1,q],a[b,q-1],a[b,q+1]] then
        result:=true;
    end;
end;
procedure rn(out n,m:int8);
var z:int8;
begin
z:=0;
  repeat
    n:=Random(4)+1;
    m:=Random(4)+1;
    z:=z+1;
  until(a[n,m]=0)and(z>=3);
end;
function gn(n:integer):string;
begin
  if n=0 then exit('    ');
  Result:=IntToStr(n).PadLeft(4,' ');
end;
procedure pm(d:TDir;score:boolean);
var
  b,q,z:int8;
begin
  case d of
    dUp:
      for z:=1to 3do
        for b:=1to 4do
          for q:=1to 3do
          begin
            if score then
            begin
              if a[q,b]=a[q+1,b] then
              begin
                a[q,b]:=a[q,b]+a[q+1,b];a[q+1,b]:=0;
              end;
            end
            else
              if a[q,b]=0 then
              begin
                a[q,b]:=a[q+1,b];a[q+1,b]:=0;
              end;
          end;
    dDown:
      for z:=1to 3do
        for b:=1to 4do
          for q:=2to 4do
          begin
            if score then
            begin
              if a[q,b]=a[q-1,b] then
              begin
                a[q,b]:=a[q,b]+a[q-1,b];a[q-1,b]:=0;
              end;
            end
            else
              if a[q,b]=0 then
              begin
                a[q-1,b]:=a[q,b];
                a[q-1,b]:=0;
              end;
          end;
    dLeft:
      for z:=1to 3do
        for q:=1to 4do
          for b:=1to 3do
          begin
            if score then
            begin
              if a[q,b]=a[q,b+1] then
                a[q,b]:=a[q,b]+a[q,b+1];a[q,b+1]:=0;
            end
            else
              if a[q,b]=0 then
              begin
                a[q,b]:=a[q,b+1];a[q,b+1]:=0;
              end;
          end;
    dRight:
      for z:=1to 3do
        for q:=1to 4do
          for b:=2to 4do
          begin
            if score then
            begin
              if a[q,b]=a[q,b-1] then
              begin
                a[q,b]:=a[q,b]+a[q,b-1];a[q,b-1]:=0;
              end;
            end
            else
              if a[q,b]=0 then
              begin
                a[q,b]:=a[q,b-1];a[q,b-1]:=0;
              end;
          end;
  end;
end;

function gd(s:string):TDir;
begin
  s:=lowercase(s);
  if s='u'then exit(dUp);
  if s='d'then exit(dDown);
  if s='l'then exit(dLeft);
  if s='r'then exit(dRight);
  exit(dInv)
end;
procedure dg;
var z:int8;
begin
  writeln(t);
  for z:=1to 4do
  begin
    writeln(er);
    Writeln(Format(nr,[gn(a[z,1]),gn(a[z,2]),gn(a[z,3]),gn(a[z,4])]));
    Writeln(br);
  end;
end;
function hw:boolean;
var b,q:int8;
begin
  for b:=1to 4do
    for q:=1to 4do
      if a[b,q]=2048 then
        result:=true;
end;
function dm:boolean;
var
  d:Tdir;
begin
  d:=gd(m);
  if d=dInv then if not gs then exit(false)else exit(true);
  pm(d,false);
  pm(d,true);
  pm(d,false);
  exit(true);
end;
begin
    gs:=true;m:='';
    for j:=1to 4do
      for i:=1to 4do
      begin
        a[i,j]:=0;
      end;
   rx:=0;ry:=0;
   rn(rx,ry);
   a[rx,ry]:=2;
  repeat
    if (dm) then
    begin
      if hz then
      begin
        rn(rx,ry);
        a[rx,ry]:=2;
      end;
      gs:=false;
    end;
    mycls;
    GameOver:=true;
    if hw then
      WriteLn('You have won!')
    else if HM then
    begin
      GameOver:=false;
      dg;
      writeln('Direction: [U]=up, [D]=Down, [L]=Left, [R]=Right');
      readln(m);
    end
    else
      WriteLn('Game Over, no more possible moves :('#13#10'Try again next time')
  until GameOver;
  readln;
end.
Teun Pronk
fuente
2
2.979 bytes ? ¿Se supone que son kilobytes?
Hosch250
99
Algunos lugares del mundo usan comas en números de la forma en que usamos los puntos, no estaría tan sorprendido si lo contrario también fuera cierto.
undergroundmonorail
1
@undergroundmonorail Es cierto, en Europa el número mil doce coma seis a menudo se escribe como 1.012,6 en lugar del estadounidense 1,012.6 :)
tomsmeding
¡CodeGolf me enseñó que puedes intercambiar ,y .en números!
Tejas Kale
1
Lo bueno es que esta pregunta no tiene una tabla de clasificación ...
Patrick Roberts
7

C (estándar C89), 881 bytes

Usa las teclas wasd para moverte. Compila en GCC y clang por defecto, a menos que esté configurado en el estándar C99 (supongo). Utiliza termios.h, trabajó en Linux y MacOS X. No estoy seguro acerca de Windows.

#include<termios.h>
#define R return
#define H while
char t[17],*Q,*W="adws",D,x,y,X;m(x,y){R!D?x+y*4:D==1?3-x+y*4:D==2?y+x*4:y+(3-x)*4;}c(){for(y=0;y<3;++y)for(x=0;x<3;++x){D=t[x+y*4];if(t[x+1+y*4]==D||t[x+4+y*4]==D)x=y=9;}R y>4;}d(){if(strlen(t)==16)R 0;H(t[x=(rand()&15)]);R t[x]=1;}r(x){putchar(x);}b(){y=0;r(10);H(y<21)r(y++%5?45:43);r(10);}f(){for(x=0;x<17;++x)if(X=(t[x]==11))x=32;R x<18;}struct termios z;main(){srand(time(tcgetattr(0,&z)));z.c_lflag&=~ICANON;tcsetattr(0,0,&z);H(f()&&(d()||c())){x=0;H(x<16){if(!(x&3)){b();r('|');}if(y=t[x++])printf("%4u|",1<<y);else printf("    |");}b();r(10);H(!(Q=strchr(W,getchar())));D=Q-W;for(y=0;y<4;++y)for(X=0,x=1;x<4;++x)if(t[m(x,y)]){if(t[m(x,y)]==t[m(X,y)]&&t[m(X,y)]++)t[m(x,y)]=0;X=x;}do{for(y=0;y<4;++y)for(x=0;x<3;++x)if(!t[m(x,y)]&&(X=t[m(x+1,y)])){t[m(x,y)]=X;t[m(x+1,y)]=0;x=y=9;}}H(y>4);}puts(X?"you win":"you lose");}

Roto en algunas líneas:

#include<termios.h>
#define R return
#define H while
char t[17],*Q,*W="adws",D,x,y,X;m(x,y){R!D?x+y*4:D==1?3-x+y*4:D==2?y+x*4:y+(3-x)*4;}
c(){for(y=0;y<3;++y)for(x=0;x<3;++x){D=t[x+y*4];if(t[x+1+y*4]==D||t[x+4+y*4]==D)x=y=9;}R y>4;}
d(){if(strlen(t)==16)R 0;H(t[x=(rand()&15)]);R t[x]=1;}
r(x){putchar(x);}
b(){y=0;r(10);H(y<21)r(y++%5?45:43);r(10);}
f(){for(x=0;x<17;++x)if(X=(t[x]==11))x=32;R x<18;}
struct termios z;
main(){srand(time(tcgetattr(0,&z)));z.c_lflag&=~ICANON;tcsetattr(0,0,&z);
H(f()&&(d()||c())){x=0;H(x<16){if(!(x&3)){b();r('|');}if(y=t[x++])printf("%4u|",1<<y);else printf("    |");}
b();r(10);H(!(Q=strchr(W,getchar())));D=Q-W;for(y=0;y<4;++y)for(X=0,x=1;x<4;++x)
if(t[m(x,y)]){if(t[m(x,y)]==t[m(X,y)]&&t[m(X,y)]++)t[m(x,y)]=0;X=x;}
do{for(y=0;y<4;++y)for(x=0;x<3;++x)if(!t[m(x,y)]&&(X=t[m(x+1,y)]))
{t[m(x,y)]=X;t[m(x+1,y)]=0;x=y=9;}}H(y>4);}puts(X?"you win":"you lose");}

Las miradas:

+----+----+----+----+
|   8|   4|   8|   2|
+----+----+----+----+
|    |  16|    |    |
+----+----+----+----+
|    |   2|    |    |
+----+----+----+----+
|    |    |    |   2|
+----+----+----+----+

Se puede mejorar con seguridad.

asr
fuente
5

Java: 1346 1269

Editar Entonces, aunque este concurso está terminado, a veces no puedo dejarlo ir cuando se pueden hacer mejoras. Esta versión cuenta con una función de plegado más delgada, más mala en el lugar, el desalojo de la mayoríaboolean tipos, excepto donde sería más detallado sin ellos, y celdas ligeramente más pequeñas (4x4 en lugar de 5x5) para cortar algunos caracteres adicionales allí.

Así que esta fue divertida. ¡Gracias por publicar! Ungolfed, esto era 2856 bytes, golf lo reduje a 1346 bytes. Siendo Java, no voy a ganar, pero quería mostrarme bien. Descubrir una función de acumulación "general" para manejar las uniones y movimientos de mosaico fue divertido; por supuesto, puede verificar mi "progreso" mirando los commits en mi repositorio de github para esta solución .

Golfizado:

import java.util.*;class T{public static void main(String[]a){(new T()).s();}int[][]b=new int[4][4];int d,p,i,j,x,y,v,q,r;boolean I,V;void s(){p();do{d();do{char a=(new Scanner(System.in)).nextLine().charAt(0);y=a=='u'?f(0,1):a=='d'?f(1,1):a=='l'?f(0,0):a=='r'?f(1,0):0;}while(y<1);p();}while((x=n())>0);d();c("you "+(x<0?"win":"lose"));}int h(){for(int[]y:b)for(int x:y)if(x<2)return 1;return 0;}int n(){for(y=0;y<4;y++){for(x=0;x<4;x++){i=b[y][x];if(x<3&&i==b[y][x+1]||y<3&&i==b[y+1][x])return 1;if(i>2047)return -1;}}return h();}int f(int w,int z){I=w>0;V=z>0;for(i=d=0;i<4;i++){p=I?3:0;for(j=1;j<4;){v=V?i:j;x=I?3-v:v;v=V?j:i;y=I?3-v:v;q=V?x:p;r=V?p:y;if(b[y][x]==0||p==(V?y:x))j++;else if(b[r][q]==0){d+=b[r][q]=b[y][x];b[y][x]=0;j++;}else if(b[r][q]==b[y][x]){d+=b[r][q]*=2;b[y][x]=0;p+=I?-1:1;j++;}else p+=I?-1:1;}}return d;}int v(){return(new Random()).nextInt(4);}void p(){if(h()<1)return;do{x=v();y=v();}while(b[x][y]>0);b[x][y]=2;}void c(String a){System.out.println(a);}String l(char n,char m){String s=""+n;for(i=0;i<4;i++){for(j=0;j<4;j++)s+=m;s+=n;}return s;}void d(){c(l('+','-'));String p[]=new String[5];for(int[]y:b){p[0]=p[1]=p[3]=l('|',' ');p[2]="";for(x=0;x<4;)p[2]+=String.format("|%4d",y[x++]);p[2]+="|";p[4]=l('+','-');for(String q:p)c(q);}}}

Ungolfed: (Consulte mi repositorio de github para este proyecto para obtener una versión actualizada, que incluye una prueba basada en aserciones para nuevas funciones de plegado)

import java.util.*;
class Twe {
    public static void main(String[] a){
        (new Twe()).start();
    }
    int[][] board=new int[4][4];
    void start(){
        int x;
        placeTwo();
        do{
            drawBoard();
            resolve();
            placeTwo();
        }while((x=notDone())>0);
        drawBoard();
        wrapup(x);
    }
    int hasFree(){
        for(int[]y:board)
            for(int x:y)
                if(x<2)return 1;
        return 0;
    }
    int notDone(){
        int moves,x,y;
        for(moves=y=0;y<4;y++){
            for(x=0;x<4;x++){
                else if(x<3&&board[y][x]==board[y][x+1]||
                        y<3&&board[y][x]==board[y+1][x])moves++;
                if(board[y][x]>2047)return -1;
            }
        }
        return hasFree()+moves;
    }
    void wrapup(int k){
        if(k<0){
            chalk("you win",true);
        }else{
            chalk("you lose",true);
        }
    }
    void resolve(){
        do{
            switch((new Scanner(System.in)).nextLine().charAt(0)){
                case 'u':
                    if (fold(false,true)>0)return;
                    break;
                case 'd':
                    if (fold(true, true)>0)return;
                    break;
                case 'l':
                    if (fold(false,false)>0)return;
                    break;
                case 'r':
                    if (fold(true,false)>0)return;
                    break;
                case 'z':
                    board[0][0]=2048; // instant win;
                    return;
            }
        } while(true);
    }
    // false,true  = up
    // true, true  = down
    // false,false = left
    // true, false = right
    int fold(boolean inv, boolean vert){
        int didMove=0;
        int nextSpot,x,y,v,q,r;
        int[][] nb = new int[4][4];
        for(int i=0;i<4;i++){
            nextSpot=inv?3:0;
            for(int j=0;j<4;j++){
                v=vert?i:j;
                x=inv?3-v:v;
                v=vert?j:i;
                y=inv?3-v:v;
                q=vert?x:nextSpot;
                r=vert?nextSpot:y;
                if(board[y][x]>0){
                    if(nb[r][q]<1){
                        nb[r][q]=board[y][x];
                        didMove+=(inv?-1:1)*(vert?y-r:x-q);
                    }else if(nb[r][q]==board[y][x]){
                        nb[r][q]*=2;
                        nextSpot+=inv?-1:1;
                        didMove++;
                    }else{
                        nextSpot+=inv?-1:1;//suckage
                        q=vert?x:nextSpot;
                        r=vert?nextSpot:y;
                        nb[r][q]=board[y][x];
                        didMove+=(inv?-1:1)*(vert?y-r:x-q);
                    }
                }
            }
        }
        board=nb;
        return didMove;
    }
    int vec(){
        return (new Random()).nextInt(4);
    }
    void placeTwo(){
        if (hasFree()<1) return;
        int x,y;
        do{
            x=vec();y=vec();
        }while(board[x][y]>0);
        board[x][y]=2;
    }
    void chalk(String a, boolean nl){
        System.out.print(a+(nl?"\n":""));
    }
    String fill(char node, char mid){
        String str = ""+node;
        for(int i=0;i<4;i++){
            for(int j=0;j<5;j++)
                str+=mid;
            str+=node;
        }
        return str;
    }
    void drawBoard(){
        chalk(fill('+','-'),true);
        String p[] = new String[6];
        for(int[]y:board){
            p[0]=p[1]=p[3]=p[4]=fill('|',' ');
            p[2]="";
            for(int x=0;x<4;){
                p[2]+=adjust(y[x++]);
            }
            p[2]+="|";
            p[5]=fill('+','-');
            for (String q:p){
                chalk(q,true);
            }
        }
    }
    String adjust(int a){
        return String.format("|%5d",a);
    }
}

Usar el programa es simple. Para construir y ejecutar:

javac T.java
java T

Presione upara plegar hacia arriba, rplegar hacia la derecha, dplegar hacia abajo, lplegar hacia la izquierda. Se ignora cualquier otra tecla, se ignoran los movimientos no válidos (sin resultado). Siendo Java, presione enterdespués de cada tecla para vaciar el búfer de línea. Como lo requieren las reglas, si gana las salidas del programa you win, si pierde las salidas del programa you lose. Los nuevos 2se colocan aleatoriamente en las fichas abiertas. Las fusiones siguen las reglas establecidas. Las celdas son caracteres 4x4, con un borde que rodea cada celda. Por supuesto, déjame un comentario si he estropeado algo y me aseguraré de arreglarlo.

Salida de ejemplo:

$ java T
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   0|   0|   0|   0|
|    |    |    |    |
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   0|   0|   0|   0|
|    |    |    |    |
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   0|   0|   0|   0|
|    |    |    |    |
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   2|   0|   0|   0|
|    |    |    |    |
+----+----+----+----+
u
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   2|   0|   0|   0|
|    |    |    |    |
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   0|   0|   0|   0|
|    |    |    |    |
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   0|   0|   0|   2|
|    |    |    |    |
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   0|   0|   0|   0|
|    |    |    |    |
+----+----+----+----+
l
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   2|   0|   0|   0|
|    |    |    |    |
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   0|   0|   0|   0|
|    |    |    |    |
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   2|   0|   0|   0|
|    |    |    |    |
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   2|   0|   0|   0|
|    |    |    |    |
+----+----+----+----+
u
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   4|   0|   0|   0|
|    |    |    |    |
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   2|   2|   0|   0|
|    |    |    |    |
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   0|   0|   0|   0|
|    |    |    |    |
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   0|   0|   0|   0|
|    |    |    |    |
+----+----+----+----+
l
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   4|   0|   0|   0|
|    |    |    |    |
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   4|   0|   0|   0|
|    |    |    |    |
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   0|   0|   0|   0|
|    |    |    |    |
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   0|   0|   0|   2|
|    |    |    |    |
+----+----+----+----+
u
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   8|   2|   0|   2|
|    |    |    |    |
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   0|   0|   0|   0|
|    |    |    |    |
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   0|   0|   0|   0|
|    |    |    |    |
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   0|   0|   0|   0|
|    |    |    |    |
+----+----+----+----+
l
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   8|   4|   2|   0|
|    |    |    |    |
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   0|   0|   0|   0|
|    |    |    |    |
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   0|   0|   0|   0|
|    |    |    |    |
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   0|   0|   0|   0|
|    |    |    |    |
+----+----+----+----+
l
u
d
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   0|   0|   0|   0|
|    |    |    |    |
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   0|   0|   0|   0|
|    |    |    |    |
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   0|   0|   2|   0|
|    |    |    |    |
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   8|   4|   2|   0|
|    |    |    |    |
+----+----+----+----+
d
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   0|   0|   0|   0|
|    |    |    |    |
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   0|   0|   0|   2|
|    |    |    |    |
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   0|   0|   0|   0|
|    |    |    |    |
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   8|   4|   4|   0|
|    |    |    |    |
+----+----+----+----+
l
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   0|   0|   0|   0|
|    |    |    |    |
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   2|   0|   0|   0|
|    |    |    |    |
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   0|   0|   2|   0|
|    |    |    |    |
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   8|   8|   0|   0|
|    |    |    |    |
+----+----+----+----+
l
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   0|   0|   0|   0|
|    |    |    |    |
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   2|   2|   0|   0|
|    |    |    |    |
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   2|   0|   0|   0|
|    |    |    |    |
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|  16|   0|   0|   0|
|    |    |    |    |
+----+----+----+----+
d
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   0|   2|   0|   0|
|    |    |    |    |
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   0|   0|   0|   0|
|    |    |    |    |
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   4|   0|   0|   0|
|    |    |    |    |
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|  16|   2|   0|   0|
|    |    |    |    |
+----+----+----+----+
d
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   0|   0|   0|   0|
|    |    |    |    |
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   0|   0|   0|   0|
|    |    |    |    |
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|   4|   2|   0|   0|
|    |    |    |    |
+----+----+----+----+
|    |    |    |    |
|    |    |    |    |
|  16|   4|   0|   0|
|    |    |    |    |
+----+----+----+----+
Programador Dan
fuente
2

Lua, 622 616 615 612 592 590 575 bytes

Consulta stdin para 1,2,3,4 correlacionando con izquierda, abajo, derecha, arriba (hecho para la entrada del teclado numérico); se bloquea si le das una entrada incorrecta.

Los cuadrados en blanco se imprimen como '0'.

b={('\0'):rep(16):byte(1,16)}c=1 a=print h=unpack while{}do if c then c=z
e={}for i=1,16 do e[#e+1]=0==b[i]and i or z end _=#e==0 and
a'you lose'b[e[math.random(#e)]]=2 l=('+----'):rep(4)..'+\n'm=l:gsub('-',' ')for
i=1,13,4 do a(l..m..m..m..('+%4d+%4d+%4d+%4d+'):format(h(b,i)))end a(l)end c=z
u,v,w=h({4,1,-4,1,-4,16,4,-1,1,1,4,-4},3*io.read()-2)for i=1,4 do o=-1 for j=2,4
do if 0~=b[u*i+v*j+w]then for k=1-j,o do p=u*i-v*k+w q=p+v r=b[p]if r==0 then
b[p]=b[q]b[q]=r c=1 o=k elseif r==b[q]then _=r==1024 and a'you win'b[p]=r*2
b[q]=0 c=1 o=k-1 break end end end end end end 

Salida de ejemplo:

+----+----+----+----+
+    +    +    +    +
+    +    +    +    +
+    +    +    +    +
+   2+   0+   0+   0+
+----+----+----+----+
+    +    +    +    +
+    +    +    +    +
+    +    +    +    +
+   0+   0+   0+   0+
+----+----+----+----+
+    +    +    +    +
+    +    +    +    +
+    +    +    +    +
+   0+   0+   0+   0+
+----+----+----+----+
+    +    +    +    +
+    +    +    +    +
+    +    +    +    +
+   0+   0+   0+   0+
+----+----+----+----+

2
+----+----+----+----+
+    +    +    +    +
+    +    +    +    +
+    +    +    +    +
+   0+   2+   0+   0+
+----+----+----+----+
+    +    +    +    +
+    +    +    +    +
+    +    +    +    +
+   0+   0+   0+   0+
+----+----+----+----+
+    +    +    +    +
+    +    +    +    +
+    +    +    +    +
+   0+   0+   0+   0+
+----+----+----+----+
+    +    +    +    +
+    +    +    +    +
+    +    +    +    +
+   2+   0+   0+   0+
+----+----+----+----+
thenumbernine
fuente
0

Clojure: 599

ejecutarlo en un REPL

golf

(defn i[b](let[f(into[](flatten b))z(seq(keep-indexed #(when(zero? %2)%1)f))]
(cond(some #{2048}f)(pr "you win")(empty? z)(pr "game over"):e(partition 4
(assoc f(rand-nth z)2)))))(def r #(remove zero? %))(loop[b(i (partition 4
(repeat 16 0)))](when((fn[v](doseq[l(for[a v](apply str(map #(format "%5d " %)a)))]
(println l "\n"))v)b)(-> b((apply comp(assoc(into[](repeat 5(fn[v]
(map(fn[n](map #(nth % n)v))[3 2 1 0]))))({"h"4 "k"3 "l"2 "j"1}(read-line))
(partial map(comp #(take 4(concat % [0 0 0 0]))(fn[v]
(r(reduce #(let[l(last %1)](if(= %2 l)(conj(pop %1)(+ l %2) 0)
(conj %1 %2)))[]v)))r)))))i recur)))

sin golf

(defn insert-2 [board]
  (let [flat (into [] (flatten board))
        zero-indices (seq (keep-indexed
                       #(when (zero? %2) %1)
                       flat))]
    (cond
      (some #{2048} flat) (pr "you win")
      (empty? zero-indices) (pr "game over")
      :else (partition 4 (assoc flat (rand-nth zero-indices) 2)))))

(defn rotate [board]
  (map
    (fn [n]
        (map #(nth % n)
             board))
    [3 2 1 0]))

(defn remove-zeros [row]
 (remove zero? row))

(defn fill [row]
 (take 4 (concat row [0 0 0 0])))

(defn sum-up [acc x]
  (let [l (last acc)]
    (if (= x l)
      (conj (pop acc) (+ l x) 0)
      (conj acc x))))

(defn sum-pairs [v]
  (remove-zeros (reduce sum-up [] v)))

(defn render [v]
  (doseq [line (for [row v]
                 (apply str (map #(format "%5d " %) row)))]
    (println line "\n")) v)

(defn slide [board]
 (map (comp
        fill
        sum-pairs
        remove-zeros
        ) board))

(loop [board (insert-2 (partition 4 (repeat 16 0)))]
  (when (render board)
    (let [input ({"h" 4 "k" 3 "l" 2 "j" 1} (read-line))
          command (apply comp
                         (assoc (into [] (repeat 5 rotate))
                                input slide))] ;; (comp rotate rotate slide rotate rotate)
      (-> board command insert-2 recur))))
Kolja
fuente