64

I guess some of you might know the game 2048. A situation has the following shape:

Example

I would like to create a TikZ template that allows me to make similar drawings.

MWE

To create the following example (which is the best I got), I've used answers from Can TikZ create pixel art images?

\documentclass[tikz]{standalone}
\usepackage{ifthen}
\renewcommand\familydefault{\sfdefault}
\usepackage{tikz}
\usetikzlibrary{calc}
\def\pixels{
{0,2,0,0},
{0,8,0,4},
{2,2,4,16},
{8,16,128,2},
}

% Font color for 2 and 4: #776e65
% Font color for rest: #f9f6f2
% Grid color: #bbada0
% Font family: "Clear Sans", "Helvetica Neue", Arial, sans-serif

\definecolor{pixel 0}{HTML}{CCC0B3}
\definecolor{pixel 2}{HTML}{EEE4DA}
\definecolor{pixel 4}{HTML}{EEE4DA}
\definecolor{pixel 8}{HTML}{F2B179}
\definecolor{pixel 16}{HTML}{F59563}
\definecolor{pixel 32}{HTML}{F2B179} % TODO
\definecolor{pixel 64}{HTML}{F2B179}
\definecolor{pixel 128}{HTML}{EDCF72}
\definecolor{pixel 256}{HTML}{F2B179} % TODO
\definecolor{pixel 512}{HTML}{F2B179} % TODO
\definecolor{pixel 1024}{HTML}{F2B179} % TODO
\definecolor{pixel 2048}{HTML}{F2B179} % TODO
\definecolor{pixel 4096}{HTML}{3E3933}
\begin{document}
\begin{tikzpicture}
  \foreach \line [count=\y] in \pixels {
    \foreach \pix [count=\x] in \line {
      \draw[fill=pixel \pix] (\x,-\y) rectangle +(1,1);
      \ifthenelse{\equal{0}{\pix}}
           {}
           {\node at ($(\x,-\y) + (0.5,0.5)$)    {\Huge \pix};}
    }
  }

\end{tikzpicture}
\end{document}

Rendered:

enter image description here

Issues

  • How do I change the font color?
  • I always have problems with changing fonts: In this case, the font should be bold.
  • The numbers should fit into the cells with some padding.
  • The grid should not be black but #bbada0.
4
  • 1
    Off-topic: perhaps the online course udacity.com/course/ud248 might interests you May 2, 2014 at 10:36
  • Clear Sans is available online (I didn’t check what the Apache License, Version 2.0. indicates about usage): 01.org/clear-sans
    – doncherry
    May 3, 2014 at 11:02
  • 2
    Could anybody please explain my why this question gets so many upvotes? May 5, 2014 at 9:06
  • 1
    @doncherry TeXLive provides the Clear Sans family (via the clearsans package). May 5, 2014 at 11:15

5 Answers 5

81

Third version (via pdflatex using ClearSans package)

(Note: ClearSans package, version 2014-05-28)

enter image description here

\documentclass[tikz]{standalone}
\usepackage{ClearSans}
\usepackage[T1]{fontenc}
\usepackage{tikz}
%
\usetikzlibrary{fit,backgrounds}
%
\def\gamefont{\bfseries\sffamily}
%
\definecolor{grid color}{HTML}{BBADA0}
\definecolor{pixel 0}{HTML}{CCC0B3}
\definecolor{pixel 2}{HTML}{EEE4DA}
\definecolor{pixel 4}{HTML}{EDE0C8}
\definecolor{pixel 8}{HTML}{F2B179}
\definecolor{pixel 16}{HTML}{F59563}
\definecolor{pixel 32}{HTML}{F67C5F}
\definecolor{pixel 64}{HTML}{F65E3B}
\definecolor{pixel 128}{HTML}{EDCF72}
\definecolor{pixel 256}{HTML}{EDCC61}
\definecolor{pixel 512}{HTML}{EDC850}
\definecolor{pixel 1024}{HTML}{EDC53F}
\definecolor{pixel 2048}{HTML}{EDC22E}
\definecolor{pixel 4096}{HTML}{3E3933}
%
\definecolor{small color}{HTML}{776E65}
\definecolor{big color}{HTML}{F9F6F2}
%
\tikzset{
  case 2048 base/.style={
    minimum size=9mm,rounded corners=.3mm,text=#1,inner sep=0,line width=0,
  },
  %
  case 2048 Large/.style={font=\Large\gamefont,case 2048 base=#1},
  case 2048 large/.style={font=\large\gamefont,case 2048 base=#1},
  case 2048 normal/.style={font=\normalsize\gamefont,case 2048 base=#1},
  %
  case 2048 0/.style={case 2048 Large=black,fill=pixel 0,node contents={}},
  case 2048 2/.style={case 2048 Large=small color,fill=pixel 2,node contents={2}},
  case 2048 4/.style={case 2048 Large=small color,fill=pixel 4,node contents={4}},
  case 2048 8/.style={case 2048 Large=big color,fill=pixel 8,node contents={8}},
  case 2048 16/.style={case 2048 Large=big color,fill=pixel 16,node contents={16}},
  case 2048 32/.style={case 2048 Large=big color,fill=pixel 32,node contents={32}},
  case 2048 64/.style={case 2048 Large=big color,fill=pixel 64,node contents={64}},
  case 2048 128/.style={case 2048 large=big color,fill=pixel 128,node contents={128}},
  case 2048 256/.style={case 2048 large=big color,fill=pixel 256,node contents={256}},
  case 2048 512/.style={case 2048 large=big color,fill=pixel 512,node contents={512}},
  case 2048 1024/.style={case 2048 normal=big color,fill=pixel 1024,node contents={1024}},
  case 2048 2048/.style={case 2048 normal=big color,fill=pixel 2048,node contents={2048}},
  case 2048 4096/.style={case 2048 normal=big color,fill=pixel 4096,node contents={4096}},
}
\begin{document}
\begin{tikzpicture}
  \def\pixels{
    {2,4,0,2048},
    {8,0,2,4096},
    {8,16,32,64},
    {1024,512,256,128},
  }

  \foreach \line [count=\y] in \pixels {
    \foreach \pix [count=\x] in \line {
      \path (\x,-\y) node[name=c2048-\x-\y,case 2048 \pix];
    }
  }

  \begin{scope}[on background layer]
    \node[fill=grid color,fit=(c2048-1-1)(c2048-4-4),
    inner sep=1mm,rounded corners=.3mm]{};
  \end{scope}
\end{tikzpicture}
\end{document}

2nd version (using the Intel ClearSans font with help of lualatex)

enter image description here

\documentclass[tikz]{standalone}
\usepackage{fontspec}
\usepackage{tikz}
%
\usetikzlibrary{fit,backgrounds}
%
\newfontfamily\clearsansfont{ClearSans}
\def\gamefont{\bfseries\clearsansfont}
%
\definecolor{grid color}{HTML}{BBADA0}
\definecolor{pixel 0}{HTML}{CCC0B3}
\definecolor{pixel 2}{HTML}{EEE4DA}
\definecolor{pixel 4}{HTML}{EDE0C8}
\definecolor{pixel 8}{HTML}{F2B179}
\definecolor{pixel 16}{HTML}{F59563}
\definecolor{pixel 32}{HTML}{F67C5F}
\definecolor{pixel 64}{HTML}{F65E3B}
\definecolor{pixel 128}{HTML}{EDCF72}
\definecolor{pixel 256}{HTML}{EDCC61}
\definecolor{pixel 512}{HTML}{EDC850}
\definecolor{pixel 1024}{HTML}{EDC53F}
\definecolor{pixel 2048}{HTML}{EDC22E}
\definecolor{pixel 4096}{HTML}{3E3933}
%
\definecolor{small color}{HTML}{776E65}
\definecolor{big color}{HTML}{F9F6F2}
%
\tikzset{
  case 2048 base/.style={
    minimum size=9mm,rounded corners=.3mm,text=#1,inner sep=0,line width=0,
  },
  %
  case 2048 Large/.style={font=\Large\gamefont,case 2048 base=#1},
  case 2048 large/.style={font=\large\gamefont,case 2048 base=#1},
  case 2048 normal/.style={font=\normalsize\gamefont,case 2048 base=#1},
  %
  case 2048 0/.style={case 2048 Large=black,fill=pixel 0,node contents={}},
  case 2048 2/.style={case 2048 Large=small color,fill=pixel 2,node contents={2}},
  case 2048 4/.style={case 2048 Large=small color,fill=pixel 4,node contents={4}},
  case 2048 8/.style={case 2048 Large=big color,fill=pixel 8,node contents={8}},
  case 2048 16/.style={case 2048 Large=big color,fill=pixel 16,node contents={16}},
  case 2048 32/.style={case 2048 Large=big color,fill=pixel 32,node contents={32}},
  case 2048 64/.style={case 2048 Large=big color,fill=pixel 64,node contents={64}},
  case 2048 128/.style={case 2048 large=big color,fill=pixel 128,node contents={128}},
  case 2048 256/.style={case 2048 large=big color,fill=pixel 256,node contents={256}},
  case 2048 512/.style={case 2048 large=big color,fill=pixel 512,node contents={512}},
  case 2048 1024/.style={case 2048 normal=big color,fill=pixel 1024,node contents={1024}},
  case 2048 2048/.style={case 2048 normal=big color,fill=pixel 2048,node contents={2048}},
  case 2048 4096/.style={case 2048 normal=big color,fill=pixel 4096,node contents={4096}},
}
\begin{document}
\begin{tikzpicture}
  \def\pixels{
    {2,4,0,2048},
    {8,0,2,4096},
    {8,16,32,64},
    {1024,512,256,128},
  }

  \foreach \line [count=\y] in \pixels {
    \foreach \pix [count=\x] in \line {
      \path (\x,-\y) node[name=c2048-\x-\y,case 2048 \pix];
    }
  }

  \begin{scope}[on background layer]
    \node[fill=grid color,fit=(c2048-1-1)(c2048-4-4),
    inner sep=1mm,rounded corners=.3mm]{};
  \end{scope}
\end{tikzpicture}
\end{document}

First version (default font and pdflatex)

Here is a (completed) solution without ifthen package:

enter image description here

\documentclass[tikz]{standalone}
\renewcommand\familydefault{\sfdefault}
\usepackage{tikz}
\usetikzlibrary{fit,backgrounds}
%
\definecolor{grid color}{HTML}{BBADA0}
\definecolor{pixel 0}{HTML}{CCC0B3}
\definecolor{pixel 2}{HTML}{EEE4DA}
\definecolor{pixel 4}{HTML}{EDE0C8}
\definecolor{pixel 8}{HTML}{F2B179}
\definecolor{pixel 16}{HTML}{F59563}
\definecolor{pixel 32}{HTML}{F67C5F}
\definecolor{pixel 64}{HTML}{F65E3B}
\definecolor{pixel 128}{HTML}{EDCF72}
\definecolor{pixel 256}{HTML}{EDCC61}
\definecolor{pixel 512}{HTML}{EDC850}
\definecolor{pixel 1024}{HTML}{EDC53F}
\definecolor{pixel 2048}{HTML}{EDC22E}
\definecolor{pixel 4096}{HTML}{3E3933}
%
\definecolor{small color}{HTML}{776E65}
\definecolor{big color}{HTML}{F9F6F2}
%
\tikzset{
  case 2048 base/.style={minimum size=9mm,rounded corners=.3mm,text=#1,inner sep=0},
  %
  case 2048 LARGE/.style={font=\LARGE\bfseries\sffamily,case 2048 base=#1},
  case 2048 Large/.style={font=\Large\bfseries\sffamily,case 2048 base=#1},
  case 2048 large/.style={font=\large\bfseries\sffamily,case 2048 base=#1},
  case 2048 normal/.style={font=\normalsize\bfseries\sffamily,case 2048 base=#1},
  %
  case 2048 0/.style={case 2048 Large=black,fill=pixel 0,node contents={}},
  case 2048 2/.style={case 2048 Large=small color,fill=pixel 2,node contents={2}},
  case 2048 4/.style={case 2048 Large=small color,fill=pixel 4,node contents={4}},
  case 2048 8/.style={case 2048 Large=big color,fill=pixel 8,node contents={8}},
  case 2048 16/.style={case 2048 Large=big color,fill=pixel 16,node contents={16}},
  case 2048 32/.style={case 2048 Large=big color,fill=pixel 32,node contents={32}},
  case 2048 64/.style={case 2048 Large=big color,fill=pixel 64,node contents={64}},
  case 2048 128/.style={case 2048 large=big color,fill=pixel 128,node contents={128}},
  case 2048 256/.style={case 2048 large=big color,fill=pixel 256,node contents={256}},
  case 2048 512/.style={case 2048 large=big color,fill=pixel 512,node contents={512}},
  case 2048 1024/.style={case 2048 normal=big color,fill=pixel 1024,node contents={1024}},
  case 2048 2048/.style={case 2048 normal=big color,fill=pixel 2048,node contents={2048}},
  case 2048 4096/.style={case 2048 normal=big color,fill=pixel 4096,node contents={4096}},
}
\begin{document}
\begin{tikzpicture}
  \def\pixels{
    {0,2,32,64},
    {256,8,512,4},
    {1024,2048,4,16},
    {4096,16,128,2},
  }

  \foreach \line [count=\y] in \pixels {
    \foreach \pix [count=\x] in \line {
      \path (\x,-\y) node[name=c2048-\x-\y,case 2048 \pix];
    }
  }

  \begin{scope}[on background layer]
    \node[fill=grid color,fit=(c2048-1-1)(c2048-4-4),
    inner sep=1mm,rounded corners=.3mm]{};
  \end{scope}
\end{tikzpicture}
\end{document}
2
  • 25
    new project: implement 2048 in latex May 2, 2014 at 22:56
  • 6
    @enthdegree I expect the 2048th vote to begin. May 3, 2014 at 17:03
34

This is a possible solution with the aim to be less invasive as possible with respect to the original code.

Modifications concern the way in which each cell is realized: previous \drawing mechanism has become a \node. Indeed, using a spreading factor \grshift to space cells, it becomes necessary to know precisely where the background is placed, hence nodes with names makes life easier.

\documentclass[tikz,border=10pt]{standalone}
\usepackage{ifthen}
\renewcommand\familydefault{\sfdefault}
\usepackage{tikz}
\usetikzlibrary{backgrounds,calc}
\def\pixels{
{0,2,0,0},
{0,8,0,4},
{2,2,4,16},
{8,16,4096,2},% changed one value for testing purposes
}

% Font color for 2 and 4: #776e65
% Font color for rest: #f9f6f2
% Grid color: #bbada0
% Font family: "Clear Sans", "Helvetica Neue", Arial, sans-serif

\definecolor{gridc}{HTML}{BBADA0}

\definecolor{pixel 0}{HTML}{CCC0B3}
\definecolor{pixel 2}{HTML}{EEE4DA}
\definecolor{pixel 4}{HTML}{EEE4DA}
\definecolor{pixel 8}{HTML}{F2B179}
\definecolor{pixel 16}{HTML}{F59563}
\definecolor{pixel 32}{HTML}{F2B179} % TODO
\definecolor{pixel 64}{HTML}{F2B179}
\definecolor{pixel 128}{HTML}{EDCF72}
\definecolor{pixel 256}{HTML}{F2B179} % TODO
\definecolor{pixel 512}{HTML}{F2B179} % TODO
\definecolor{pixel 1024}{HTML}{F2B179} % TODO
\definecolor{pixel 2048}{HTML}{F2B179} % TODO
\definecolor{pixel 4096}{HTML}{3E3933}

\definecolor{font 0}{HTML}{F9F6F2}
\definecolor{font 2}{HTML}{776E65}
\definecolor{font 4}{HTML}{776E65}
\definecolor{font 8}{HTML}{F9F6F2}
\definecolor{font 16}{HTML}{F9F6F2}
\definecolor{font 32}{HTML}{F9F6F2}
\definecolor{font 64}{HTML}{F9F6F2}
\definecolor{font 128}{HTML}{F9F6F2}
\definecolor{font 256}{HTML}{F9F6F2}
\definecolor{font 512}{HTML}{F9F6F2}
\definecolor{font 1024}{HTML}{F9F6F2}
\definecolor{font 2048}{HTML}{F9F6F2}
\definecolor{font 4096}{HTML}{F9F6F2}

\tikzset{shift value/.store in=\grshift,
  shift value=1.2,
}

\begin{document}
\begin{tikzpicture}
  \foreach \line [count=\y] in \pixels {
    \foreach \pix [count=\x] in \line {
      \node [draw=none,fill=pixel \pix,
            rounded corners,minimum size=1cm]
            (\x\y) at (\grshift*\x,-\grshift*\y) {};
      % putting text
      \ifthenelse{\equal{0}{\pix}}
           {}
           {\node[font=\bfseries,text=font \pix] at (\x\y)  {\pix};}
    }
  }

\begin{scope}[on background layer]
\fill[gridc,rounded corners]
  ($(11)+(-.65*\grshift,.65*\grshift)$)
 rectangle
  ($(44)+(.65*\grshift,-.65*\grshift)$);
\end{scope}
\end{tikzpicture}
\end{document}

The result:

enter image description here

Previous solution however was not aligned at (0,0) exactly due to \grshift. Taking this into account, an improved version:

\documentclass[tikz,border=10pt]{standalone}
\renewcommand\familydefault{\sfdefault}
\usepackage{tikz}
\usetikzlibrary{backgrounds,calc}

\definecolor{gridc}{HTML}{BBADA0}

\definecolor{pixel 0}{HTML}{CCC0B3}
\definecolor{pixel 2}{HTML}{EEE4DA}
\definecolor{pixel 4}{HTML}{EDE0C8}
\definecolor{pixel 8}{HTML}{F2B179}
\definecolor{pixel 16}{HTML}{F59563}
\definecolor{pixel 32}{HTML}{F67C5F}
\definecolor{pixel 64}{HTML}{F65E3B}
\definecolor{pixel 128}{HTML}{EDCF72}
\definecolor{pixel 256}{HTML}{EDCC61}
\definecolor{pixel 512}{HTML}{EDC850}
\definecolor{pixel 1024}{HTML}{EDC53F}
\definecolor{pixel 2048}{HTML}{EDC22E}
\definecolor{pixel 4096}{HTML}{3E3933}

\definecolor{font 0}{HTML}{F9F6F2}
\definecolor{font 2}{HTML}{776E65}
\definecolor{font 4}{HTML}{776E65}
\definecolor{font 8}{HTML}{F9F6F2}
\definecolor{font 16}{HTML}{F9F6F2}
\definecolor{font 32}{HTML}{F9F6F2}
\definecolor{font 64}{HTML}{F9F6F2}
\definecolor{font 128}{HTML}{F9F6F2}
\definecolor{font 256}{HTML}{F9F6F2}
\definecolor{font 512}{HTML}{F9F6F2}
\definecolor{font 1024}{HTML}{F9F6F2}
\definecolor{font 2048}{HTML}{F9F6F2}
\definecolor{font 4096}{HTML}{F9F6F2}

\tikzset{shift value/.store in=\grshift,
  shift value=1.2cm,
  module/.style={minimum size=1cm},
  every module/.code={\tikzset{module/.append style={#1}}},
  game/.code={%
    \foreach \line [count=\y] in \pixels {
    \foreach \pix [count=\x] in \line {
      \node [draw=none,fill=pixel \pix,
            rounded corners,
            module]
            (gm-\x-\y) 
            at ([xshift=-.45*\grshift,yshift=.45*\grshift]\grshift*\x,-\grshift*\y) {};%
      % putting text
      \ifnum\pix=0\relax%
      \else%
        \node[font=\bfseries,text=font \pix] at (gm-\x-\y)  {\pix};%
      \fi%
    }%
  }%

  \begin{scope}[on background layer]
  \fill[gridc,rounded corners]
    ($(gm-1-1)+(-.55*\grshift,.55*\grshift)$)
   rectangle
    ($(gm-4-4)+(.55*\grshift,-.55*\grshift)$);
  \end{scope}%
  },%
}%

% that's just an alias for \node
\makeatletter
\newcommand{\drawgame}[1][game]{\tikz@path@overlay{node}[#1]}
\makeatother


\begin{document}
\def\pixels{
 {0,2,32,64},
 {256,8,512,4},
 {1024,2048,4,16},
 {4096,16,128,2},
}

\begin{tikzpicture}
\drawgame{};
\end{tikzpicture}

\begin{tikzpicture}
\drawgame[shift value=1.5cm, 
 every module={minimum size=1.2cm},
 game]% specify as last option the actual code ``game''
 {};
\draw(0,0)--(7,0);
\end{tikzpicture}
\end{document}

The second picture provides:

enter image description here

0
27

Another starting point. This one uses a matrix and customized styles for each kind of note. Final colors where stolen from Claudio's answer.

Next code defines a command \drawboard{} which can create an empty board or an already filled board when rows are indicated \drawboard{{2,0,16},{64,128,0,32},{0,4},{2,4,4}} (there is no need to fill all positions).

And command \drawpixel{x-y}{value} fills boardposition x-y with indicated value. It can be used once a board is created.

\documentclass[tikz, border=2mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{matrix}
% Font color for 2 and 4: #776e65
% Font color for rest: #f9f6f2
% Grid color: #bbada0
% Font family: "Clear Sans", "Helvetica Neue", Arial, sans-serif

\definecolor{board}{HTML}{BBADA0}
\definecolor{pixel 0}{HTML}{CCC0B3}
\definecolor{pixel 2}{HTML}{EEE4DA}
\definecolor{pixel 4}{HTML}{EDE0C8}
\definecolor{pixel 8}{HTML}{F2B179}
\definecolor{pixel 16}{HTML}{F59563}
\definecolor{pixel 32}{HTML}{F67C5F}
\definecolor{pixel 64}{HTML}{F65E3B}
\definecolor{pixel 128}{HTML}{EDCF72}
\definecolor{pixel 256}{HTML}{EDCC61}
\definecolor{pixel 512}{HTML}{EDC850}
\definecolor{pixel 1024}{HTML}{EDC53F}
\definecolor{pixel 2048}{HTML}{EDC22E}
\definecolor{pixel 4096}{HTML}{3E3933}

\definecolor{font 0}{HTML}{F9F6F2}
\definecolor{font 2}{HTML}{776E65}
\definecolor{font 4}{HTML}{776E65}
\definecolor{font 8}{HTML}{F9F6F2}
\definecolor{font 16}{HTML}{F9F6F2}
\definecolor{font 32}{HTML}{F9F6F2}
\definecolor{font 64}{HTML}{F9F6F2}
\definecolor{font 128}{HTML}{F9F6F2}
\definecolor{font 256}{HTML}{F9F6F2}
\definecolor{font 512}{HTML}{F9F6F2}
\definecolor{font 1024}{HTML}{F9F6F2}
\definecolor{font 2048}{HTML}{F9F6F2}
\definecolor{font 4096}{HTML}{F9F6F2}

\tikzset{
    pixel/.style={rounded corners, minimum width=1cm, minimum height=1cm, 
                   anchor=center, fill=#1, font=\sffamily},
    pixel 0/.style={pixel=pixel 0, text=font 0,node contents={~}},
    pixel 2/.style={pixel=pixel 2, text=font 2, node contents={2}},
    pixel 4/.style={pixel=pixel 4, text=font 4, node contents={4}},
    pixel 8/.style={pixel=pixel 8, text=font 8, node contents={8}},
    pixel 16/.style={pixel=pixel 16, text=font 16, node contents={16}},
    pixel 32/.style={pixel=pixel 32, text=font 32, node contents={32}},
    pixel 64/.style={pixel=pixel 64, text=font 64, node contents={64}},
    pixel 128/.style={pixel=pixel 128, text=font 128, node contents={128}},
    pixel 256/.style={pixel=pixel 256, text=font 256, node contents={256}},
    pixel 512/.style={pixel=pixel 512, text=font 512, node contents={512}},
    pixel 1024/.style={pixel=pixel 1024, text=font 1024, node contents={1024}},
    pixel 2048/.style={pixel=pixel 2048, text=font 2048, node contents={2048}},
    board/.style={matrix of nodes, nodes={pixel=pixel 0}, fill=board, 
                         column sep=2mm, row sep=2mm, nodes in empty cells, 
                         rounded corners=1mm}
    }

\def\pixels{{0,2,0,32},{2,8,2,4},{2,2,4,16},{8,16,128,2}}

\newcommand{\drawboard}[1]{
    \matrix (board) [board, ampersand replacement=\&]%
            { \& \& \& \\ \& \& \& \\ \& \& \& \\ \& \& \& \\};
    \foreach \line [count =\y] in {#1} { 
        \foreach \pix [count = \x] in \line {
            \node[pixel \pix, at=(board-\y-\x)];
        }
    }   
}

\newcommand{\drawpixel}[2]{
    \node[pixel #2, at=(board-#1)];
}

\begin{document}   
\begin{tikzpicture}
\drawboard{{0,2,0,32},{2,8},{2},{8,16,128,2}}

\drawpixel{1-2}{4}
\drawpixel{3-3}{1024}

\end{tikzpicture}
\end{document}

2048 board

21

Simple (or simplistic) version. Some of the colors were shamelessly stolen from other answers on this page.

\documentclass[tikz,border=5]{standalone}
\newbox\tzfebox
\tikzset{%
  HTML fill/.style={/utils/exec=\definecolor{@fill}{HTML}{#1}, fill=@fill},
  HTML text/.style={/utils/exec=\definecolor{@text}{HTML}{#1}, text=@text},
  rounding/.style={rounded corners=0.0625cm},
  2048/.cd, 
    node/.style={%
      rounding, minimum size=.9cm, inner sep=0pt, 
      font=\Large\sffamily\bfseries, node contents=#1, 2048/#1/.try,
      execute at begin node={\setbox\tzfebox=\hbox\bgroup},
      execute at end node={\egroup%
         \pgfmathparse{\wd\tzfebox>.75cm ? .75cm/\wd\tzfebox : 1}%
         \scalebox{\pgfmathresult}{\box\tzfebox}%
      }%
    },
    0/.style={HTML fill=CCC0B3, HTML text=CCC0B3},
    2/.style={HTML fill=EEE4DA, HTML text=776E65},
    4/.style={HTML fill=EDE0C8, HTML text=776E65},
    8/.style={HTML fill=F2B179, HTML text=F9F6F2},
   16/.style={HTML fill=F59563, HTML text=F9F6F2},
   32/.style={HTML fill=F67C5F, HTML text=F9F6F2},
   64/.style={HTML fill=F65E3B, HTML text=F9F6F2},
  128/.style={HTML fill=EDCF72, HTML text=F9F6F2},
  256/.style={HTML fill=EDCC61, HTML text=F9F6F2},
  512/.style={HTML fill=EDC850, HTML text=F9F6F2},
 1024/.style={HTML fill=EDC53F, HTML text=F9F6F2},
 2048/.style={HTML fill=EDC22E, HTML text=F9F6F2},
 4096/.style={HTML fill=3E3933, HTML text=F9F6F2}
} 
\def\pixels{
{0,2,0,0},
{0,8,0,64},
{2,32,4,128},
{8,16,4096,2},
}
\begin{document}
\begin{tikzpicture}
\path [HTML fill=BBADA0, rounding] (-.55,-.55) rectangle ++(4+.1,4+.1);
\foreach \i [count=\y from 0] in \pixels
  \foreach \j [count=\x from 0] in \i
    \node at (\x, 3-\y) [2048/node=\j];
\end{tikzpicture}
\end{document}

enter image description here

And this one combines the background layer idea of Paul Gaborit so that the 2048 board can be a pic with a cleaner board specification which uses the chains, calc, fit and background libraries (I think I also got the idea of recursive key parsing from one of Paul Gaborit's answers to another question).

\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{chains,fit,backgrounds,calc}
\newbox\tzfebox
\tikzset{%
  HTML fill/.style={/utils/exec=\definecolor{@fill}{HTML}{#1}, fill=@fill},
  HTML text/.style={/utils/exec=\definecolor{@text}{HTML}{#1}, text=@text},
  rounding/.style={rounded corners=0.0625cm},
  pics/2048 board/.style={
    /tikz/.cd,
      insert path={ coordinate (tikz@2048) },
      start chain=2048 placed {at={($(tikz@2048)+({mod(\tikzchaincount-1,4)},{-floor((\tikzchaincount-1)/4)})$)}},
      2048/parse pixels={#1 99 99}
  },
  2048/.cd, 
    node/.style={%
      rounding, minimum size=.9cm, inner sep=0pt, 
      font=\Large\sffamily\bfseries, node contents=#1, 2048/#1/.try,
      execute at begin node={\setbox\tzfebox=\hbox\bgroup},
      execute at end node={\egroup%
         \pgfmathparse{\wd\tzfebox>.75cm ? .75cm/\wd\tzfebox : 1}%
         \scalebox{\pgfmathresult}{\box\tzfebox}%
      }%
    },
    0/.style={HTML fill=CCC0B3, HTML text=CCC0B3},
    2/.style={HTML fill=EEE4DA, HTML text=776E65},
    4/.style={HTML fill=EDE0C8, HTML text=776E65},
    8/.style={HTML fill=F2B179, HTML text=F9F6F2},
   16/.style={HTML fill=F59563, HTML text=F9F6F2},
   32/.style={HTML fill=F67C5F, HTML text=F9F6F2},
   64/.style={HTML fill=F65E3B, HTML text=F9F6F2},
  128/.style={HTML fill=EDCF72, HTML text=F9F6F2},
  256/.style={HTML fill=EDCC61, HTML text=F9F6F2},
  512/.style={HTML fill=EDC850, HTML text=F9F6F2},
 1024/.style={HTML fill=EDC53F, HTML text=F9F6F2},
 2048/.style={HTML fill=EDC22E, HTML text=F9F6F2},
 4096/.style={HTML fill=3E3933, HTML text=F9F6F2},
 parse pixels/.code args={#1 #2}{%
    \ifnum#1=99\relax%
      \begin{pgfonlayer}{background}%
        \node [HTML fill=BBADA0, rounding, fit=(n-1) (n-\tikzchaincount)] {};
      \end{pgfonlayer}%
    \else
      \tikzset{/tikz/insert path={node [on chain,name=n-\tikzchaincount,2048/node=#1]},
        2048/parse pixels={#2}}%
    \fi
  }
} 

\begin{document}
\begin{tikzpicture}

\path (0,0) pic {2048 board={
    0    0    0    0
    4    0    2    2
    4   32    0    4
    8   32   64  128
 }};

\path (5,0) pic {2048 board={
    0    0    0    0
    0    0    0    0
    8    0    0    4
    8   64   64  128
 }};

\path (0,-5) pic {2048 board={
    0    0    0    0
    0    0    0    4
    0    0    0    8
   16    0  128  128
 }};

\path (5,-5) pic {2048 board={
    0    0    0    0
    0    4    0    0
    0    0    0    8
   16    0    0  256
 }};

\end{tikzpicture}
\end{document}

enter image description here

14

Here's another solution based on logicpuzzle's hitori environment:

\documentclass{standalone}
\usepackage{logicpuzzle}
\renewcommand\familydefault{\sfdefault}
\makeatletter
% defining colors LP@c@romannumeral
\definecolor{LP@c@zero}{HTML}{CCC0B3}
\definecolor{LP@c@grid}{HTML}{BBADA0}
\definecolor{LP@c@numcoli}{HTML}{776E65}
\definecolor{LP@c@numcolii}{HTML}{F9F6F2}
\definecolor{LP@c@ii}{HTML}{EEE4DA}
\definecolor{LP@c@iv}{HTML}{EEE4DA}
\definecolor{LP@c@viii}{HTML}{F2B179}
\definecolor{LP@c@xvi}{HTML}{F59563}
\definecolor{LP@c@xxxii}{HTML}{F2B179}
\definecolor{LP@c@lxiv}{HTML}{F2B179}
\definecolor{LP@c@cxxviii}{HTML}{EDCF72}
\definecolor{LP@c@cclvi}{HTML}{F2B179}
%
%redefine \setcolorrow for using different zero color
\renewcommand*\setcolorrow[2]%
{%
  \setcounter{LP@counti}{1}%
  \setcounter{LP@countii}{#1}%
  \gdef\LP@fontcolor{LP@c@numcolii}%
  \foreach \LP@element in {#2}%
  {%
    \ifthenelse{\equal{\LP@element}{0}}%
    {%
      \gdef\LP@HT@color{LP@c@zero}%
      \begin{puzzlebackground}%
        \fillcell{\arabic{LP@counti}}{\arabic{LP@countii}}%
      \end{puzzlebackground}%
    }%
    {%
      \expandafter\gdef\expandafter\LP@HT@color{LP@c@\romannumeral\LP@element}%
      \begin{puzzlebackground}%
        \fillcell{\arabic{LP@counti}}{\arabic{LP@countii}}%
      \end{puzzlebackground}%
      \ifthenelse{\equal{\LP@element}{2}}%
        {\def\LP@fontcolor{LP@c@numcoli}}{}%
      \ifthenelse{\equal{\LP@element}{4}}%
        {\def\LP@fontcolor{LP@c@numcoli}}{}%
      \node[color=\LP@fontcolor,font=\bfseries] at (\arabic{LP@counti}.5,\arabic{LP@countii}.5){\LP@element};%
    }%
    \stepcounter{LP@counti}%
  }%
}%
%
% redefining grid color and line width
\renewcommand*\LP@drawgrid[5]%
{%
  \setcounter{LP@counti}{#3}% max column
  \setcounter{LP@countii}{#4}% max row
  \stepcounter{LP@counti}%
  \stepcounter{LP@countii}%
  \draw[color=LP@c@grid,step=#5,line width=2.4pt,\LP@grid@linestyle,%
        draw opacity=\LP@draw@opacity,line join=round,line cap=round]%
        (#1,#2) grid (\value{LP@counti},\value{LP@countii});%
}%
\let\mypuzzle\hitori
\let\endmypuzzle\endhitori
\makeatother
\begin{document}
\begin{mypuzzle}[rows=4,columns=4,width=4.3cm]
\setcolorrow{4}{0,2,0,0}
\setcolorrow{3}{0,8,0,4}
\setcolorrow{2}{2,2,4,16}
\setcolorrow{1}{8,16,128,2}
\end{mypuzzle}
\end{document}

enter image description here

3
  • You need \newcommand*\LP@G@setcellcontent, not \renewcommand*\LP@G@setcellcontent, and make sure this works for larger numbers as well.
    – Werner
    May 2, 2014 at 16:27
  • \LP@G@setcellcontent is defined in logicpuzzle.sty! Do you have an older version of logicpuzzle? For larger numbers one can use the fontsize option of the environment.
    – Josef
    May 2, 2014 at 16:32
  • Perhaps; I've never used logicpuzzle.
    – Werner
    May 2, 2014 at 16:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .