% \iffalse %<*driver> \ProvidesFile{havannah.dtx} \documentclass{ltxdoc} \usepackage{havannah} \usepackage[scaled=0.92]{helvet} \usepackage{lstdoc} \usepackage{mathpazo} \usetikzlibrary{decorations.pathmorphing} \EnableCrossrefs \CodelineIndex \RecordChanges \begin{document} \DocInput{havannah.dtx} \PrintChanges \PrintIndex \end{document} % % \fi % % \newcommand\package{\texttt} % % \title{The \LaTeX\ \package{havannah} package} % \author{Marcin Ciura\thanks{\texttt{mciura@gmail.com}}} % \date{2015-02-21} % \maketitle % % \begin{abstract} % The \package{havannah} package defines macros for typesetting % diagrams of board positions in the games of Havannah and Hex. % \end{abstract} % % \begin{center} % \begin{HavannahBoard}[board size=8,coordinate style=little golem] % \HGame{ % i12,h13,l7,m4,h12,g12,g11,f11,f10,e10,i13,h14,i14,h15,e9, % d9,a8,d8,e8,d7,d4,e6,f5,c4,h10,e7,c3,b3,b2,a2,a1,f8,g7, % h9,i7,i9,i10,g9,k9,j7,j11,g10,j9,h11,j8,i8,k7,l8,k10,i11, % k6,j6,l4,d5,m3,c6,c5,b6,a4,b7,c8,b8,c9,b9,c10,j5,n1,j4, % l5,j3,m5,m6,n3,n4,o2,j2,o1} % \end{HavannahBoard} % % A Havannah game between Maciej Celuch and Mirko Rahn\\ % played on \texttt{http://www.littlegolem.net} from 2009-07-05 to 2009-07-29 % \end{center} % % \section{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. % % \DescribeEnv{HavannahBoard} % The |HavannahBoard| environment typesets a Havannah board. % It accepts the following keys: % \begin{itemize} % \item |board size|: an integer from 1 to 13, default: |10|, % \item |coordinate style|: |little golem |or| classical|, % default: |classical|, % \item |hex height|: a length, default: |17.5pt|, % \item |show coordinates|: a Boolean, default: |true|, % \item |show hexes|: a Boolean, default: |true|. % \end{itemize} % Sample effects of setting these keys are shown below. % % \vbox{\begin{lstsample}{}{} % \begin{HavannahBoard}[board size=2] % \end{HavannahBoard} % % \begin{HavannahBoard}[board size=3] % \end{HavannahBoard} % % \begin{HavannahBoard}[board size=4] % \end{HavannahBoard} % \end{lstsample}} % % \noindent\hrulefill % % \vbox{\begin{lstsample}{}{} % \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} % \end{lstsample}} % % \noindent\hrulefill % % \vbox{\begin{lstsample}{}{} % \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} % \end{lstsample}} % % \noindent\hrulefill % % \vbox{\begin{lstsample}{}{} % \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} % \end{lstsample}} % % \noindent\hrulefill % % \vbox{\begin{lstsample}{}{} % \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} % \end{lstsample}} % % \noindent\hrulefill % % \DescribeEnv{HexBoard} % The |HexBoard| environment typesets a Hex board. % It accepts the following keys: % \begin{itemize} % \item |board size|: an integer from 1 to 26, default: 11, % \item |top left color|: either |white| or |black|, % default: |black|, % \item |hex height|: a length, default: |17.5pt|, % \item |show coordinates|: a Boolean, default: |true|, % \item |show hexes|: a Boolean, default: |true|. % \end{itemize} % Sample effects of setting these keys are show below. % % \vbox{\begin{lstsample}{}{} % \begin{HexBoard}[board size=2] % \end{HexBoard} % % \begin{HexBoard}[board size=3] % \end{HexBoard} % % \begin{HexBoard}[board size=4] % \end{HexBoard} % \end{lstsample}} % % \noindent\hrulefill % % \vbox{\begin{lstsample}{}{} % \begin{HexBoard}[board size=3] % \HGame{a3,c2} % \end{HexBoard} % % \begin{HexBoard}[board size=3, % top left color=white] % \HGame{a3,c2} % \end{HexBoard} % \end{lstsample}} % % \noindent\hrulefill % % \vbox{\begin{lstsample}{}{} % \begin{HexBoard}[board size=3] % \HGame{a3,c2} % \end{HexBoard} % % \begin{HexBoard}[board size=3, % hex height=1cm] % \HGame{a3,c2} % \end{HexBoard} % \end{lstsample}} % % \noindent\hrulefill % % \vbox{\begin{lstsample}{}{} % \begin{HexBoard}[board size=3] % \HGame{a3,c2} % \end{HexBoard} % % \begin{HexBoard}[board size=3, % show coordinates=false] % \HGame{a3,c2} % \end{HexBoard} % \end{lstsample}} % % \noindent\hrulefill % % \vbox{\begin{lstsample}{}{} % \begin{HexBoard}[board size=3] % \HGame{a3,c2} % \end{HexBoard} % % \begin{HexBoard}[board size=3, % show hexes=false] % \HGame{a3,c2} % \end{HexBoard} % \end{lstsample}} % % \noindent\hrulefill % % \DescribeEnv{InnerHavannahBoard} % The |InnerHavannahBoard| environment typesets a Havannah board % inside a |tikzpicture| environment. It is useful for drawing % multiple diagrams in one picture. % In addition to the keys of |HavannahBoard|, it accepts the following keys: % \begin{itemize} % \item |prefix|: to be put before cell names. % \item |x|: the x coordinate of the lower corner of the board. % \item |y|: the y coordinate of the lower corner of the bowrd. % \end{itemize} % An example of its use is shown below. % % \vbox{\begin{lstsample}{}{} % \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} % \end{lstsample}} % % \DescribeEnv{InnerHexBoard} % The |InnerHexBoard| environment typesets a Hex board % inside a |tikzpicture| environment. It accepts the same set % of extra keys as |InnerHavannahBoard|: |prefix|, |x|, and |y|. % % \DescribeMacro{HLetterCordinates} % \DescribeMacro{HCoordinateStyle} % \DescribeMacro{HDrawHex} % You can use \cs{renewcommand} to redefine three hooks % that change the look and feel of |HavannahBoard| or |HexBoard|. % They are: % \begin{itemize} % \item \cs{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}|, % \item \cs{HCoordinateStyle}: a one-argument macro, default:\\ % |{\sffamily#1}|, % \item \cs{HDrawHex}: a |tikz| command, 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]|. % \end{itemize} % Sample results of redefining them are shown below. % % \vbox{\begin{lstsample}{}{} % \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} % \end{lstsample}} % % \noindent\hrulefill % % \vbox{\begin{lstsample}{}{} % \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} % \end{lstsample}} % % \noindent\hrulefill % % \vbox{\begin{lstsample}{}{} % \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} % \end{lstsample}} % % \noindent\hrulefill % % \DescribeMacro{HGame} % The \cs{HGame} macro can only be used inside a % |HavannahBoard| or |HexBoard| environment. % It accepts the following keys: % \begin{itemize} % \item |first move label|: a text, default: |1|, % \item |first player|: either |white| or |black|, default: % |white| inside |HavannahBoard| and |black| inside |HexBoard|. % \item |numbered moves|: a Boolean, default: |true|, % \item |relative stone size|: a number, default: |0.75|. % \end{itemize} % Their effects are shown below. % % \vbox{\begin{lstsample}{}{} % \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} % \end{lstsample}} % % \noindent\hrulefill % % \vbox{\begin{lstsample}{}{} % \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} % \end{lstsample}} % % \noindent\hrulefill % % \vbox{\begin{lstsample}{}{} % \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} % \end{lstsample}} % % \noindent\hrulefill % % \vbox{\begin{lstsample}{}{} % \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} % \end{lstsample}} % % \noindent\hrulefill % % \vbox{\begin{lstsample}{}{} % \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} % \end{lstsample}} % % \noindent\hrulefill % % \DescribeMacro{HStoneGroup} % The \cs{HStoneGroup} macro can only be used inside a % |HavannahBoard| or |HexBoard| environment. % It puts a group of stones of the same color on the board. % It accepts the following keys: % \begin{itemize} % \item |color|: |white|, |black|, or |transparent|, % there is no default -- the value must be specified, % \item |label|: a text, default: empty string, % \item |relative stone size|: a number, default: |0.75|. % \end{itemize} % The effects of |color| and |label| are shown below. % The effect of |relative stone size| is the same as for % \cs{HGame} and will not be shown. % % \vbox{\begin{lstsample}{}{} % \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} % \end{lstsample}} % % \DescribeMacro{HMoveNumberStyle} % \DescribeMacro{HWhiteStone} % \DescribeMacro{HBlackStone} % \DescribeMacro{HTransparentStone} % \DescribeMacro{HBeforeOddMove} % \DescribeMacro{HBeforeEvenMove} % \DescribeMacro{HBeforeStone} % There are five hooks that can be redefined via \cs{renewcommand} % to change the appearance of \cs{HGame} and \cs{HStoneGroup}. % They are: % \begin{itemize} % \item \cs{HMoveNumberStyle}: a one-argument macro, % influences \cs{HGame}, default:\\ % |{\sffamily#1}|, % \item \cs{HWhiteStone}: a |tikz| command, % influences \cs{HGame} and \cs{HStoneGroup}, default:\\ % |{\node[circle,draw,inner sep=0.6pt,fill=white,|\\ % |minimum size=\HStoneDiameter]}|, % \item \cs{HBlackStone}: a |tikz| command, % influences \cs{HGame} and \cs{HStoneGroup}, default:\\ % |{\node[circle,draw,inner sep=0.6pt,fill=black,text=white|\\ % |minimum size=\HStoneDiameter]}|, % \item \cs{HTransparentStone}: a |tikz| command, % influences \cs{HStoneGroup}, default:\\ % |{\node[circle,draw,inner sep=0.6pt,|\\ % |minimum size=\HStoneDiameter]}|, % \item \cs{HBeforeOddMove}, \cs{BeforeEvenMove}: macros expanded % before placing stones, for example \cs{pause} when animating % games in |beamer|, influence \cs{HGame}, default: |{}|, % \item \cs{HBeforeStone}: a macro expanded before placing stones, % influences \cs{HStoneGroup}, default: |{}|. % \end{itemize} % Sample effects of redefining some of them are shown below. % % \vbox{\begin{lstsample}{}{} % \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} % \end{lstsample}} % % \noindent\hrulefill % % \vbox{\begin{lstsample}{}{} % \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} % \end{lstsample}} % % \noindent\hrulefill % % \DescribeMacro{HHexGroup} % The \cs{HHexGroup} macro can only be used inside a % |HavannahBoard| or |HexBoard| 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 the |HexBoard| environment % due to the simplicity of its coordinate system. % It accepts the following keys: % \begin{itemize} % \item |label|: a text, default: empty string, % \end{itemize} % An example of its use is shown below. % % \vbox{\begin{lstsample}{}{} % \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} % \end{lstsample}} % % \StopEventually % % \section{Implementation} % \begin{macrocode} %<*package> \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{havannah}[2010/06/06 LaTeX havannah package] \RequirePackage{tikz} % \end{macrocode} % % The naming schema used in the \package{havannah} package % is \cs{HFooBar} for redefinable hooks, % and \cs{h@foo@bar} for internal macros. % % Start with defining default expansions for the hooks. % \begin{macrocode} \newcommand\HLetterCoordinates{% 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} \newcommand\HCoordinateStyle[1]{\sffamily#1} \newcommand\HMoveNumberStyle[1]{\sffamily#1} \newcommand\HDrawHex{\shadedraw[ shading=radial,inner color=gray!30,outer color=gray!70]} \newcommand\HWhiteStone{\node[ circle,draw=black,inner sep=0.6pt,fill=white, minimum size=\HStoneDiameter]} \newcommand\HBlackStone{\node[ circle,draw=black,inner sep=0.6pt,fill=black,text=white, minimum size=\HStoneDiameter]} \newcommand\HTransparentStone{\node[ circle,draw=black,inner sep=0.6pt, minimum size=\HStoneDiameter]} \newcommand\HBeforeOddMove{} \newcommand\HBeforeEvenMove{} \newcommand\HBeforeStone{} % \end{macrocode} % % The \cs{h@draw@hex} macro draws a hexagonal cell. % The cell is |3\h@one@third@hex@wd| wide and |2\h@half@hex@ht| high. % It has two horizontal and four slanted edges. % The \cs{h@draw@hex} macro takes one argument: % the coordinates of the center of the cell. % It uses the \cs{HDrawHex} hook to style the cell. % \begin{macrocode} \newcommand{\h@draw@hex}[1]{% \HDrawHex (#1) ++(-2\h@one@third@hex@wd,0)-- ++(\h@one@third@hex@wd,-\h@half@hex@ht)-- ++(2\h@one@third@hex@wd,0)-- ++(\h@one@third@hex@wd,\h@half@hex@ht)-- ++(-\h@one@third@hex@wd,\h@half@hex@ht)-- ++(-2\h@one@third@hex@wd,0)-- cycle; } % \end{macrocode} % % Define \package{pgfkeys} paths. % \begin{macrocode} \newif\ifh@numbered@moves \newif\ifh@show@coordinates \newif\ifh@show@hexes \pgfkeys{% /h@havannah@board/.cd, board size/.store in=\hv@board@size, coordinate style/.is choice, coordinate style/classical/.code={% \def\h@draw@board{\h@draw@classical@board}}, coordinate style/little golem/.code={% \def\h@draw@board{\h@draw@little@golem@board}}, hex height/.store in=\h@hex@height, prefix/.store in=\h@prefix, show coordinates/.is if=h@show@coordinates, show hexes/.is if=h@show@hexes, x/.store in=\h@xx, y/.store in=\h@yy, board size=10, coordinate style=classical, hex height=17.5pt, prefix=, show coordinates=true, show hexes=true, x=0, y=0, % /h@hex@board/.cd, top left color/.is choice, top left color/white/.code={% \def\h@top@left@color{\HWhiteStone}% \def\h@bottom@left@color{\HBlackStone}% }, top left color/black/.code={% \def\h@top@left@color{\HBlackStone}% \def\h@bottom@left@color{\HWhiteStone}% }, board size/.store in=\hx@board@size, hex height/.store in=\h@hex@height, prefix/.store in=\h@prefix, relative stone size/.store in=\h@relative@stone@size, show coordinates/.is if=h@show@coordinates, show hexes/.is if=h@show@hexes, x/.store in=\h@xx, y/.store in=\h@yy, top left color=black, board size=11, hex height=17.5pt, relative stone size=0.75, show coordinates=true, show hexes=true, % /h@game/.cd, first move label/.store in=\h@first@move@label, first player/.is choice, first player/white/.code={% \def\h@odd@player{\HWhiteStone}% \def\h@even@player{\HBlackStone}% }, first player/black/.code={% \def\h@odd@player{\HBlackStone}% \def\h@even@player{\HWhiteStone}% }, numbered moves/.is if=h@numbered@moves, relative stone size/.store in=\h@relative@stone@size, first move label=1, numbered moves=true, relative stone size=0.75, % /h@stone@group/.cd, color/.is choice, color/white/.code={\def\h@player{\HWhiteStone}}, color/black/.code={\def\h@player{\HBlackStone}}, color/transparent/.code={\def\h@player{\HTransparentStone}}, label/.store in=\h@label, relative stone size/.store in=\h@relative@stone@size, relative stone size=0.75, % /h@hex@group/.cd, label/.store in=\h@label, } % \end{macrocode} % % The |InnerHavannahBoard| environment first sets the values of % \cs{hv@board@size}, \cs{h@draw@board}, \cs{h@hex@height}, % and \cs{h@show@coordinatestrue} or \cs{h@show@coordinatesfalse}. % Then it computes \cs{h@half@hex@ht}, \cs{h@one@third@hex@wd}, % and \cs{h@board@diagonal}, and executes \cs{h@draw@board}. % \begin{macrocode} \newcount\h@board@diagonal \newdimen\h@half@hex@ht \newdimen\h@one@third@hex@wd \newenvironment{InnerHavannahBoard}[1][]{% \def\h@odd@player{\HWhiteStone}% \def\h@even@player{\HBlackStone}% \pgfqkeys{/h@havannah@board}{#1}% \setlength\h@half@hex@ht{\h@hex@height}% \divide\h@half@hex@ht by 2 \setlength\h@one@third@hex@wd{0.577350269\h@half@hex@ht}% \h@board@diagonal=\hv@board@size \multiply\h@board@diagonal by 2 \advance\h@board@diagonal by -1 \h@draw@board } % \end{macrocode} % % There is nothing to be done at the end of |InnerHavannahBoard|. % \begin{macrocode} {} % \end{macrocode} % % The |HavannahBoard| environment just wraps |InnerHavannahBoard| % inside a |tikzpicture|. % \begin{macrocode} \newenvironment{HavannahBoard}[1][]{% \begin{tikzpicture} \begin{InnerHavannahBoard}[#1,prefix=,x=0,y=0] } % \end{macrocode} % Finally, |HavannahBoard| closes the |InnerHavannahBoard| and % |tikzpicture| environments. % \begin{macrocode} { \end{InnerHavannahBoard} \end{tikzpicture} } % \end{macrocode} % % The \cs{h@draw@classical@board} and \cs{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. % \begin{macrocode} \newcount\h@l \newcount\h@a@corner \newcount\h@b@corner % \end{macrocode} % % The \cs{h@draw@classical@board} macro is a bit simpler % than the other one. % \begin{macrocode} \newcommand\h@draw@classical@board{% \h@l=0 \h@b@corner=\hv@board@size \foreach \h@letter in \HLetterCoordinates {% \global\advance\h@l by 1 \ifnum \h@l > \h@board@diagonal \breakforeach \else \global\advance\h@b@corner by 1 \h@a@corner=\hv@board@size \foreach \h@n in {1,...,\h@board@diagonal} {% \global\advance\h@a@corner by 1 \ifnum \h@l < \h@a@corner \ifnum \h@n < \h@b@corner \coordinate (\h@prefix\h@letter\h@n) at (\h@xx+3*\h@n\h@one@third@hex@wd-3*\h@l\h@one@third@hex@wd, \h@yy+\h@n\h@half@hex@ht+\h@l\h@half@hex@ht); \ifh@show@hexes \h@draw@hex{\h@prefix\h@letter\h@n}% \fi \fi \fi }% \ifh@show@coordinates \ifnum \h@l < \hv@board@size\relax \node at (\h@xx-3*\h@l\h@one@third@hex@wd,\h@yy+\h@l\h@half@hex@ht) {\HCoordinateStyle{\h@letter}}; \else \node at (\h@xx-3*\hv@board@size\h@one@third@hex@wd, \h@yy+2*\h@l\h@half@hex@ht-\hv@board@size\h@half@hex@ht) {\HCoordinateStyle{\h@letter}}; \fi \fi \fi }% \ifh@show@coordinates \foreach \h@n in {1,...,\h@board@diagonal} {% \ifnum \h@n < \hv@board@size \node at (\h@xx+3*\h@n\h@one@third@hex@wd,\h@yy+\h@n\h@half@hex@ht) {\HCoordinateStyle{\h@n}}; \else \node at (\h@xx+3*\hv@board@size\h@one@third@hex@wd, \h@yy+2*\h@n\h@half@hex@ht-\hv@board@size\h@half@hex@ht) {\HCoordinateStyle{\h@n}}; \fi }% \fi } % \end{macrocode} % % The \cs{h@draw@little@golem@board} macro is more complicated % since the numbered rows in Little Golem change direction in the middle. % \begin{macrocode} \newcommand\h@draw@little@golem@board{% \h@a@corner=\hv@board@size \h@b@corner=\hv@board@size \multiply\h@b@corner by 3 \h@l=0 \foreach \h@letter in \HLetterCoordinates {% \global\advance\h@l by 1 \ifnum \h@l > \h@board@diagonal \breakforeach \else \global\advance\h@a@corner by 1 \global\advance\h@b@corner by -1 \foreach \h@n in {1,...,\h@board@diagonal} {% \ifnum \h@n < \h@a@corner \ifnum \h@n < \h@b@corner \ifnum \h@l < \hv@board@size \coordinate (\h@prefix\h@letter\h@n) at (\h@xx+3*\h@l\h@one@third@hex@wd, \h@yy+2*\hv@board@size\h@half@hex@ht+ 2*\h@n\h@half@hex@ht-\h@l\h@half@hex@ht); \ifh@show@hexes \h@draw@hex{\h@prefix\h@letter\h@n}% \fi \else \coordinate (\h@prefix\h@letter\h@n) at (\h@xx+3*\h@l\h@one@third@hex@wd, \h@yy+2*\h@n\h@half@hex@ht+\h@l\h@half@hex@ht); \ifh@show@hexes \h@draw@hex{\h@prefix\h@letter\h@n}% \fi \fi \fi \fi } \ifh@show@coordinates \ifnum \h@l < \hv@board@size \node at (\h@xx+3*\h@l\h@one@third@hex@wd, \h@yy+2*\hv@board@size\h@half@hex@ht-\h@l\h@half@hex@ht) {\HCoordinateStyle{\h@letter}}; \else \node at (\h@xx+3*\h@l\h@one@third@hex@wd,\h@yy+\h@l\h@half@hex@ht) {\HCoordinateStyle{\h@letter}}; \fi \fi \fi }% \ifh@show@coordinates \foreach \h@n in {1,...,\h@board@diagonal} {% \ifnum \h@n < \hv@board@size \node at (\h@xx, \h@yy+2*\h@n\h@half@hex@ht+ \h@board@diagonal\h@half@hex@ht+\h@half@hex@ht) {\HCoordinateStyle{\h@n}}; \node at (\h@xx+3*\h@board@diagonal\h@one@third@hex@wd+ 3*\h@one@third@hex@wd, \h@yy+2*\h@n\h@half@hex@ht+ \h@board@diagonal\h@half@hex@ht+\h@half@hex@ht) {\HCoordinateStyle{\h@n}}; \else \node at (\h@xx+3*\h@n\h@one@third@hex@wd- 3*\hv@board@size\h@one@third@hex@wd, \h@yy+\h@n\h@half@hex@ht+3*\hv@board@size\h@half@hex@ht) {\HCoordinateStyle{\h@n}}; \node at (\h@xx-3*\h@n\h@one@third@hex@wd+ 9*\hv@board@size\h@one@third@hex@wd, \h@yy+\h@n\h@half@hex@ht+3*\hv@board@size\h@half@hex@ht) {\HCoordinateStyle{\h@n}}; \fi }% \fi } % \end{macrocode} % % The |InnerHexBoard| environment is similar to |InnerHavannahBoard| % but simpler, as it typesets an entire cross-product of coordinates, % without cutting the corners. % \begin{macrocode} \newenvironment{InnerHexBoard}[1][]{% \def\h@odd@player{\HBlackStone}% \def\h@even@player{\HWhiteStone}% \pgfqkeys{/h@hex@board}{#1}% \tracingcommands=1 \setlength\h@half@hex@ht{\h@hex@height}% \divide\h@half@hex@ht by 2 \setlength\h@one@third@hex@wd{0.577350269\h@half@hex@ht}% \HStoneDiameter=\h@relative@stone@size\h@half@hex@ht \multiply\HStoneDiameter by 2 \h@l=0 \foreach \h@letter in \HLetterCoordinates {% \global\advance\h@l by 1 \ifnum \h@l > \hx@board@size \breakforeach \else \foreach \h@n in {1,...,\hx@board@size} {% \coordinate (\h@letter\h@n) at (3*\h@l\h@one@third@hex@wd+3*\h@n\h@one@third@hex@wd, \h@l\h@half@hex@ht-\h@n\h@half@hex@ht); \ifh@show@hexes \h@draw@hex{\h@letter\h@n}% \fi }% \coordinate (\h@letter) at (3*\h@l\h@one@third@hex@wd, 2\h@half@hex@ht-2\h@half@hex@ht+\h@l\h@half@hex@ht); \coordinate (-\h@letter) at (3*\hx@board@size\h@one@third@hex@wd+ 3\h@one@third@hex@wd+3*\h@l\h@one@third@hex@wd, -\hx@board@size\h@half@hex@ht- \h@half@hex@ht+\h@l\h@half@hex@ht); \ifh@show@coordinates \h@top@left@color at (\h@letter) {\HCoordinateStyle{\h@letter}}; \h@top@left@color at (-\h@letter) {\HCoordinateStyle{\h@letter}}; \fi \fi }% \ifh@show@coordinates \foreach \h@n in {1,...,\hx@board@size} {% \coordinate (\h@n) at (3*\h@n\h@one@third@hex@wd,-1*\h@n\h@half@hex@ht); \coordinate (-\h@n) at (3*\hx@board@size\h@one@third@hex@wd+3\h@one@third@hex@wd+ 3*\h@n\h@one@third@hex@wd, \hx@board@size\h@half@hex@ht+\h@half@hex@ht-\h@n\h@half@hex@ht); \h@bottom@left@color at (\h@n) {\HCoordinateStyle{\h@n}}; \h@bottom@left@color at (-\h@n) {\HCoordinateStyle{\h@n}}; }% \fi } {} % \end{macrocode} % % The |HexBoard| environment just wraps |InnerHexBoard| % inside a |tikzpicture|. % \begin{macrocode} \newenvironment{HexBoard}[1][]{% \begin{tikzpicture} \begin{InnerHexBoard}[#1,prefix=,x=0,y=0] } % \end{macrocode} % Finally, |HexBoard| closes the |InnerHexBoard| and % |tikzpicture| environments. % \begin{macrocode} { \end{InnerHexBoard} \end{tikzpicture} } % \end{macrocode} % % The \cs{HGame} macro % \begin{macrocode} \newcount\h@move@number \newdimen\HStoneDiameter \newcommand\HGame[2][]{% \pgfqkeys{/h@game}{#1}% \HStoneDiameter=\h@relative@stone@size\h@half@hex@ht \multiply\HStoneDiameter by 2 \h@move@number=0 \ifh@numbered@moves \def\h@label{\HMoveNumberStyle{\h@first@move@label}% \global\def\h@label{\HMoveNumberStyle{\the\h@move@number}}} \else \def\h@label{} \fi \foreach \h@coord in {#2} {% \global\advance\h@move@number by 1 \ifodd\h@move@number \HBeforeOddMove \h@odd@player at (\h@coord) {\h@label}; \else \HBeforeEvenMove \h@even@player at (\h@coord) {\h@label}; \fi } } % \end{macrocode} % % The \cs{HStoneGroup} % \begin{macrocode} \newcommand\HStoneGroup[2][]{% \let\h@player\empty \let\h@label\empty \pgfqkeys{/h@stone@group}{#1}% \ifx\h@player\empty \errmessage{No color specified for HStoneGroup} \fi \HStoneDiameter=\h@relative@stone@size\h@half@hex@ht \multiply\HStoneDiameter by 2 \foreach \h@coord in {#2} {% \HBeforeStone \h@player at (\h@coord) {\h@label}; }% } % \end{macrocode} % % The \cs{HHexGroup} % \begin{macrocode} \newcommand\HHexGroup[2][]{% \let\h@label\empty \pgfqkeys{/h@hex@group}{#1}% \foreach \h@coord in {#2} {% \node at (\h@coord) {\h@label}; \h@draw@hex{\h@coord}% }% } % \end{macrocode} % % That's all, folks. % \begin{macrocode} % % \end{macrocode} % % \Finale