1

Follow up question to the previous question on drawing Tic-Tac-Toe boards.

This question is similar to this one but since SebGlav created such an understandable and easily customizable figure others could surely benefit from it as well.

The goal is to create a partial game tree of Tic-Tac-Toe to explain the Minimax algorithm similar to the one below. The below figure is from "Artifical Intelligence - A Modern Approach" 1995 by Russel and Norvig.

Image is from Russel Norvig "Artifical Intelligence

Edit

After SebGlav informed me that tikzpictures can't be nested I decided to use the solution from the old question mentioned above and was able to create the figure below. current tree of my own

The are still the following problems that I do not know how to solve:

  1. I would like to add the text on the right, e.g. MAX(X), TERMINAL etc.
  2. Currently I do not know how to properly display the dots so I wrote "child dots" as placeholders
  3. The edges of the "child dot" nodes overlap with the board nodes - I assume this is because the text and board nodes are center aligned

Since two of the problems are about the dots I tried to create a Dots style(?) similar to the TTT that was used in the old question.

This is my code:

\documentclass{standalone}
\usepackage{tikz}
\usepackage{forest,calc}
\forestset{
  make tab/.style args={#1:#2:#3/#4:#5:#6/#7:#8:#9}{%
    content={%
      \tabcolsep=.6\tabcolsep
      \begin{tabular}{p{\widthof{x}}|p{\widthof{x}}|p{\widthof{x}}}
        #1 & #2 & #3\\\hline#4&#5&#6\\\hline#7&#8&#9
      \end{tabular}}},
  label position r/.initial=right,
  label position b/.initial=below
}
\begin{document}
\begin{forest}
  TTT/.style args={#1:#2}{
    make tab/.expanded=\forestove{content},
     label={\pgfkeysvalueof{/forest/label position #1}:$#2$}
  },
  TTT*/.style={
    make tab=::/::/::,
    content/.expand once=%
    \expandafter\vphantom\expandafter{\romannumeral-`0\forestov{content}},
    draw=none,
    append after command={(\tikzlastnode.north) edge (\tikzlastnode.south)},
    for descendants={before computing xy={l*=1.2}},
  },
  Dots/.style={
  draw=none,
  },
  th/.style=thick,
  for tree={node options=draw, inner sep=+0pt, parent anchor=south, child anchor=north}
%
[::/::/::, TTT=r:
 [x::/::/::, for tree={calign=child, calign child=1},TTT=r:
   [x:o:/::/::,TTT=b:
     [x:o:x/::/::,TTT=b:
       [child dots, Dots
       [x:o:x/:o:x/:o:, TTT=b:-1]
       ]
       [child dots, Dots
       [x:o:x/o:o:x/x:x:o, TTT=b:0]
       ]
       [child dots, Dots
       [x:o:x/:x:/x:o:o, TTT=b:1]
       ]
       [child dots, Dots
       [child dots terminal, Dots]
       ]
     ]
     [x:o:/x::/::, TTT=b:]
     [x:o:/:x:/::, TTT=b:]
     [child dots, Dots]
   ]
   [x::o/::/::, TTT=b:]
   [x::/o::/::, TTT=b:]
   [child dots, Dots]
]
 [:x:/::/::, TTT=r:]
 [::x/::/::, TTT=r:]
 [::/x::/::, TTT=r:]
 [::/:x:/::, TTT=r:]
 [::/::x/::, TTT=r:]
 [::/::/x::, TTT=r:]
 [::/::/:x:, TTT=r:]
 [::/::/::x, TTT=r:]
]
\end{forest}

\end{document} % [,TTT* % this is just cheating :( to skip a level and go beneath % [o::/:x:/::, TTT=b:1] % [:o:/:x:/::, TTT=b:2] % ]

legnib
  • 77
  • It would be more appreciated if you came with something you already tried and asked specific questions about troubles you encountered, rather than waiting for a do it for me. You sure will get more help by doing that. Creating a tree should be something that you can learn here and there. – SebGlav Feb 21 '22 at 15:49
  • And the problem with trees is that you can't nest tikzpictures without breaking many things. Why don't you want to use the solution presented in your linked answer? – SebGlav Feb 21 '22 at 15:57
  • 1
    @SebGlav Thanks again for the last question. You are absolutely correct that it is better if I show some effort myself as it its supposed be a question rather than a request. I will try to create a version this evening/tomorrow and update the question accordingly. I didn't want to use the version from the linked question because the displayed depth/nodes are different. I will look into changing it. – legnib Feb 21 '22 at 15:59

1 Answers1

2

However, there are basic things that are not clear, some manuals are very gloomy, each node can be named and then used as points to detail or correlate them using arrows, text, etc. In the case of "..." just use \dots, then you can increase the size of the text box in Dots/style... to match size of other styles using inner sep, and outer sep.

RESULT:

enter image description here

MWE:

\documentclass[tikz,border=10pt]{standalone}
\usepackage{forest,calc}
\forestset{
    make tab/.style args={#1:#2:#3/#4:#5:#6/#7:#8:#9}{%
        content={%
            \tabcolsep=.6\tabcolsep
            \begin{tabular}{p{\widthof{x}}|p{\widthof{x}}|p{\widthof{x}}}
                #1 & #2 & #3\\\hline#4&#5&#6\\\hline#7&#8&#9
    \end{tabular}}},
    label position r/.initial=right,
    label position b/.initial=below
}
\begin{document}
    \begin{forest}
        TTT/.style args={#1:#2}{
            make tab/.expanded=\forestove{content},
            label={\pgfkeysvalueof{/forest/label position #1}:$#2$}
        },
        TTT*/.style={
            make tab=::/::/::,
            content/.expand once=%
            \expandafter\vphantom\expandafter{\romannumeral-`0\forestov{content}},
            draw=none,
            append after command={(\tikzlastnode.north) edge (\tikzlastnode.south)},
            for descendants={before computing xy={l*=1.2}},
        },
        Dots/.style={
            draw=none,
            outer sep=20pt %addet this to increase the text node box, that was erased by draw=none
        },
        th/.style=thick,
        for tree={node options=draw, inner sep=+0pt, parent anchor=south, child anchor=north}
        %
        [::/::/::,name=box0, TTT=r:
        [x::/::/::,name=box1, for tree={calign=child, calign child=1},TTT=r:
        [x:o:/::/::,name=box2,TTT=b:
        [x:o:x/::/::,name=box3,TTT=b:
        [\dots, Dots
        [x:o:x/:o:x/:o:,name=box4,TTT=b:-1]
        ]
        [\dots, Dots
        [x:o:x/o:o:x/x:x:o, TTT=b:0]
        ]
        [\dots, Dots
        [x:o:x/:x:/x:o:o, TTT=b:1]
        ]
        [\dots, Dots
        [\dots, Dots]
        ]
        ]
        [x:o:/x::/::, TTT=b:]
        [x:o:/:x:/::, TTT=b:]
        [\dots, Dots]
        ]
        [x::o/::/::, TTT=b:]
        [x::/o::/::, TTT=b:]
        [\dots, Dots]
        ]
        [:x:/::/::, TTT=r:]
        [::x/::/::, TTT=r:]
        [::/x::/::, TTT=r:]
        [::/:x:/::, TTT=r:]
        [::/::x/::, TTT=r:]
        [::/::/x::, TTT=r:]
        [::/::/:x:, TTT=r:]
        [::/::/::x, TTT=r:]
        ]
        \draw(box1.center)++ (-2,0)node(node-name1)[]{MIN (O)};
        \draw(node-name1.center|-box0)node{MAX(X)};
        \draw(box2.center)++ (-2,0)node{MAX (X)};
        \draw(box3.center)++ (-2,0)node{MIN (O)};
        \draw(box4.center)++ (-2,0)node(node-name2){TERMINAL};
        \draw(node-name2.center)++ (0,-1)node{Utility};
    \end{forest}

\end{document}

PSD:

Of course some may get annoyed when making code from images that can be imported as fixed graphics but the idea is to learn and be able to customize, however if you use frameworks like forest that are made to save the code to obtain complex maps, you may sacrificed the customization that yo could do by nesting and automating code, in the end it's a matter of taste.

J Leon V.
  • 11,533
  • 16
  • 47
  • Thank you for your solution and additional explanation. I agree that learning to customize is a better goal than just recreating images that. can be imported as fixed graphics. I will look into properly learning tikz after my thesis. – legnib Feb 22 '22 at 14:14