我需要编写一些文档,并需要显示 Hnefatafl 棋盘。基本上,它是一个 11x11 的棋盘,一些方格会被突出显示(例如交叉影线)。棋子基本上相当于黑棋、白棋、黑王 - 我可以使用圆圈甚至国际象棋棋子来表示,棋盘将具有国际象棋风格的等级和文件符号(1-11、AK 等)。
真的需要一些建议,我想我可能需要编写一些(希望是简单的)包,tikZ 是最好的起点吗?或者有没有国际象棋包或其他可以实现上述功能的东西?我对 LaTeX 比较陌生,我可以做基础工作,但需要多学一点。如果能就如何做到这一点提出任何建议,我将不胜感激。
提前致谢!
答案1
您可以创建自定义命令。在这里,我使用 expl 语法将一些字母数字坐标(例如f4
Ti 中相关坐标处的节点)转换为钾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}