是否有可能以更简单的方式编写代码?:
\documentclass[landscape]{article}
\usepackage[paperwidth=42in,paperheight=40in,margin=0.5in]{geometry}
\usepackage{skak} %package to display chessboards with notation
\usepackage{tikz}
\pagenumbering{gobble} % avoid page numbering
\begin{document}
\begin{tikzpicture}[
level 1/.style={sibling distance=32cm,}, %x-spacing
level 2/.style={sibling distance=0cm,},
level 3/.style={sibling distance=17cm,},
level 4/.style={sibling distance=0cm,},
level 5/.style={sibling distance=7cm,},
level distance=7cm, %y-spacing
line width=2,]
%
\node {\newgame \mainline{1.f4} \storegame{move1000} \showboard}
child { node {\restoregame{move1000} \mainline{1...Nf6} \showboard}
child { node { \mainline{2.g3} \storegame{move1100} \showboard}
child { node {\restoregame{move1100} \mainline{2...d5} \showboard}
child { node { \mainline{3. Bg2} \storegame{move1110} \showboard}
child { node {\restoregame{move1110} \mainline{3...e6} \showboard}
child { node { \mainline{4. a4} \showboard}
child { node { \mainline{4...c6} \showboard}
child { node [rectangle, minimum size=7.5cm] {eval: -0.1}}
}
}
}
child { node {\restoregame{move1110} \mainline{3...e6} \showboard}
child { node {\mainline{4. a4} \showboard}
child { node {\mainline{4...c6} \showboard}
child { node [rectangle, minimum size=7.5cm] {eval: -0.2}}
}
}
}
child { node {\restoregame{move1110} \mainline{3...c5} \showboard}
child { node [rectangle, minimum size=7.5cm] {-0.3}}
}
}
}
child { node {\restoregame{move1100} \mainline{2...g6} \showboard}
child { node [rectangle, minimum size=7.5cm] {eval: -0.2}}
}
child { node {\restoregame{move1100} \mainline{2...c5} \showboard}
child { node { \mainline{3. Nf3} \showboard}
child { node [rectangle, minimum size=7.5cm] {eval: -0.2}}
}
}
}
}
%
child { node [operator, xshift=-0cm] {\restoregame{move1000} \mainline{1...e5} \showboard}
child { node {\mainline{2. fxe5} \showboard}
child { node {\mainline{2...d6} \showboard}
child { node {\mainline{3. exd6} \showboard}
child { node {\mainline{3...Bxd6} \showboard}
child { node {\mainline{4. Nf3} \showboard}
child { node {\mainline{4...Nf6} \showboard}
child { node [rectangle, minimum size=7.5cm] {eval: +0.7}}
}
}
}
}
}
}
}
%
child { node [operator, xshift=-20cm] {\restoregame{move1000} \mainline{1...f5} \showboard}
child { node {\mainline{2. Nf3} \showboard}
child { node {\mainline{2...Nf6} \showboard}
child { node {\mainline{3. c4} \showboard}
child { node {\mainline{3...c5} \showboard}
child { node {\mainline{4. b3} \showboard}
child { node {\mainline{4...g6} \showboard}
child { node {\mainline{5. g3} \showboard}
child { node {\mainline{5...Nc6} \showboard}
child { node {\mainline{6. Bg2} \showboard}
child { node {\mainline{6... Bg7} \showboard}
child { node {\mainline{7. Bb2} \showboard}
child { node [rectangle, minimum size=7.5cm] {eval: +0.3}}
}
}
}
}
}
}
}
}
}
}
}
}
%
child { node [operator, xshift=-40cm] {\restoregame{move1000} \mainline{1...g6} \showboard}
child { node {\mainline{2. Nf3} \showboard}
child { node {\mainline{2...d5} \showboard}
child { node {\mainline{3. e3} \showboard}
child { node {\mainline{3...Bg7} \showboard}
child { node {\mainline{4. d4} \showboard}
child { node {\mainline{4...c5} \showboard}
child { node {\mainline{5. Bd3} \showboard}
child { node [rectangle, minimum size=7.5cm] {eval: -0.4}}
}
}
}
}
}
}
}
}
%
child { node [operator, xshift=-60cm] {\restoregame{move1000} \mainline{1...b6} \showboard}
child { node {\mainline{2. e4} \showboard}
child { node {\mainline{2...Bb7} \showboard}
child { node {\mainline{3. d3} \showboard}
child { node {\mainline{3...e6} \showboard}
child { node {\mainline{4. Bd2} \showboard}
child { node {\mainline{4...Nc6} \showboard}
child { node {\mainline{5. Nf3} \showboard}
child { node [rectangle, minimum size=7.5cm] {eval: -0.1}}
}
}
}
}
}
}
}
}
%
;
\end{tikzpicture};
%
\end{document}
获得类似的结果:
我会欣赏像森林这样的东西: https://tex.stackexchange.com/questions/35526/tikz-tree-sibling-distance
(或者,我倾向于将移动描述放在棋盘前面的行上,例如在棋盘前面加上“\newline”)。
答案1
这里有一种方法,它:
- 从你的代码开始
- 提供一些
refactoring
专注于较短行的内容,即更好的可读性(希望如此) - 草图转移到包装
forest
开始
我意识到你会在一张小纸上画出一幅巨大的图画。假设 papersize 不相关,我用 替换了该类
article
,standalone
它可以根据需要放大“页面”。作为副产品,大多数软件包都过时了。我无法对所有子分支进行编译,也无法定位问题,因此我将其简化为那些可以编译的分支:这基本上是第一个子分支。因此从现在开始,它更像是一个演示,而不是 1:1 翻译。
重构
接下来,我认识到了 node-content 和 node-style 的重复模式。我
evl
在 开头定义的样式tikzpicture
,其中rectangle
,默认形状,已经过时了。node-content 原来非常系统化,所以我决定将它们重构为 3 个 TeX 宏\restg
,\mainl
和\mnlne
。用更有用的名称替换将是下一个重构步骤,这里不做。(在 tikzpicture 环境中使用 \newcommands 时,Tikz 几乎总是会失败,而 TeX 宏似乎运行良好,但代价是牺牲了 \newcommand 附带的所有检查功能。)现在,每行代码都更紧凑了,尽管还剩下很多空白噪音。处理这些问题取决于个人品味和偏好。所以我基本保持原样。
在这棵树上迷路真是太容易了,在森林里也是如此……
\documentclass[10pt,border=3mm,tikz]{standalone}% if you're not bound to a papersize
%\documentclass[landscape]{article}
%\usepackage[paperwidth=42in,paperheight=40in,margin=0.5in]{geometry}
\usepackage{skak} %package to display chessboards with notation
%\usepackage{tikz} % already called with standalone
%\pagenumbering{gobble} % avoid page numbering % standalone is one big page
% ~~~ refactoring: some shortcuts ~~~~~~~~~~~~~~~~~~~~~~~~~
\def\restg#1#2{\restoregame{move#1} \mainline{#2} \showboard}
\def\mainl#1#2{\mainline{#1} \storegame{move#2} \showboard}
\def\mnlne#1{\mainline{#1} \showboard}
% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\begin{document}
\begin{tikzpicture}[
level 1/.style={sibling distance=32cm,}, %x-spacing
level 2/.style={sibling distance=0cm,},
level 3/.style={sibling distance=17cm,},
level 4/.style={sibling distance=0cm,},
level 5/.style={sibling distance=7cm,},
level distance=7cm, %y-spacing
line width=2,
%
% refactoring:
evl/.style={minimum size=7.5cm,fill=teal!5}, % eval-style; rectangle = default shape
]
%
\node {\newgame \mainline{1.f4} \storegame{move1000} \showboard}
child { node { \restg{1000}{1...Nf6} }
child { node { \mainl{2.g3}{1100} }
child { node {\restg{1100}{2...d5}}
child { node { \mainl{3. Bg2}{1110} }
child { node { \restg{1110}{3...e6} }
child { node { \mnlne{4. a4} }
child { node { \mnlne{4...c6} }
child { node [evl] {eval: -0.1}}
}
}
}
child { node {\restg{1110}{3...e6}}
child { node { \mnlne{4. a4} }
child { node { \mnlne{4...c6} }
child { node [evl] {eval: -0.2}}
}
}
}
child { node {\restg{1110}{3...c5}}
child { node [evl] {-0.3} }% <<< intended to miss eval?
}
}
}
child { node {\restg{1100}{2...g6}}
child { node [evl] {eval: -0.2} }
}
child { node {\restg{1100}{2...c5}}
child { node { \mnlne{3. Nf3} }
child { node [evl] {eval: -0.2} }
}
}
}
}
;
\end{tikzpicture}%;
%
\end{document}
森林
重复使用上面的最终代码,我开始将其转移到森林中。我必须承认,我很快就迷失在棋步和游戏恢复的精确流程中。所以这里更像是一个演示,省去了森林微调的所有花哨功能。(现在的内容肯定几乎毫无用处。)
\documentclass[10pt,border=3mm,tikz]{standalone}% if you're not bound to a papersize
\usepackage{skak} %package to display chessboards with notation
\usepackage{forest}
% ~~~ refactoring: some shortcuts ~~~~~~~~~~~~~~~~~~~~~~~~~
\def\restg#1#2{\restoregame{move#1} \mainline{#2} \showboard}
\def\mainl#1#2{\mainline{#1} \storegame{move#2} \showboard}
\def\mnlne#1{\mainline{#1} \showboard}
% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\begin{document}
\begin{forest}
[\newgame \mainline{1.f4} \storegame{move1000} \showboard
[\restg{1000}{1...Nf6}
[\mainl{2.g3}{1100}]
[\restg{1000}{1...g6}
[eval: -0.2]
]
[\restg{1000}{1...b6}]
]
]
\end{forest}
\end{document}
结束语
- 这两种方法都可以调整许多布局相关的方面,例如:
- 距离和位置
- 连接器的形状(像这里一样直的,或者矩形的,或者带圆角的等等)
- 框架和颜色
- ETC。
关键当然是以合乎逻辑、易于掌握的方式构建分支。例如,可以使用一种工具将主分支放在首位,然后
\input
从专用文件中创建子分支,这些文件只包含一系列有用的[ ... ]
构造。如果我理解正确的话,包
skak
可以隐藏输出指定的动作。如果是这样,你可以:
- 将移动放在专用的 \node 内,将其放置在您需要的位置(即不再放在左下角)
- 稍微修改一下上述宏
- 一个有用的
Tikz
命令是\pic
,以及args
用于传递参数,其中 \pic 只绘制整个棋盘并将移动放置在需要的位置(视为\pic
来自的绘图宏Tikz
)