使用 TikZ(或其他包)绘制游戏板,有点类似于国际象棋(Hnefatafl)

使用 TikZ(或其他包)绘制游戏板,有点类似于国际象棋(Hnefatafl)

我需要编写一些文档,并需要显示 Hnefatafl 棋盘。基本上,它是一个 11x11 的棋盘,一些方格会被突出显示(例如交叉影线)。棋子基本上相当于黑棋、白棋、黑王 - 我可以使用圆圈甚至国际象棋棋子来表示,棋盘将具有国际象棋风格的等级和文件符号(1-11、AK 等)。

真的需要一些建议,我想我可能需要编写一些(希望是简单的)包,tikZ 是最好的起点吗?或者有没有国际象棋包或其他可以实现上述功能的东西?我对 LaTeX 比较陌生,我可以做基础工作,但需要多学一点。如果能就如何做到这一点提出任何建议,我将不胜感激。

提前致谢!

答案1

您可以创建自定义命令。在这里,我使用 expl 语法将一些字母数字坐标(例如f4Ti 中相关坐标处的节点)转换为Z 坐标系。对于实际的游戏板,我使用了\pic。但当然,还有很多其他同样有效的方法:

\documentclass[border=10pt]{standalone}
\usepackage{tikz}

\ExplSyntaxOn
\cs_generate_variant:Nn \int_from_alph:n { e }
\NewExpandableDocumentCommand{\HnefataflBoardMakeNode}{ o m }{
    \str_set:Nn \l_tmpa_str { #2 }
    \str_set:Nn \l_tmpb_str { #2 } 
    \regex_replace_all:nnN { \d } { } \l_tmpa_str
    \regex_replace_all:nnN { [a-zA-Z] } { } \l_tmpb_str
    \int_set:Nn \l_tmpa_int { \int_from_alph:e { \l_tmpa_str } }
    \int_set:Nn \l_tmpb_int { \l_tmpb_str } 
    \int_decr:N \l_tmpa_int
    \int_decr:N \l_tmpb_int
    \node[#1] at ( { \int_use:N \l_tmpa_int + 0.5 } , { \int_use:N \l_tmpb_int + 0.5 } ) {};
}
\ExplSyntaxOff

\tikzset{
    pics/hnefatafl board/.style={
        code={
            \tikzset{hnefatafl board/.cd, #1}
            \draw[step=1cm] (0,0) grid 
                (\pgfkeysvalueof{/tikz/hnefatafl board/size},\pgfkeysvalueof{/tikz/hnefatafl board/size});
            \draw[thick] (0,0) rectangle 
                (\pgfkeysvalueof{/tikz/hnefatafl board/size},\pgfkeysvalueof{/tikz/hnefatafl board/size});
            \foreach \cx in {0, {\pgfkeysvalueof{/tikz/hnefatafl board/size}-1}} {
                \foreach \cy in {0, {\pgfkeysvalueof{/tikz/hnefatafl board/size}-1}} {
                    \draw (\cx,\cy) -- +(1,1) +(1,0) -- +(0,1);
                }
            }
        }
    },
    hnefatafl board/size/.initial={11},
    hnefatafl board/king node/.style={
        circle,
        draw,
        minimum size=0.9cm,
        append after command={
            node[circle, draw, minimum size=0.7cm] at (\tikzlastnode.center) {}
        }
    },
    hnefatafl board/defender node/.style={
        circle,
        draw,
        minimum size=0.9cm
    },
    hnefatafl board/aggressor node/.style={
        circle,
        fill,
        minimum size=0.9cm
    },
    hnefatafl board/k/.code={
        \HnefataflBoardMakeNode[hnefatafl board/king node]{#1}
    },
    hnefatafl board/a/.code={
        \HnefataflBoardMakeNode[hnefatafl board/aggressor node]{#1}
    },
    hnefatafl board/d/.code={
        \HnefataflBoardMakeNode[hnefatafl board/defender node]{#1}
    },
    hnefatafl board/king/.code={
        \tikzset{hnefatafl board/k/.list={#1}}
    },
    hnefatafl board/aggressors/.code={
        \tikzset{hnefatafl board/a/.list={#1}}
    },
    hnefatafl board/defenders/.code={
        \tikzset{hnefatafl board/d/.list={#1}}
    }
}

\begin{document}
    \begin{tikzpicture}
        \pic {hnefatafl board={
            king={f6},
            aggressors={a4,a5,a6,a7,a8,b6,k4,k5,k6,k7,k8,j6},
            aggressors={d1,e1,f1,g1,h1,f2,d11,e11,f11,g11,h11,f10},
            defenders={f8,e7,f7,g7,d6,e6,g6,h6,e5,f5,g5,f4},
        }};
    \end{tikzpicture}

    \begin{tikzpicture}
        \pic {hnefatafl board={
            size=7,
            king={d4},
            aggressors={a3,a4,a5,b4,f4,g3,g4,g5},
            aggressors={c1,d1,e1,d2,c7,d7,e7,d6},
            defenders={e3,e4,e5,d3,d5,c3,c4,c5}
        }};
    \end{tikzpicture}
\end{document}

在此处输入图片描述


或者也许是使用包的实现l3draw

\documentclass[border=10pt]{standalone}
\usepackage{l3draw}

\ExplSyntaxOn

\cs_generate_variant:Nn \int_from_alph:n { e }
\dim_new:N \l_lewise_hnefataflboard_coordx_dim
\dim_new:N \l_lewise_hnefataflboard_coordy_dim
\cs_new:Nn \lewise_hnefataflboard_convert_coordinate:n {
    \str_set:Nn \l_tmpa_str { #1 }
    \str_set:Nn \l_tmpb_str { #1 } 
    \regex_replace_all:nnN { \d } { } \l_tmpa_str
    \regex_replace_all:nnN { [a-zA-Z] } { } \l_tmpb_str
    \int_set:Nn \l_tmpa_int { \int_from_alph:e { \l_tmpa_str } }
    \int_set:Nn \l_tmpb_int { \l_tmpb_str } 
    \int_decr:N \l_tmpa_int
    \int_decr:N \l_tmpb_int
    \dim_set:Nn \l_lewise_hnefataflboard_coordx_dim { \l_tmpa_int cm + 0.5cm }
    \dim_set:Nn \l_lewise_hnefataflboard_coordy_dim { \l_tmpb_int cm + 0.5cm }
}

\int_new:N \l_lewise_hnefataflboard_size_int
\seq_new:N \g_lewise_hnefataflboard_pieces_seq
\keys_define:nn { hnefatafl board } {
    size .int_set:N = \l_lewise_hnefataflboard_size_int ,
    size .initial:n = { 11 } ,
    king .code:n = {
        \clist_set:Nn \l_tmpa_clist { #1 }
        \clist_map_inline:Nn \l_tmpa_clist {
            \seq_gput_right:Nn \g_lewise_hnefataflboard_pieces_seq { 
                \lewise_hnefataflboard_convert_coordinate:n { ##1 } 
                \draw_path_circle:nn 
                    { \l_lewise_hnefataflboard_coordx_dim , 
                      \l_lewise_hnefataflboard_coordy_dim } { 0.45cm }
                \draw_path_circle:nn 
                    { \l_lewise_hnefataflboard_coordx_dim , 
                      \l_lewise_hnefataflboard_coordy_dim } { 0.35cm }
                \draw_path_use_clear:n { stroke }
            }
        }
    },
    defenders .code:n = {
        \clist_set:Nn \l_tmpa_clist { #1 }
        \clist_map_inline:Nn \l_tmpa_clist {
            \seq_gput_right:Nn \g_lewise_hnefataflboard_pieces_seq { 
                \lewise_hnefataflboard_convert_coordinate:n { ##1 } 
                \draw_path_circle:nn 
                    { \l_lewise_hnefataflboard_coordx_dim , 
                      \l_lewise_hnefataflboard_coordy_dim } { 0.45cm }
                \draw_path_use_clear:n { stroke }
            }
        }
    },
    aggressors .code:n = {
        \clist_set:Nn \l_tmpa_clist { #1 }
        \clist_map_inline:Nn \l_tmpa_clist {
            \seq_gput_right:Nn \g_lewise_hnefataflboard_pieces_seq { 
                \lewise_hnefataflboard_convert_coordinate:n { ##1 } 
                \draw_path_circle:nn 
                    { \l_lewise_hnefataflboard_coordx_dim , 
                      \l_lewise_hnefataflboard_coordy_dim } { 0.45cm }
                \draw_path_use_clear:n { fill }
            }
        }
    }
}

\NewDocumentCommand{\HnefataflBoard}{ m }{
    \seq_gclear:N \g_lewise_hnefataflboard_pieces_seq
    \keys_set:nn { hnefatafl board } { #1 } 

    \draw_begin:

    \draw_linewidth:n { 0.2pt }
    \draw_path_grid:nnnn
        { 1cm } { 1cm }
        { 0cm , 0cm }
        { \l_lewise_hnefataflboard_size_int * 1cm , 
            \l_lewise_hnefataflboard_size_int * 1cm }
    \draw_path_use_clear:n { stroke }
    \draw_linewidth:n { 0.4pt }
    \draw_path_rectangle:nn 
        { 0 , 0 } 
        { \l_lewise_hnefataflboard_size_int * 1cm , 
            \l_lewise_hnefataflboard_size_int * 1cm }
    \draw_path_use:n { stroke }

    \draw_path_moveto:n { 0cm , 0cm }
    \draw_path_lineto:n { 1cm , 1cm }
    \draw_path_moveto:n { 1cm , 0cm }
    \draw_path_lineto:n { 0cm , 1cm }
    \draw_path_moveto:n { ( \l_lewise_hnefataflboard_size_int - 1 ) * 1cm , 0cm }
    \draw_path_lineto:n { \l_lewise_hnefataflboard_size_int * 1cm , 1cm }
    \draw_path_moveto:n { \l_lewise_hnefataflboard_size_int * 1cm , 0cm }
    \draw_path_lineto:n { ( \l_lewise_hnefataflboard_size_int - 1 ) * 1cm , 1cm }
    \draw_path_moveto:n { 0cm , ( \l_lewise_hnefataflboard_size_int - 1 ) * 1cm }
    \draw_path_lineto:n { 1cm , \l_lewise_hnefataflboard_size_int * 1cm }
    \draw_path_moveto:n { 0cm , \l_lewise_hnefataflboard_size_int * 1cm }
    \draw_path_lineto:n { 1cm , ( \l_lewise_hnefataflboard_size_int - 1 ) * 1cm }
    \draw_path_moveto:n { ( \l_lewise_hnefataflboard_size_int - 1 ) * 1cm , 
        ( \l_lewise_hnefataflboard_size_int - 1 ) * 1cm }
    \draw_path_lineto:n { \l_lewise_hnefataflboard_size_int * 1cm ,   
        \l_lewise_hnefataflboard_size_int * 1cm }
    \draw_path_moveto:n { ( \l_lewise_hnefataflboard_size_int - 1 ) * 1cm , 
        \l_lewise_hnefataflboard_size_int * 1cm }
    \draw_path_lineto:n { \l_lewise_hnefataflboard_size_int * 1cm , 
        ( \l_lewise_hnefataflboard_size_int - 1 ) * 1cm }
    \draw_path_use:n { stroke }

    \seq_map_inline:Nn \g_lewise_hnefataflboard_pieces_seq { ##1 }
    
    \draw_end:
}

\ExplSyntaxOff

\begin{document}
    \HnefataflBoard{ 
        king={f6}, 
        aggressors={a4,a5,a6,a7,a8,b6,k4,k5,k6,k7,k8,j6},
        aggressors={d1,e1,f1,g1,h1,f2,d11,e11,f11,g11,h11,f10},
        defenders={f8,e7,f7,g7,d6,e6,g6,h6,e5,f5,g5,f4}
    }
\end{document}

在此处输入图片描述

相关内容