The L A TEX havannah package
Marcin Ciura
∗2015-02-21
Abstract
Thehavannahpackage defines macros for typesetting diagrams of board positions in the games of Havannah and Hex.
a b c
d e f g
h i
j k l
m n o
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 9 10 11 12 13 14 14 13 12 11 10 9 8 15 15
1 2
3
4 5
6 7 8 9 10
11 12 13 14
15 16 17
18 19 20
21 22
23 24
25 26
27 28 29 30 31
32 33
34 35 36 37 38
39
40 41
42
43 44
45 46 47
48 49 50
51 52
53 54
55 56
57 58 59
60 61 62 63 64 65
66
67 68
69
70
71 72
73 74
75
76
77
A Havannah game between Maciej Celuch and Mirko Rahn played onhttp://www.littlegolem.netfrom 2009-07-05 to 2009-07-29
1 Usage
Put\usepackage{havannah}in the preamble of your document.
This package defines four environments, three commands, and several hooks that allow for the customization of its output.
TheHavannahBoardenvironment typesets a Havannah board. It accepts the HavannahBoard
following keys:
• board size: an integer from 1 to 13, default:10,
• coordinate style:little golem or classical, default:classical,
• hex height: a length, default:17.5pt,
• show coordinates: a Boolean, default:true,
• show hexes: a Boolean, default:true.
Sample effects of setting these keys are shown below.
a b c
1 2 3
a b c d e
1 2
3 4 5
a b c d e f g
1 2
3 4 5 6 7
\begin{HavannahBoard}[board size=2]
\end{HavannahBoard}
\begin{HavannahBoard}[board size=3]
\end{HavannahBoard}
\begin{HavannahBoard}[board size=4]
\end{HavannahBoard}
\begin{HavannahBoard}[board size=3,coordinate style=little golem]
\HGame{d3,c2}
\end{HavannahBoard}
\begin{HavannahBoard}[board size=3,coordinate style=classical]
\HGame{d3,c2}
\end{HavannahBoard}
a b
c d
e
1 1
2 2
3 3
4 4
5 5
1
2
a b c d e
1 2
3 4 5 1
2
\begin{HavannahBoard}[board size=3,coordinate style=little golem]
\HGame{d3,c2}
\end{HavannahBoard}
\begin{HavannahBoard}[
board size=3,coordinate style=little golem,hex height=1cm]
\HGame{d3,c2}
\end{HavannahBoard}
a b
c d
e
1 1
2 2
3 3
4 4
5 5
1
2 a
b c
d e
1 1
2 2
3 3
4 4
5 5
1
2
\begin{HavannahBoard}[board size=3,coordinate style=little golem]
\HGame{d3,c2}
\end{HavannahBoard}
\begin{HavannahBoard}[
board size=3,coordinate style=little golem,show coordinates=false]
\HGame{d3,c2}
\end{HavannahBoard}
a b
c d
e
1 1
2 2
3 3
4 4
5 5
1
2
1
2
\begin{HavannahBoard}[board size=3,coordinate style=little golem]
\HGame{d3,c2}
\end{HavannahBoard}
\begin{HavannahBoard}[
board size=3,coordinate style=little golem,show hexes=false]
\HGame{d3,c2}
\end{HavannahBoard}
a b
c d
e
1 1
2 2
3 3
4 4
5 5
1
2
a b
c d
e
1 1
2 2
3 3
4 4
5 5
1
2
The HexBoardenvironment typesets a Hex board. It accepts the following HexBoard
keys:
• board size: an integer from 1 to 26, default: 11,
• top left color: eitherwhiteorblack, default:black,
• hex height: a length, default:17.5pt,
• show coordinates: a Boolean, default:true,
• show hexes: a Boolean, default:true.
Sample effects of setting these keys are show below.
a
a b
b 1
1
2
2
a
a b
b c
1 c
1
2
2
3
3
a
a b
b c
c d
d 1
1
2
2
3
3
4
4
\begin{HexBoard}[board size=2]
\end{HexBoard}
\begin{HexBoard}[board size=3]
\end{HexBoard}
\begin{HexBoard}[board size=4]
\end{HexBoard}
a
a b
b c
1 c
1
2
2
3
3
1 2
a
a b
b c
1 c
1
2
2
3
3
1 2
\begin{HexBoard}[board size=3]
\HGame{a3,c2}
\end{HexBoard}
\begin{HexBoard}[board size=3, top left color=white]
\HGame{a3,c2}
\end{HexBoard}
a
a b
b c
1 c
1
2
2
3
3
1 2
a
a b
b c
1 c
1
2
2
3
3
1 2
\begin{HexBoard}[board size=3]
\HGame{a3,c2}
\end{HexBoard}
\begin{HexBoard}[board size=3, hex height=1cm]
\HGame{a3,c2}
\end{HexBoard}
a
a b
b c
1 c
1
2
2
3
3
1 2
1 2
\begin{HexBoard}[board size=3]
\HGame{a3,c2}
\end{HexBoard}
\begin{HexBoard}[board size=3, show coordinates=false]
\HGame{a3,c2}
\end{HexBoard}
a
a b
b c
1 c
1
2
2
3
3
1 2
a
a b
b c
1 c
1
2
2
3
3
1 2
\begin{HexBoard}[board size=3]
\HGame{a3,c2}
\end{HexBoard}
\begin{HexBoard}[board size=3, show hexes=false]
\HGame{a3,c2}
\end{HexBoard}
TheInnerHavannahBoardenvironment typesets a Havannah board inside a InnerHavannahBoard
tikzpicture environment. It is useful for drawing multiple diagrams in one picture. In addition to the keys ofHavannahBoard, it accepts the following keys:
• prefix: to be put before cell names.
• x: the x coordinate of the lower corner of the board.
• y: the y coordinate of the lower corner of the bowrd.
An example of its use is shown below.
\begin{tikzpicture}
\begin{InnerHavannahBoard}[board size=4,prefix=A,x=0,y=0]
\end{InnerHavannahBoard}
\begin{InnerHavannahBoard}[board size=4,prefix=B,x=7cm,y=0]
\end{InnerHavannahBoard}
\draw (Ad4)..controls (Ae7) and (Bg5)..(Bd4);
\HStoneGroup[color=white]{Ad4,Bd4}
\end{tikzpicture}
a b c d e f g
1 2
3 4 5 6 7
a b c d e f g
1 2
3 4 5 6 7
TheInnerHexBoardenvironment typesets a Hex board inside atikzpicture InnerHexBoard
environment. It accepts the same set of extra keys as InnerHavannahBoard:
prefix,x, andy.
You can use\renewcommandto redefine three hooks that change the look and HLetterCordinates
HCoordinateStyle HDrawHex
feel ofHavannahBoardorHexBoard. They are:
• \HLetterCoordinates: a comma-separated list, default:
{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z},
• \HCoordinateStyle: a one-argument macro, default:
{\sffamily#1},
• \HDrawHex: atikzcommand, default:
{\shadedraw[shading=radial,inner color=gray!30,
outer color=gray!70]}. Note that the default shading is a heavy task for some printers so you might want to use a simpler command instead, for instance\draw[fill=gray!35].
Sample results of redefining them are shown below.
\begin{HavannahBoard}[board size=3,coordinate style=little golem]
\HGame{d3,c2}
\end{HavannahBoard}
\renewcommand\HLetterCoordinates{1 ,2 ,3 ,4 ,5 }
\begin{HavannahBoard}[board size=3,coordinate style=little golem]
\HGame{4 3,3 2}
\end{HavannahBoard}
a b
c d
e
1 1
2 2
3 3
4 4
5 5
1
2
1 2
3 4
5
1 1
2 2
3 3
4 4
5 5
1
2
\begin{HavannahBoard}[board size=3,coordinate style=little golem]
\end{HavannahBoard}
\renewcommand\HCoordinateStyle[1]{\Large\bfseries#1}
\begin{HavannahBoard}[board size=3,coordinate style=little golem]
\end{HavannahBoard}
a b
c d
e
1 1
2 2
3 3
4 4
5 5
a b c d e
1 1
2 2
3 4 5 5 4 3
\begin{HavannahBoard}[board size=3,coordinate style=little golem]
\end{HavannahBoard}
\renewcommand\HDrawHex{\draw[
decorate,decoration={random steps,segment length=1pt}]}
\begin{HavannahBoard}[board size=3,coordinate style=little golem]
\end{HavannahBoard}
a b
c d
e
1 1
2 2
3 3
4 4
5 5
a b
c d
e
1 1
2 2
3 3
4 4
5 5
The\HGamemacro can only be used inside aHavannahBoardorHexBoarden- HGame
vironment. It accepts the following keys:
• first move label: a text, default:1,
• first player: eitherwhiteorblack, default:whiteinsideHavannahBoard andblackinsideHexBoard.
• numbered moves: a Boolean, default:true,
• relative stone size: a number, default:0.75. Their effects are shown below.
\begin{HavannahBoard}[board size=3,coordinate style=little golem]
\HGame{c3,e1,e3,c2,a1,d3,c5,d4,c4,b2,a3,d2,b4}
\end{HavannahBoard}
\begin{HavannahBoard}[board size=3,coordinate style=little golem]
\HGame[first move label=S]{
c3,e1,e3,c2,a1,d3,c5,d4,c4,b2,a3,d2,b4}
\end{HavannahBoard}
a b
c d
e
1 1
2 2
3 3
4 4
5 5
1 2 3
4 5
6 7
8 9
10 11
12 13
a b
c d
e
1 1
2 2
3 3
4 4
5 5
S 2 3
4 5
6 7
8 9
10 11
12 13
\begin{HavannahBoard}[board size=3,coordinate style=little golem]
\HGame{c3,e1,e3,c2,a1,d3,c5,d4,c4,b2,a3,d2,b4}
\end{HavannahBoard}
\begin{HavannahBoard}[board size=3,coordinate style=little golem]
\HGame[first player=black]{
c3,e1,e3,c2,a1,d3,c5,d4,c4,b2,a3,d2,b4}
\end{HavannahBoard}
a b
c d
e
1 1
2 2
3 3
4 4
5 5
1 2 3
4 5
6 7
8 9
10 11
12 13
a b
c d
e
1 1
2 2
3 3
4 4
5 5
1 2 3
4 5
6 7
8 9
10 11
12 13
\begin{HexBoard}[board size=3]
\HGame{b2,b1,c1,a3,b3}
\end{HexBoard}
\begin{HexBoard}[board size=3,top left color=white]
\HGame[first player=white]{
b2,b1,c1,a3,b3}
\end{HexBoard}
a
a b
b c
1 c
1
2
2
3
3 1
2 3
4 5
a
a b
b c
1 c
1
2
2
3
3 1
2 3
4 5
\begin{HavannahBoard}[board size=3,coordinate style=little golem]
\HGame{c3,e1,e3,c2,a1,d3,c5,d4,c4,b2,a3,d2,b4}
\end{HavannahBoard}
\begin{HavannahBoard}[board size=3,coordinate style=little golem]
\HGame[numbered moves=false]{
c3,e1,e3,c2,a1,d3,c5,d4,c4,b2,a3,d2,b4}
\end{HavannahBoard}
a b
c d
e
1 1
2 2
3 3
4 4
5 5
1 2 3
4 5
6 7
8 9
10 11
12 13
a b
c d
e
1 1
2 2
3 3
4 4
5 5
\begin{HavannahBoard}[board size=3,coordinate style=little golem]
\HGame{c3,e1,e3,c2,a1,d3,c5,d4,c4,b2,a3,d2,b4}
\end{HavannahBoard}
\begin{HavannahBoard}[board size=3,coordinate style=little golem]
\HGame[relative stone size=0.9]{
c3,e1,e3,c2,a1,d3,c5,d4,c4,b2,a3,d2,b4}
\end{HavannahBoard}
a b
c d
e
1 1
2 2
3 3
4 4
5 5
1 2 3
4 5
6 7
8 9
10 11
12 13
a b
c d
e
1 1
2 2
3 3
4 4
5 5
1 2 3
4 5
6 7
8 9
10 11
12 13
The \HStoneGroup macro can only be used inside a HavannahBoard or HStoneGroup
HexBoardenvironment. It puts a group of stones of the same color on the board.
It accepts the following keys:
• color: white,black, ortransparent, there is no default – the value must be specified,
• label: a text, default: empty string,
• relative stone size: a number, default:0.75.
The effects ofcolorandlabelare shown below. The effect ofrelative stone size is the same as for\HGameand will not be shown.
\begin{HavannahBoard}[board size=6,coordinate style=little golem]
\HStoneGroup[color=black,label=$\mathcal F$]{
a5,b5,c5,d6,d7,d8,c8,e8,f8,g8,h7,i7,j7}
\HStoneGroup[color=white,label=$\mathcal B$]{
a1,b2,c3,d3,e3,e2,f2,f1}
\HStoneGroup[color=transparent,label=$\mathcal R$]{
h6,g6,g5,g4,h3,i2,j2,j3,j4,i5}
\end{HavannahBoard}
a b
c d
e f
g h i
j k
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 10
11 11
F F
F F F F F
F F F
F F F
B B B B
B B
B B
R R R R
R R R
R R R
There are five hooks that can be redefined via\renewcommandto change the HMoveNumberStyle
HWhiteStone HBlackStone HTransparentStone HBeforeOddMove HBeforeEvenMove HBeforeStone
appearance of\HGameand\HStoneGroup. They are:
• \HMoveNumberStyle: a one-argument macro, influences\HGame, default:
{\sffamily#1},
• \HWhiteStone: atikzcommand, influences\HGameand\HStoneGroup, de- fault:
{\node[circle,draw,inner sep=0.6pt,fill=white, minimum size=\HStoneDiameter]},
• \HBlackStone: atikzcommand, influences\HGameand\HStoneGroup, de- fault:
{\node[circle,draw,inner sep=0.6pt,fill=black,text=white minimum size=\HStoneDiameter]},
• \HTransparentStone: atikzcommand, influences\HStoneGroup, default:
{\node[circle,draw,inner sep=0.6pt,
minimum size=\HStoneDiameter]},
• \HBeforeOddMove, \BeforeEvenMove: macros expanded before placing stones, for example\pause when animating games in beamer, influence
\HGame, default:{},
• \HBeforeStone: a macro expanded before placing stones, influences\HStoneGroup, default:{}.
Sample effects of redefining some of them are shown below.
\begin{HavannahBoard}[board size=3,coordinate style=little golem]
\HGame{c3,e1,e3,c2,a1,d3,c5,d4,c4,b2,a3,d2,b4}
\end{HavannahBoard}
\renewcommand\HMoveNumberStyle[1]{\footnotesize\romannumeral#1}
\begin{HavannahBoard}[board size=3,coordinate style=little golem]
\HGame{c3,e1,e3,c2,a1,d3,c5,d4,c4,b2,a3,d2,b4}
\end{HavannahBoard}
a b
c d
e
1 1
2 2
3 3
4 4
5 5
1 2 3
4 5
6 7
8 9
10 11
12 13
a b
c d
e
1 1
2 2
3 3
4 4
5 5
i ii iii
v iv
vi vii
viii ix x xi
xii xiii
\begin{HavannahBoard}[board size=3,coordinate style=little golem]
\HGame{c3,e1,e3,c2,a1,d3,c5,d4,c4,b2,a3,d2,b4}
\end{HavannahBoard}
\renewcommand\HDrawHex{\draw}
\renewcommand\HWhiteStone{\node[
circle,shading=ball,ball color=white,inner sep=0.6pt, minimum size=\HStoneDiameter]}
\renewcommand\HBlackStone{\node[
circle,shading=ball,ball color=black,inner sep=0.6pt,text=white, minimum size=\HStoneDiameter]}
\begin{HavannahBoard}[board size=3]
\HGame{c3,e1,e3,c2,a1,d3,c5,d4,c4,b2,a3,d2,b4}
\end{HavannahBoard}
a b
c d
e
1 1
2 2
3 3
4 4
5 5
1 2 3
5 4
6 7
8 9
10 11
12 13
a b c d e
1 2
3 4 5 1
2 3
4
5 6
7 8
9
10 11
12 13
The\HHexGroupmacro can only be used inside aHavannahBoardorHexBoard HHexGroup
environment. It puts a group of hexes on the board, which presumably is typeset with show hexes=false. It is recommended to use it inside theHexBoardenvi- ronment due to the simplicity of its coordinate system. It accepts the following keys:
• label: a text, default: empty string, An example of its use is shown below.
\begin{HexBoard}[
board size=9,show coordinates=false,show hexes=false]
\HHexGroup
{a1,b1,c1,d1,e1,f1,g1,h1,a2,b2,c2,e2,f2,g2,a3,b3,c3,d3,e3,f3,b4,c4,d4}
\draw [dotted] (a1)--(a2); \draw [dotted] (b1)--(a2);
\draw [dotted] (c1)--(c2); \draw [dotted] (d1)--(c2);
\draw [dotted] (e1)--(e2); \draw [dotted] (f1)--(e2);
\draw [dotted] (g1)--(g2); \draw [dotted] (h1)--(g2);
\draw [dotted] (c2)--(b3); \draw [dotted] (e2)--(e3);
\draw [dotted] (a2)..controls(a3)..(b3);
\draw [dotted] (a2)..controls(b2)..(b3);
\draw [dotted] (g2)..controls(f3)..(e3);
\draw [dotted] (g2)..controls(f2)..(e3);
\draw [dotted] (b3)..controls(b4)..(c4);
\draw [dotted] (b3)..controls(c3)..(c4);
\draw [dotted] (e3)..controls(d4)..(c4);
\draw [dotted] (e3)..controls(d3)..(c4);
\HStoneGroup[color=black]{a,b,c,d,e,f,g,h,i,c4}
\end{HexBoard}
2 Implementation
1h∗packagei
2\NeedsTeXFormat{LaTeX2e}
3\ProvidesPackage{havannah}[2010/06/06 LaTeX havannah package]
4\RequirePackage{tikz}
The naming schema used in thehavannahpackage is\HFooBarfor redefinable hooks, and\h@foo@barfor internal macros.
Start with defining default expansions for the hooks.
5\newcommand\HLetterCoordinates{%
6 a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z}
7\newcommand\HCoordinateStyle[1]{\sffamily#1}
8\newcommand\HMoveNumberStyle[1]{\sffamily#1}
9\newcommand\HDrawHex{\shadedraw[
10 shading=radial,inner color=gray!30,outer color=gray!70]}
11\newcommand\HWhiteStone{\node[
12 circle,draw=black,inner sep=0.6pt,fill=white,
13 minimum size=\HStoneDiameter]}
14\newcommand\HBlackStone{\node[
15 circle,draw=black,inner sep=0.6pt,fill=black,text=white,
16 minimum size=\HStoneDiameter]}
17\newcommand\HTransparentStone{\node[
18 circle,draw=black,inner sep=0.6pt,
19 minimum size=\HStoneDiameter]}
20\newcommand\HBeforeOddMove{}
21\newcommand\HBeforeEvenMove{}
22\newcommand\HBeforeStone{}
The\h@draw@hexmacro draws a hexagonal cell. The cell is3\h@one@third@hex@wd wide and2\h@half@hex@hthigh. It has two horizontal and four slanted edges.
The\h@draw@hexmacro takes one argument: the coordinates of the center of the cell. It uses the\HDrawHexhook to style the cell.
23\newcommand{\h@draw@hex}[1]{%
24 \HDrawHex (#1)
25 ++(-2\h@one@third@hex@wd,0)--
26 ++(\h@one@third@hex@wd,-\h@half@hex@ht)--
27 ++(2\h@one@third@hex@wd,0)--
28 ++(\h@one@third@hex@wd,\h@half@hex@ht)--
29 ++(-\h@one@third@hex@wd,\h@half@hex@ht)--
30 ++(-2\h@one@third@hex@wd,0)--
31 cycle;
32}
Definepgfkeyspaths.
33\newif\ifh@numbered@moves
34\newif\ifh@show@coordinates
35\newif\ifh@show@hexes
36\pgfkeys{%
37 /h@havannah@board/.cd,
38 board size/.store in=\hv@board@size,
39 coordinate style/.is choice,
40 coordinate style/classical/.code={%
41 \def\h@draw@board{\h@draw@classical@board}},
42 coordinate style/little golem/.code={%
43 \def\h@draw@board{\h@draw@little@golem@board}},
44 hex height/.store in=\h@hex@height,
45 prefix/.store in=\h@prefix,
46 show coordinates/.is if=h@show@coordinates,
47 show hexes/.is if=h@show@hexes,
48 x/.store in=\h@xx,
49 y/.store in=\h@yy,
50 board size=10,
51 coordinate style=classical,
52 hex height=17.5pt,
53 prefix=,
54 show coordinates=true,
55 show hexes=true,
56 x=0,
57 y=0,
58%
59 /h@hex@board/.cd,
60 top left color/.is choice,
61 top left color/white/.code={%
62 \def\h@top@left@color{\HWhiteStone}%
63 \def\h@bottom@left@color{\HBlackStone}%
64 },
65 top left color/black/.code={%
66 \def\h@top@left@color{\HBlackStone}%
67 \def\h@bottom@left@color{\HWhiteStone}%
68 },
69 board size/.store in=\hx@board@size,
70 hex height/.store in=\h@hex@height,
71 prefix/.store in=\h@prefix,
72 relative stone size/.store in=\h@relative@stone@size,
73 show coordinates/.is if=h@show@coordinates,
74 show hexes/.is if=h@show@hexes,
75 x/.store in=\h@xx,
76 y/.store in=\h@yy,
77 top left color=black,
78 board size=11,
79 hex height=17.5pt,
80 relative stone size=0.75,
81 show coordinates=true,
82 show hexes=true,
83%
84 /h@game/.cd,
85 first move label/.store in=\h@first@move@label,
86 first player/.is choice,
87 first player/white/.code={%
88 \def\h@odd@player{\HWhiteStone}%
89 \def\h@even@player{\HBlackStone}%
90 },
91 first player/black/.code={%
92 \def\h@odd@player{\HBlackStone}%
93 \def\h@even@player{\HWhiteStone}%
94 },
95 numbered moves/.is if=h@numbered@moves,
96 relative stone size/.store in=\h@relative@stone@size,
97 first move label=1,
98 numbered moves=true,
99 relative stone size=0.75,
100%
101 /h@stone@group/.cd,
102 color/.is choice,
103 color/white/.code={\def\h@player{\HWhiteStone}},
104 color/black/.code={\def\h@player{\HBlackStone}},
105 color/transparent/.code={\def\h@player{\HTransparentStone}},
106 label/.store in=\h@label,
107 relative stone size/.store in=\h@relative@stone@size,
108 relative stone size=0.75,
109%
110 /h@hex@group/.cd,
111 label/.store in=\h@label,
112}
TheInnerHavannahBoardenvironment first sets the values of\hv@board@size,
\h@draw@board,\h@hex@height, and\h@show@coordinatestrueor\h@show@coordinatesfalse. Then it computes\h@half@hex@ht,\h@one@third@hex@wd, and\h@board@diagonal,
and executes\h@draw@board.
113\newcount\h@board@diagonal
114\newdimen\h@half@hex@ht
115\newdimen\h@one@third@hex@wd
116\newenvironment{InnerHavannahBoard}[1][]{%
117 \def\h@odd@player{\HWhiteStone}%
118 \def\h@even@player{\HBlackStone}%
119 \pgfqkeys{/h@havannah@board}{#1}%
120 \setlength\h@half@hex@ht{\h@hex@height}%
121 \divide\h@half@hex@ht by 2
122 \setlength\h@one@third@hex@wd{0.577350269\h@half@hex@ht}%
123 \h@board@diagonal=\hv@board@size
124 \multiply\h@board@diagonal by 2
125 \advance\h@board@diagonal by -1
126 \h@draw@board
127}
There is nothing to be done at the end ofInnerHavannahBoard.
128{}
The HavannahBoard environment just wraps InnerHavannahBoard inside a tikzpicture.
129\newenvironment{HavannahBoard}[1][]{%
130 \begin{tikzpicture}
131 \begin{InnerHavannahBoard}[#1,prefix=,x=0,y=0]
132}
Finally,HavannahBoardcloses theInnerHavannahBoardandtikzpictureenvi- ronments.
133{ \end{InnerHavannahBoard}
134 \end{tikzpicture}
135}
The \h@draw@classical@board and \h@draw@little@golem@board macros differ enough that a common routine would be of little help. They both draw a rhombus of hexes with two corners cut. The edges of adjacent hexes are drawn twice.
The following counters are shared by both macros.
136\newcount\h@l
137\newcount\h@a@corner
138\newcount\h@b@corner
The\h@draw@classical@boardmacro is a bit simpler than the other one.
139\newcommand\h@draw@classical@board{%
140 \h@l=0
141 \h@b@corner=\hv@board@size
142 \foreach \h@letter in \HLetterCoordinates {%
143 \global\advance\h@l by 1
144 \ifnum \h@l > \h@board@diagonal
145 \breakforeach
146 \else
147 \global\advance\h@b@corner by 1
148 \h@a@corner=\hv@board@size
149 \foreach \h@n in {1,...,\h@board@diagonal} {%
150 \global\advance\h@a@corner by 1
151 \ifnum \h@l < \h@a@corner
152 \ifnum \h@n < \h@b@corner
153 \coordinate (\h@prefix\h@letter\h@n) at
154 (\h@xx+3*\h@n\h@one@third@hex@wd-3*\h@l\h@one@third@hex@wd,
155 \h@yy+\h@n\h@half@hex@ht+\h@l\h@half@hex@ht);
156 \ifh@show@hexes
157 \h@draw@hex{\h@prefix\h@letter\h@n}%
158 \fi
159 \fi
160 \fi
161 }%
162 \ifh@show@coordinates
163 \ifnum \h@l < \hv@board@size\relax
164 \node at
165 (\h@xx-3*\h@l\h@one@third@hex@wd,\h@yy+\h@l\h@half@hex@ht)
166 {\HCoordinateStyle{\h@letter}};
167 \else
168 \node at
169 (\h@xx-3*\hv@board@size\h@one@third@hex@wd,
170 \h@yy+2*\h@l\h@half@hex@ht-\hv@board@size\h@half@hex@ht)
171 {\HCoordinateStyle{\h@letter}};
172 \fi
173 \fi
174 \fi
175 }%
176 \ifh@show@coordinates
177 \foreach \h@n in {1,...,\h@board@diagonal} {%
178 \ifnum \h@n < \hv@board@size
179 \node at
180 (\h@xx+3*\h@n\h@one@third@hex@wd,\h@yy+\h@n\h@half@hex@ht)
181 {\HCoordinateStyle{\h@n}};
182 \else
183 \node at
184 (\h@xx+3*\hv@board@size\h@one@third@hex@wd,
185 \h@yy+2*\h@n\h@half@hex@ht-\hv@board@size\h@half@hex@ht)
186 {\HCoordinateStyle{\h@n}};
187 \fi
188 }%
189 \fi
190}
The \h@draw@little@golem@board macro is more complicated since the numbered rows in Little Golem change direction in the middle.
191\newcommand\h@draw@little@golem@board{%
192 \h@a@corner=\hv@board@size
193 \h@b@corner=\hv@board@size
194 \multiply\h@b@corner by 3
195 \h@l=0
196 \foreach \h@letter in \HLetterCoordinates {%
197 \global\advance\h@l by 1
198 \ifnum \h@l > \h@board@diagonal
199 \breakforeach
200 \else
201 \global\advance\h@a@corner by 1
202 \global\advance\h@b@corner by -1
203 \foreach \h@n in {1,...,\h@board@diagonal} {%
204 \ifnum \h@n < \h@a@corner
205 \ifnum \h@n < \h@b@corner
206 \ifnum \h@l < \hv@board@size
207 \coordinate (\h@prefix\h@letter\h@n) at
208 (\h@xx+3*\h@l\h@one@third@hex@wd,
209 \h@yy+2*\hv@board@size\h@half@hex@ht+
210 2*\h@n\h@half@hex@ht-\h@l\h@half@hex@ht);
211 \ifh@show@hexes
212 \h@draw@hex{\h@prefix\h@letter\h@n}%
213 \fi
214 \else
215 \coordinate (\h@prefix\h@letter\h@n) at
216 (\h@xx+3*\h@l\h@one@third@hex@wd,
217 \h@yy+2*\h@n\h@half@hex@ht+\h@l\h@half@hex@ht);
218 \ifh@show@hexes
219 \h@draw@hex{\h@prefix\h@letter\h@n}%
220 \fi
221 \fi
222 \fi
223 \fi
224 }
225 \ifh@show@coordinates
226 \ifnum \h@l < \hv@board@size
227 \node at
228 (\h@xx+3*\h@l\h@one@third@hex@wd,
229 \h@yy+2*\hv@board@size\h@half@hex@ht-\h@l\h@half@hex@ht)
230 {\HCoordinateStyle{\h@letter}};
231 \else
232 \node at
233 (\h@xx+3*\h@l\h@one@third@hex@wd,\h@yy+\h@l\h@half@hex@ht)
234 {\HCoordinateStyle{\h@letter}};
235 \fi
236 \fi
237 \fi
238 }%
239 \ifh@show@coordinates
240 \foreach \h@n in {1,...,\h@board@diagonal} {%
241 \ifnum \h@n < \hv@board@size
242 \node at
243 (\h@xx,
244 \h@yy+2*\h@n\h@half@hex@ht+
245 \h@board@diagonal\h@half@hex@ht+\h@half@hex@ht)
246 {\HCoordinateStyle{\h@n}};
247 \node at
248 (\h@xx+3*\h@board@diagonal\h@one@third@hex@wd+
249 3*\h@one@third@hex@wd,
250 \h@yy+2*\h@n\h@half@hex@ht+
251 \h@board@diagonal\h@half@hex@ht+\h@half@hex@ht)
252 {\HCoordinateStyle{\h@n}};
253 \else
254 \node at
255 (\h@xx+3*\h@n\h@one@third@hex@wd-
256 3*\hv@board@size\h@one@third@hex@wd,
257 \h@yy+\h@n\h@half@hex@ht+3*\hv@board@size\h@half@hex@ht)
258 {\HCoordinateStyle{\h@n}};
259 \node at
260 (\h@xx-3*\h@n\h@one@third@hex@wd+
261 9*\hv@board@size\h@one@third@hex@wd,
262 \h@yy+\h@n\h@half@hex@ht+3*\hv@board@size\h@half@hex@ht)
263 {\HCoordinateStyle{\h@n}};
264 \fi
265 }%
266 \fi
267}
TheInnerHexBoardenvironment is similar toInnerHavannahBoardbut sim- pler, as it typesets an entire cross-product of coordinates, without cutting the corners.
268\newenvironment{InnerHexBoard}[1][]{%
269 \def\h@odd@player{\HBlackStone}%
270 \def\h@even@player{\HWhiteStone}%
271 \pgfqkeys{/h@hex@board}{#1}%
272 \tracingcommands=1
273 \setlength\h@half@hex@ht{\h@hex@height}%
274 \divide\h@half@hex@ht by 2
275 \setlength\h@one@third@hex@wd{0.577350269\h@half@hex@ht}%
276 \HStoneDiameter=\h@relative@stone@size\h@half@hex@ht
277 \multiply\HStoneDiameter by 2
278 \h@l=0
279 \foreach \h@letter in \HLetterCoordinates {%
280 \global\advance\h@l by 1
281 \ifnum \h@l > \hx@board@size
282 \breakforeach
283 \else
284 \foreach \h@n in {1,...,\hx@board@size} {%
285 \coordinate (\h@letter\h@n) at
286 (3*\h@l\h@one@third@hex@wd+3*\h@n\h@one@third@hex@wd,
287 \h@l\h@half@hex@ht-\h@n\h@half@hex@ht);
288 \ifh@show@hexes
289 \h@draw@hex{\h@letter\h@n}%
290 \fi
291 }%
292 \coordinate (\h@letter) at
293 (3*\h@l\h@one@third@hex@wd,
294 2\h@half@hex@ht-2\h@half@hex@ht+\h@l\h@half@hex@ht);
295 \coordinate (-\h@letter) at
296 (3*\hx@board@size\h@one@third@hex@wd+
297 3\h@one@third@hex@wd+3*\h@l\h@one@third@hex@wd,
298 -\hx@board@size\h@half@hex@ht-
299 \h@half@hex@ht+\h@l\h@half@hex@ht);
300 \ifh@show@coordinates
301 \h@top@left@color at (\h@letter)
302 {\HCoordinateStyle{\h@letter}};
303 \h@top@left@color at (-\h@letter)
304 {\HCoordinateStyle{\h@letter}};
305 \fi
306 \fi
307 }%
308 \ifh@show@coordinates
309 \foreach \h@n in {1,...,\hx@board@size} {%
310 \coordinate (\h@n) at
311 (3*\h@n\h@one@third@hex@wd,-1*\h@n\h@half@hex@ht);
312 \coordinate (-\h@n) at
313 (3*\hx@board@size\h@one@third@hex@wd+3\h@one@third@hex@wd+
314 3*\h@n\h@one@third@hex@wd,
315 \hx@board@size\h@half@hex@ht+\h@half@hex@ht-\h@n\h@half@hex@ht);
316 \h@bottom@left@color at (\h@n)
317 {\HCoordinateStyle{\h@n}};
318 \h@bottom@left@color at (-\h@n)
319 {\HCoordinateStyle{\h@n}};
320 }%
321 \fi
322}
323{}
TheHexBoardenvironment just wrapsInnerHexBoardinside atikzpicture.
324\newenvironment{HexBoard}[1][]{%
325 \begin{tikzpicture}
326 \begin{InnerHexBoard}[#1,prefix=,x=0,y=0]
327}
Finally,HexBoardcloses theInnerHexBoardandtikzpictureenvironments.
328{ \end{InnerHexBoard}
329 \end{tikzpicture}
330}
The\HGamemacro
331\newcount\h@move@number
332\newdimen\HStoneDiameter
333\newcommand\HGame[2][]{%
334 \pgfqkeys{/h@game}{#1}%
335 \HStoneDiameter=\h@relative@stone@size\h@half@hex@ht
336 \multiply\HStoneDiameter by 2
337 \h@move@number=0
338 \ifh@numbered@moves
339 \def\h@label{\HMoveNumberStyle{\h@first@move@label}%
340 \global\def\h@label{\HMoveNumberStyle{\the\h@move@number}}}
341 \else
342 \def\h@label{}
343 \fi
344 \foreach \h@coord in {#2} {%
345 \global\advance\h@move@number by 1
346 \ifodd\h@move@number
347 \HBeforeOddMove
348 \h@odd@player at (\h@coord) {\h@label};
349 \else
350 \HBeforeEvenMove
351 \h@even@player at (\h@coord) {\h@label};
352 \fi
353 }
354}
The\HStoneGroup
355\newcommand\HStoneGroup[2][]{%
356 \let\h@player\empty
357 \let\h@label\empty
358 \pgfqkeys{/h@stone@group}{#1}%
359 \ifx\h@player\empty
360 \errmessage{No color specified for HStoneGroup}
361 \fi
362 \HStoneDiameter=\h@relative@stone@size\h@half@hex@ht
363 \multiply\HStoneDiameter by 2
364 \foreach \h@coord in {#2} {%
365 \HBeforeStone
366 \h@player at (\h@coord) {\h@label};
367 }%
368}
The\HHexGroup
369\newcommand\HHexGroup[2][]{%
370 \let\h@label\empty
371 \pgfqkeys{/h@hex@group}{#1}%
372 \foreach \h@coord in {#2} {%
373 \node at (\h@coord) {\h@label};
374 \h@draw@hex{\h@coord}%
375 }%
376}
That’s all, folks.
377h/packagei