8

I have a macro (example below) to create a 3x3 grid out of a list of 9 items, but if I try to draw two of them they sit on top of each other. I get that each is a different path and restarting at 0,0... looking for advice on the cleanest way to "package" them so I can draw them next to each other without thinking about their exact size.

Eventually I want to put them into a tree layout algorithm to show a search tree for solving a 3x3 sliding puzzle (using this as an excuse to figure out how to use tikz). My guess is that I need to be able to package up the structure as one unit so that tikz can think of them as nodes to layout. Am I thinking about things the right way or not?

\documentclass{article} 
\usepackage{tikz}

\usetikzlibrary[calc]
\usepackage[active,tightpage]{preview}
\PreviewEnvironment{tikzpicture}

\newcommand{\ninepuzzle}[1] {
    \foreach [count=\i] \val in {#1} { 
        \draw  let \n{row}={int(mod(\i -1, 3))}, \n{col}={ int( ( \i - 1 ) / (-3) ) } in 
            (\n{row}, \n{col}) rectangle  +(1,1) 
            +(0.5, 0.5) node{\val};
    }
}


\begin{document}

\begin{tikzpicture}[scale=1]
    \ninepuzzle{1,2, ,3,4,5,6,7,8}
    \ninepuzzle{8,5,6,3,2,4, ,1,7}
\end{tikzpicture}


\end{document}
4

In his answer, Harish has shown how to shift the puzzles. In this answer I want to show how you can use the forest package to build the tree (notice that no shifting is required, although it could be easily done with the features provided by forest):

\documentclass{standalone} 
\usepackage{forest}
\usetikzlibrary[calc]

\newcommand{\ninepuzzle}[1]{%
\begin{tikzpicture}
    \foreach [count=\i] \val in {#1} { 
        \draw  let \n{row}={int(mod(\i -1, 3))}, \n{col}={ int( ( \i - 1 ) / (-3) ) } in 
            (\n{row}, \n{col}) rectangle  +(1,1) 
            +(0.5, 0.5) node{\val};
    }
\end{tikzpicture}%    
}

\newsavebox\myboxa
\newsavebox\myboxb
\newsavebox\myboxc
\newsavebox\myboxd
\newsavebox\myboxe
\savebox\myboxa{\ninepuzzle{1,2, ,3,4,5,6,7,8}}
\savebox\myboxb{\ninepuzzle{8,5,6,3,2,4, ,1,7}}
\savebox\myboxc{\ninepuzzle{2,4,6,8,,1,3,5,7}}
\savebox\myboxd{\ninepuzzle{,1,2,4,5,3,6,8,7}}
\savebox\myboxe{\ninepuzzle{8,7,3,,4,6,5,1,2}}

\begin{document}

\begin{forest}
for tree={
  parent anchor=south,
  child anchor=north,
}
[\usebox\myboxa
  [\usebox\myboxb
    [\usebox\myboxd
    ]
    [\usebox\myboxe
    ]
  ]
  [\usebox\myboxc
  ]
]
\end{forest}

\end{document}

enter image description here

There's only one thing that remains to be simplified and is the need to previously box each puzzle. In Is it possible to use \node paths directly in forest? (a question I opened inspired by this situation) I expect to get a way to not to have to do the boxing.

5

You can use a scope with some xshift

\documentclass{article}
\usepackage{tikz}

\usetikzlibrary[calc]
\usepackage[active,tightpage]{preview}
\PreviewEnvironment{tikzpicture}

\newcommand{\ninepuzzle}[1] {
    \foreach [count=\i] \val in {#1} {
        \draw  let \n{row}={int(mod(\i -1, 3))}, \n{col}={ int( ( \i - 1 ) / (-3) ) } in
            (\n{row}, \n{col}) rectangle  +(1,1)
            +(0.5, 0.5) node{\val};
    }
}


\begin{document}

\begin{tikzpicture}[scale=1]
    \ninepuzzle{1,2, ,3,4,5,6,7,8}
    \begin{scope}[xshift=4cm]
    \ninepuzzle{8,5,6,3,2,4, ,1,7}
    \end{scope}
\end{tikzpicture}


\end{document}

Or you can use pic from tikz version 3.

\documentclass{article}
\usepackage{tikz}

\usetikzlibrary[calc,positioning]
\usepackage[active,tightpage]{preview}
\PreviewEnvironment{tikzpicture}

\tikzset{
ninepuzzle/.pic={
    \foreach [count=\i] \val in {#1} {
        \draw  let \n{row}={int(mod(\i -1, 3))}, \n{col}={ int( ( \i - 1 ) / (-3) ) } in
            (\n{row}, \n{col}) rectangle  +(1,1)
            +(0.5, 0.5) node{\val};
    }
    \coordinate (-mypoint) at (3,0); %% change (3,0) acc to  \n{row}={int(mod(\i -1, 3))} as 3 
}
}


\begin{document}

\begin{tikzpicture}[scale=1]
    \pic (a) {ninepuzzle={1,2, ,3,4,5,6,7,8}};
    \pic [right = of a-mypoint] {ninepuzzle={8,5,6,3,2,4, ,1,7}};
\end{tikzpicture}


\end{document}

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.