后续问题上一个问题绘制井字游戏棋盘。
这个问题类似于这个但是由于谢布·格拉夫创建了这样一个易于理解且易于定制的图形,其他人肯定也可以从中受益。
目标是创建一个井字游戏的部分博弈树来解释类似下图的 Minimax 算法。下图来自 Russel 和 Norvig 1995 年的《人工智能 - 现代方法》。
编辑
在 SebGlav 告诉我 tikzpictures 不能嵌套后,我决定使用上面提到的老问题并能创建下面的图形。
仍有以下问题我不知道如何解决:
- 我想在右侧添加文本,例如 MAX(X)、TERMINAL 等。
- 目前我不知道如何正确显示这些点,所以我写了“子点”作为占位符
- “子点”节点的边缘与板节点重叠 - 我认为这是因为文本和板节点是居中对齐的
由于其中两个问题与点有关,因此我尝试创建一种与旧问题中使用的Dots
风格类似的风格(?) 。TTT
这是我的代码:
\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\\\hline#7	
\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]
% ]
答案1
但是,有些基本的东西并不清楚,有些手册很阴暗,每个节点都可以命名,然后用作点来详细说明或使用箭头、文本等关联它们。在“...”的情况下,只需使用,然后您可以使用、和\dots
来增加文本框的大小以Dots/style...
匹配其他样式的大小。inner sep
outer sep
结果:
梅威瑟:
\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\\\hline#7	
\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}
附录:
当然,有些人可能会对从可以作为固定图形导入的图像编写代码感到恼火,但这样做的目的是为了学习并能够定制,但是如果您使用像森林这样的框架来保存代码以获得复杂的地图,您可能会牺牲通过嵌套和自动化代码可以进行的定制,最终这是一个品味问题。