% Documentation for the tikz-catan package. Compile with:
%   TEXINPUTS=..: pdflatex tikz-catan-doc.tex   (twice, for the ToC)
\documentclass[10pt]{article}
\usepackage[margin=2.4cm]{geometry}
\usepackage{parskip}
\usepackage{tikz-catan}
\usepackage[colorlinks=true,linkcolor=blue!50!black,urlcolor=blue!50!black]{hyperref}
\hypersetup{pdftitle={tikz-catan manual},pdfauthor={Teodor Filip Leahu}}
\usepackage{listings}
\definecolor{codebg}{HTML}{F7F4EC}
\definecolor{codeframe}{HTML}{D8D2C4}
\definecolor{codecmd}{HTML}{2E4A7A}
\definecolor{codecomment}{HTML}{8A8578}
\lstset{language=[LaTeX]TeX,
  basicstyle=\ttfamily\small,
  backgroundcolor=\color{codebg},
  frame=single, framerule=0.5pt, rulecolor=\color{codeframe}, framesep=5pt,
  texcsstyle=*\color{codecmd},
  commentstyle=\color{codecomment}\itshape,
  columns=fullflexible, keepspaces=true,
  moretexcs={documentclass,usepackage,begin,end,newcommand,renewcommand,
    catanframe,standardboard,standardports,catanrows,robber,
    hexfull,hexdim,hexshape,hexprob,hexauto,hexdots,
    hlhex,hlres,hlnum,settlement,city,road,port,portdim,portauto,
    catanlegend,vertexXY,hexXY,CatanS,cataniconsfalse,cataniconstrue,
    coordinate,draw,node,myboard}}

\newcommand\cmd[1]{\texttt{\textcolor{codecmd}{\textbackslash #1}}}
\newenvironment{cmddesc}
  {\begin{list}{}{\setlength\leftmargin{1.6em}\setlength\itemsep{5pt}}}
  {\end{list}}

\title{\bfseries tikz-catan\\[3pt]\large Catan board diagrams in pure \LaTeX/TikZ}
\author{Teodor Filip Leahu}
\date{}

\begin{document}
\maketitle

\begin{center}
{\renewcommand\CatanS{0.88}
\begin{tikzpicture}
  \catanframe \standardboard{\hexfull} \standardports{\port} \robber{0}{0}
\end{tikzpicture}}
\end{center}

\noindent\textbf{tikz-catan} draws board states of \emph{The Settlers of Catan}
directly in \LaTeX: full boards with resources, number tokens, ports, pieces,
and a robber; desaturated and silhouette variants; and highlight views by hex
coordinate, resource, or number token. Diagrams are pure TikZ vector output,
with no image files and fonts matching the surrounding document, and the
package depends on nothing beyond TikZ itself. It is aimed at papers, theses,
teaching material, and strategy write-ups.

\bigskip

\tableofcontents

\section{Introduction}

Board contents are declared in game terms (hexes, tokens, settlements,
ports) and the package computes all geometry. The interface is built around
three decisions:

\begin{enumerate}
  \item \textbf{Data-driven boards.} A board is a list of
  \texttt{\{q\}\{r\}\{resource\}\{number\}} entries handed to a
  \emph{renderer callback}. The same board data can therefore be drawn in
  full color, desaturated, as a bare silhouette, or with selected hexes
  highlighted, simply by swapping one macro name.
  \item \textbf{Named coordinates.} Pieces and ports are placed by hex plus
  a compass name (\texttt{\{0\}\{-1\}\{N\}}), never by raw lengths; the
  board is addressed the way a player points at it.
  \item \textbf{One scale knob.} Every dimension derives from \cmd{CatanS},
  the hex circumradius in centimetres. Redefining it (globally or inside a
  group) scales the entire figure coherently, line widths, tokens, and
  text included.
\end{enumerate}

All artwork is original flat geometry; no official Catan art is reproduced.

\section{Installation and requirements}

Requirements: a standard \LaTeX{} distribution with TikZ (any recent \TeX{}
Live or MiK\TeX). Nothing else.

\textbf{Manual installation} (works everywhere, including Overleaf): place
\texttt{tikz-catan.sty} in the same directory as the main \texttt{.tex}
file (on Overleaf, the project root) and load it with
\verb|\usepackage{tikz-catan}|.

\textbf{\TeX{} tree installation}: place the file in
\texttt{TEXMFHOME/tex/latex/tikz-catan/} (\texttt{kpsewhich -var-value
TEXMFHOME} locates the directory).

\section{Quick start}

A complete document:

\begin{lstlisting}
\documentclass[tikz,border=8pt]{standalone}
\usepackage{tikz-catan}
\begin{document}
\begin{tikzpicture}
  \catanframe % sea frame
  \standardboard{\hexfull} % 19 hexes, full color
  \standardports{\port} % nine ports
  \robber{0}{0} % robber on the desert
\end{tikzpicture}
\end{document}
\end{lstlisting}

That produces the board on the title page. \cmd{standardboard} and
\cmd{standardports} are a built-in \emph{legal} example layout: correct
tile and token multisets, no two red (6/8) tokens adjacent, a token-free
desert, and a standard-style port arrangement. Section~\ref{sec:boards}
shows how to supply a different layout.

\section{The coordinate system}
\label{sec:coords}

\subsection{Hexes: axial coordinates}

Hexes are pointy-top and addressed by axial coordinates $(q,r)$: $q$ grows
to the right, $r$ grows downward with a half-step rightward slant. The 19
board hexes are all $(q,r)$ with $|q|\le 2$, $|r|\le 2$, $|q+r|\le 2$; the
desert of the built-in layout sits at $(0,0)$.

\begin{center}
\begin{tikzpicture}
  % silhouette with printed coordinates
  \newcommand\hexcoordref[4]{%
    \hexshape{#1}{#2}{#3}{#4}%
    \hexXY{#1}{#2}%
    \node[font=\footnotesize,text=dimtoken] at (\hx,\hy) {$#1,#2$};}
  \standardboard{\hexcoordref}
\end{tikzpicture}
\end{center}

\subsection{Corners and sides: compass names}

Each hex has six \emph{corners} (vertices, where settlements go) and six
\emph{sides} (edges, where roads go), named by compass direction:

\begin{center}
{\renewcommand\CatanS{2.1}
\begin{tikzpicture}
  \hexshape{0}{0}{}{}
  \foreach \c in {N,NE,SE,S,SW,NW}{
    \vertexXY{0}{0}{\c}
    \fill[tokentext] (\vx,\vy) circle (2.2pt);
    \pgfmathsetmacro\lx{1.16*\vx}\pgfmathsetmacro\ly{1.16*\vy}
    \node[font=\small\bfseries,text=tokentext] at (\lx,\ly) {\c};}
  \foreach \s in {NE,E,SE,SW,W,NW}{
    \pgfmathsetmacro\nang{\csname sideNorm\s\endcsname}
    \pgfmathsetmacro\mx{0.62*\CatanS*cos(\nang)}
    \pgfmathsetmacro\my{0.62*\CatanS*sin(\nang)}
    \node[font=\small\itshape,text=dimtoken] at (\mx,\my) {\s};}
\end{tikzpicture}}
\end{center}

Corner names (bold, outside) address vertices; side names (italic, inside)
address edges. A side's two endpoints are its neighbouring corners: side
\texttt{E} runs from corner \texttt{NE} to corner \texttt{SE} --- so a road
on side \texttt{E} connects to a settlement on either of those corners.
Every vertex of the board belongs to up to three hexes and can be addressed
through any of them; \texttt{\{0\}\{-1\}\{N\}} and \texttt{\{0\}\{-2\}\{S\}}
are the same physical spot.

\section{Drawing boards}
\label{sec:boards}

\subsection{Renderers}

A board renderer is any macro taking four arguments
\texttt{\{q\}\{r\}\{resource\}\{number\}}, where \texttt{resource} is one of
\texttt{wood}, \texttt{brick}, \texttt{sheep}, \texttt{wheat}, \texttt{ore},
\texttt{desert}, and \texttt{number} is the token value ($0$ = no token,
used for the desert). The package ships five renderers:

\begin{cmddesc}
  \item \cmd{hexfull}\texttt{\{q\}\{r\}\{res\}\{n\}} --- colored hex,
  resource glyph (if icons are on), number token with probability pips,
  6 and 8 in red.
  \item \cmd{hexdim}\texttt{...} --- desaturated gray hex with a muted
  token; the backdrop for highlight figures.
  \item \cmd{hexshape}\texttt{...} --- bare silhouette (ignores resource
  and number).
  \item \cmd{hexprob}\texttt{...} --- neutral cream fill with full-color
  tokens; a ``probability view'' that isolates the number layer.
  \item \cmd{hexauto}\texttt{...} --- selector-aware: renders \cmd{hexfull}
  when the hex matches a highlight declaration
  (Section~\ref{sec:selectors}), \cmd{hexdim} otherwise.
\end{cmddesc}

Drawing the built-in layout means passing a renderer to
\cmd{standardboard}: \verb|\standardboard{\hexdim}|. A custom board is the
same call list with different data:

\begin{lstlisting}
\newcommand\myboard[1]{%
  #1{0}{-2}{wood}{11}#1{1}{-2}{ore}{3}% ... one entry per hex
}
\myboard{\hexfull}
\end{lstlisting}

Renderers are ordinary macros, so custom ones are one definition away; the
coordinate map in Section~\ref{sec:coords} is drawn by a four-line callback
that combines \cmd{hexshape} with a text node.

\cmd{hexdots}\texttt{\{q\}\{r\}\{.\}\{.\}} is a sixth, additive callback: it
marks the hex's six corners with dots. Used after a shape pass
(\verb|\standardboard{\hexshape}\standardboard{\hexdots}|), it displays all
54 settlement spots.

\subsection{Row input}
\label{sec:rows}

Nineteen coordinate tuples are tedious to write by hand. \cmd{catanrows}
accepts a board the way it is read from the table (five rows, top to
bottom, each row left to right) and assigns the axial coordinates
automatically:

\begin{lstlisting}
\catanrows{\hexfull}{%
  wood 11, wheat 4, ore 9;
  brick 3, sheep 10, wood 6, wheat 5;
  ore 8, wheat 2, sheep 9, brick 12, wood 10;
  ore 5, wood 3, desert, sheep 8;
  wheat 6, brick 11, sheep 4}
\end{lstlisting}

\begin{center}
{\renewcommand\CatanS{0.78}
\begin{tikzpicture}
  \catanrows{\hexfull}{%
    wood 11, wheat 4, ore 9;
    brick 3, sheep 10, wood 6, wheat 5;
    ore 8, wheat 2, sheep 9, brick 12, wood 10;
    ore 5, wood 3, desert, sheep 8;
    wheat 6, brick 11, sheep 4}
\end{tikzpicture}}
\end{center}

Format: exactly five rows of $3,4,5,4,3$ entries, separated by four
semicolons (no trailing semicolon); entries are comma-separated
``\texttt{resource number}'' pairs; the desert may be written without a
number. The first argument is the renderer, exactly as for
\cmd{standardboard}.

\subsection{Semantic highlighting}
\label{sec:selectors}

Highlight declarations mark what \cmd{hexauto} (and \cmd{portauto}, below)
should render in full color. Three selectors exist, and a hex lights up if
it matches \emph{any} of them (union semantics):

\begin{cmddesc}
  \item \cmd{hlhex}\texttt{\{q\}\{r\}} --- one hex by coordinate.
  \item \cmd{hlres}\texttt{\{resource\}} --- every hex of a resource.
  \item \cmd{hlnum}\texttt{\{n\}} --- every hex with number token $n$.
\end{cmddesc}

Declarations are local to the current \texttt{tikzpicture}. Intersections
(e.g.\ ore hexes \emph{on} 6 or 8) are expressed with explicit \cmd{hlhex}
coordinates.

\cmd{portauto}\texttt{\{q\}\{r\}\{side\}\{type\}} extends selection to
harbors: a resource port renders in full color when its resource is
declared via \cmd{hlres}, and desaturated (\cmd{portdim}) otherwise. A
board's ``wheat economy'', every wheat hex plus the wheat port, is
then three lines:

\begin{lstlisting}
\hlres{wheat}
\standardboard{\hexauto}
\standardports{\portauto}
\end{lstlisting}

\begin{center}
{\renewcommand\CatanS{0.80}
\begin{tikzpicture}
  \hlres{wheat}
  \standardboard{\hexauto}
  \standardports{\portauto}
\end{tikzpicture}}
\end{center}

\section{Pieces, ports, and scene elements}

\begin{cmddesc}
  \item \cmd{settlement}\texttt{\{q\}\{r\}\{corner\}\{color\}},
  \cmd{city}\texttt{\{q\}\{r\}\{corner\}\{color\}} --- a house / a larger
  house with tower at the named vertex. Player colors \texttt{pred},
  \texttt{pblue}, \texttt{porange}, \texttt{pwhite} are predefined; any
  xcolor expression works.
  \item \cmd{road}\texttt{\{q\}\{r\}\{side\}\{color\}} --- a road along the
  named edge, drawn with a darker outline for contrast on any terrain.
  \item \cmd{robber}\texttt{\{q\}\{r\}} --- the robber figure, offset beside
  the token position.
  \item \cmd{port}\texttt{\{q\}\{r\}\{side\}\{type\}} --- a harbor badge off
  the named \emph{coastal} side of a land hex, with piers to the two
  vertices it serves. \texttt{type} is \texttt{generic} (3:1) or a resource
  name (2:1 with a colored ring and swatch).
  \item \cmd{portdim}\texttt{...} / \cmd{portauto}\texttt{...} ---
  desaturated port / selector-aware port
  (Section~\ref{sec:selectors}); same arguments as \cmd{port}.
  \item \cmd{standardports}\texttt{\{<port renderer>\}} --- the nine ports
  of the built-in layout (four 3:1, five 2:1) through a callback:
  \verb|\standardports{\port}|, \verb|\standardports{\portauto}|, etc.
  \item \cmd{catanframe} --- the hexagonal sea backdrop; drawn first.
  \item \cmd{catanlegend}\texttt{\{y\}} --- a resource color legend centered
  at height \texttt{y} (in cm; \texttt{-6.6} sits below a default-scale
  framed board).
  \item \cmd{vertexXY}\texttt{\{q\}\{r\}\{corner\}} / \cmd{hexXY}%
  \texttt{\{q\}\{r\}} --- low-level: set \cmd{vx},\cmd{vy} /
  \cmd{hx},\cmd{hy} to the point's coordinates, for annotations such as
  distance paths (see the last gallery figure).
\end{cmddesc}

\section{Options and customization}

\begin{cmddesc}
  \item \cmd{CatanS} --- hex circumradius in cm (default \texttt{1.05}).
  Redefinable globally or locally:
  \verb|{\renewcommand\CatanS{0.8} \begin{tikzpicture}...}|.
  \item \cmd{cataniconsfalse} / \cmd{cataniconstrue} --- switch the resource
  glyph layer off/on. Icons help when introducing the game; on busy boards
  (pieces, highlights, robber) turning them off reduces visual noise and
  lets color alone carry the resource.
  \item \textbf{Palette} --- all colors are named \texttt{xcolor}
  definitions and can be redefined before the figure:
  \texttt{reswood}, \texttt{resbrick}, \texttt{ressheep}, \texttt{reswheat},
  \texttt{resore}, \texttt{resdesert}; \texttt{seafill},
  \texttt{seaborder}; \texttt{tokenfill}, \texttt{tokenborder},
  \texttt{tokentext}, \texttt{tokenred}; \texttt{dimfill},
  \texttt{dimborder}, \texttt{dimtoken}; \texttt{legendtext};
  \texttt{robbergray}; and the
  player colors \texttt{pred}, \texttt{pblue}, \texttt{porange},
  \texttt{pwhite}.
\end{cmddesc}

\section{Gallery}

Each figure states the code that produces it (frame, board, ports as in the
quick start are abbreviated to ``\dots'' where repeated).

\subsection{Icons off}
\begin{lstlisting}
\cataniconsfalse  \catanframe \standardboard{\hexfull} \standardports{\port}
\end{lstlisting}
\begin{center}
{\renewcommand\CatanS{0.80}\cataniconsfalse
\begin{tikzpicture}
  \catanframe \standardboard{\hexfull} \standardports{\port} \robber{0}{0}
\end{tikzpicture}}
\end{center}

\subsection{Silhouette with all 54 vertex spots}
\begin{lstlisting}
\standardboard{\hexshape} \standardboard{\hexdots}
\end{lstlisting}
\begin{center}
{\renewcommand\CatanS{0.72}
\begin{tikzpicture}
  \standardboard{\hexshape} \standardboard{\hexdots}
\end{tikzpicture}}
\end{center}

\newpage
\subsection{Probability view}
\begin{lstlisting}
\standardboard{\hexprob}
\end{lstlisting}
\begin{center}
{\renewcommand\CatanS{0.72}
\begin{tikzpicture}
  \standardboard{\hexprob}
\end{tikzpicture}}
\end{center}

\subsection{An opening position}
Settlements, a city, roads, and the robber; the placement respects the
distance rule.
\begin{center}
{\renewcommand\CatanS{0.86}
\begin{tikzpicture}
  \catanframe \standardboard{\hexfull} \standardports{\port} \robber{0}{0}
  \settlement{0}{-1}{N}{pred}\road{0}{-1}{NW}{pred}
  \settlement{-1}{1}{N}{pred}\road{-1}{1}{NE}{pred}
  \settlement{2}{-1}{NW}{pblue}\road{2}{-1}{NW}{pblue}
  \city{0}{1}{SE}{pblue}\road{0}{1}{E}{pblue}
  \settlement{-2}{0}{N}{porange}\road{-2}{0}{NE}{porange}
  \settlement{1}{0}{SE}{porange}\road{1}{0}{SE}{porange}
  \settlement{-2}{2}{SE}{pwhite}\road{-2}{2}{E}{pwhite}
  \settlement{1}{-2}{NE}{pwhite}\road{1}{-2}{E}{pwhite}
\end{tikzpicture}}
\end{center}

\newpage
\subsection{Highlighting a placement pair}
\begin{lstlisting}
\hlhex{0}{-1}\hlhex{0}{-2}\hlhex{1}{-2}
\hlhex{-1}{1}\hlhex{-1}{0}\hlhex{0}{0}
\standardboard{\hexauto}
\settlement{0}{-1}{N}{pred} \settlement{-1}{1}{N}{pred}
\end{lstlisting}
\begin{center}
{\renewcommand\CatanS{0.80}
\begin{tikzpicture}
  \hlhex{0}{-1}\hlhex{0}{-2}\hlhex{1}{-2}
  \hlhex{-1}{1}\hlhex{-1}{0}\hlhex{0}{0}
  \standardboard{\hexauto}
  \settlement{0}{-1}{N}{pred}
  \settlement{-1}{1}{N}{pred}
\end{tikzpicture}}
\end{center}

\subsection{Annotating with low-level coordinates}
A settlement two roads from a brick port, with the path and distance
labelled via \cmd{vertexXY}:
\begin{lstlisting}
\standardboard{\hexdim}
\port{-2}{1}{W}{brick}  \settlement{-2}{1}{NE}{pred}
\vertexXY{-2}{1}{NE}\coordinate (pa) at (\vx,\vy);
\vertexXY{-2}{1}{N} \coordinate (pb) at (\vx,\vy);
\vertexXY{-2}{1}{NW}\coordinate (pc) at (\vx,\vy);
\draw[pred,line width=2.2pt,dash pattern=on 5pt off 3.5pt,
      line cap=round,shorten <=6pt,shorten >=4pt] (pa)--(pb)--(pc);
\end{lstlisting}
\begin{center}
{\renewcommand\CatanS{0.80}
\begin{tikzpicture}
  \standardboard{\hexdim}
  \port{-2}{1}{W}{brick}
  \settlement{-2}{1}{NE}{pred}
  \vertexXY{-2}{1}{NE}\coordinate (pa) at (\vx,\vy);
  \vertexXY{-2}{1}{N}\coordinate (pb) at (\vx,\vy);
  \vertexXY{-2}{1}{NW}\coordinate (pc) at (\vx,\vy);
  \draw[pred,line width=2.2pt,dash pattern=on 5pt off 3.5pt,line cap=round,
        shorten <=6pt,shorten >=4pt] (pa)--(pb)--(pc);
  \node[font=\small\bfseries,text=pred,anchor=south] at ($(pb)+(0,0.12)$) {$d_p=2$};
\end{tikzpicture}}
\end{center}

\section{Legality and scope}

The built-in layout guarantees: the base-game tile multiset (4 wood,
4 wheat, 4 sheep, 3 brick, 3 ore, 1 desert), the token multiset (one 2 and
12, two each of 3--6 and 8--11), no two red tokens adjacent, and a
token-free desert. It is a \emph{representative} legal layout, not the
official beginner setup. The package draws the data it is given;
user-supplied boards and placements are not validated.

\section{Roadmap}

Planned for future versions: the official beginner layout as a second
built-in; a per-vertex production heatmap renderer; a longest-road trace
helper; a 5--6 player frame; a game-state layer so pieces, like hexes,
become data that renderers and selectors can act on. Issues and
contributions are welcome at the repository.

\section{License}

MIT License, \copyright{} 2026 Teodor Filip Leahu; see the \texttt{LICENSE}
file in the repository.

\end{document}
