1

I need to write some documentation and need to display a Hnefatafl board. Basically it is an 11x11 board, some of the squares would be highlighted (e.g. cross hatching). The pieces are basically equivalent to black pawn, white pawn, black King - and I could use either circles or even chess board pieces to represent, the board would have chess style rank and file notation (1-11, A-K etc.).

Really looking for some advise, I think I may need to write some (hopefully simple) package, would tikZ be the best place to start or is there a chess package or something else that could enable the above? I'm relatively new to LaTeX, I can do the basics, but need to learn a bit more. I'd appreciate any advise on how to go about this.

Thanks in advance!

LewisE
  • 11
  • 1

1 Answers1

1

You could create your custom commands. Here I used expl syntax to convert some alphanumeric coordinate such as f4 to a node at the relevant coordinate in a TikZ coordinate system. For the actual game board, I made use of a \pic. But of course, there are a lot of other equally valid approaches to this:

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

enter image description here


Or maybe an implementation using the l3draw package:

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

enter image description here