结合其他软件包优化 tikz//国际象棋开局曲目的图形可视化

结合其他软件包优化 tikz//国际象棋开局曲目的图形可视化

是否有可能以更简单的方式编写代码?:

\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

开始

  1. 我意识到你会在一张小纸上画出一幅巨大的图画。假设 papersize 不相关,我用 替换了该类articlestandalone它可以根据需要放大“页面”。作为副产品,大多数软件包都过时了。

  2. 我无法对所有子分支进行编译,也无法定位问题,因此我将其简化为那些可以编译的分支:这基本上是第一个子分支。因此从现在开始,它更像是一个演示,而不是 1:1 翻译。

重构

  1. 接下来,我认识到了 node-content 和 node-style 的重复模式。我evl在 开头定义的样式tikzpicture,其中rectangle,默认形状,已经过时了。node-content 原来非常系统化,所以我决定将它们重构为 3 个 TeX 宏\restg\mainl\mnlne。用更有用的名称替换将是下一个重构步骤,这里不做。(在 tikzpicture 环境中使用 \newcommands 时,Tikz 几乎总是会失败,而 TeX 宏似乎运行良好,但代价是牺牲了 \newcommand 附带的所有检查功能。)

  2. 现在,每行代码都更紧凑了,尽管还剩下很多空白噪音。处理这些问题取决于个人品味和偏好。所以我基本保持原样。

  3. 在这棵树上迷路真是太容易了,在森林里也是如此……

\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}

复制1

森林

重复使用上面的最终代码,我开始将其转移到森林中。我必须承认,我很快就迷失在棋步和游戏恢复的精确流程中。所以这里更像是一个演示,省去了森林微调的所有花哨功能。(现在的内容肯定几乎毫无用处。)

\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}

森林演示

结束语

  1. 这两种方法都可以调整许多布局相关的方面,例如:
  • 距离和位置
  • 连接器的形状(像这里一样直的,或者矩形的,或者带圆角的等等)
  • 框架和颜色
  • ETC。
  1. 关键当然是以合乎逻辑、易于掌握的方式构建分支。例如,可以使用一种工具将主分支放在首位,然后\input从专用文件中创建子分支,这些文件只包含一系列有用的[ ... ]构造。

  2. 如果我理解正确的话,包skak可以隐藏输出指定的动作。如果是这样,你可以:

  • 将移动放在专用的 \node 内,将其放置在您需要的位置(即不再放在左下角)
  • 稍微修改一下上述宏
  • 一个有用的Tikz命令是\pic,以及args用于传递参数,其中 \pic 只绘制整个棋盘并将移动放置在需要的位置(视为\pic来自的绘图宏Tikz

相关内容