Since I like to play backgammon, this seemed like a useful thing to do. Here's an initial version of a backgammon display package. This is pretty rough, and I expect to update it, but it's pretty usable in its present state. Obviously it still needs some documentation, and there may be a few features missing.
Update
The package described below is currently being developed and is not yet officially released. The latest version of the code can be obtained from GitHub. Comments welcome.
tikz-backgammon.sty
Put this in your local texmf folder:
% Copyright 2012 by Alan Munn
%
% This package may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
% of this license or any later version.
% The latest version of this license is in
% http://www.latex-project.org/lppl.txt
% and version 1.3 or later is part of all distributions of LaTeX
% version 2005/12/01 or later.
%
% This package has the LPPL maintenance status `maintained'.
%
% The Current Maintainer of this package is Alan Munn.
%
% This package consists of the file tikz-backgammon.sty and documentation files
% tikz-backgammon.tex and tikz-backgammon.pdf
%
% Version 0.5 2012/03/20
%
%
\ProvidesPackage{tikz-backgammon}[2012/03/20 Backgammon game display using TikZ v0.5]
\RequirePackage{etoolbox}
\RequirePackage{tikz}
\usetikzlibrary{positioning}
% Construct the board
%
% alternating colours for the board
\newcommand*{\BW}{\pgfmathifthenelse{mod(\x,2)==0}{1}{0}\let\fillstyle\pgfmathresult}
\newcommand*{\WB}{\pgfmathifthenelse{mod(\x,2)==0}{0}{1}\let\fillstyle\pgfmathresult}
% construct a down point
\newcommand*{\dpoint}{%
\BW
\draw[thick,style=\fillstyle]
(\x,0) -- (\x+3/2,15) -- (\x+3,0) -- cycle; }
% construct an up point
\newcommand{\upoint}{%
\WB
\draw[thick,style=\fillstyle]
(\x,32) -- (\x+3/2,17) -- (\x+3,32) -- cycle; }
% set basic tikzparameters
\tikzset{1/.style={fill=\boardblack},
0/.style={fill=\boardwhite},
stone/.style={scale=1.35,draw=black,circle},
sans/.style={font=\footnotesize\sffamily},
cube/.style={minimum size=.5cm}
}
% initialization
\def\cubepos{above}
\pgfdeclarelayer{board}
\pgfdeclarelayer{pieces}
\pgfsetlayers{board,pieces,main}
% These should be made internal or key values
\newcommand*{\black}{black} % for the stones
\newcommand*{\white}{white}
\newcommand*{\boardblack}{brown}
\newcommand*{\boardwhite}{olive!50}
\newcommand*{\defaultscale}{.2}
\newlength{\betweengameskip}
\setlength{\betweengameskip}{2\baselineskip}
% initial state of the doubling cube
\newcommand*{\doublestate}{neutral}
\newcommand*{\doublenum}{2}
% create 24 counters for the point counts
% create 24 macros for the point state (black,white,none)
\foreach \x in {1,...,24}{
\newcounter{bk@pt\x}
\expandafter\gdef\csname bk@state\x\endcsname{none}
}
% some debugging commands
\newcommand*\showpoint[1]{\the\csname c@bk@pt#1\endcsname}
\newcommand*\setstate[2]{\expandafter\gdef\csname bk@state#1\endcsname{#2}}
\newcommand*\usestate[1]{\csname bk@state#1\endcsname}
% basic command to draw the board
% all of these numbers probably shouldn't be hard coded
%
\newcommand{\drawboard}{%
\begin{pgfonlayer}{board}
% draw the boarder and the point numbers
\draw[line width=4pt] (0,0) -- (0,32) -- (38,32) -- (38,0) -- cycle;
\foreach \x in {1,...,6}{
\node[sans] (\x) at (39.5-\x*3,-1.5) {\x};
\pgfmathparse{int(\x+6)}\let\nodename\pgfmathresult
\node[sans] (\nodename) at (25.5-\x*3-6,-1.5) {\nodename};
\pgfmathparse{int(25-\x)}\let\nodename\pgfmathresult
\node[sans] (\nodename) at (39.5-\x*3,33.5) {\nodename};
\pgfmathparse{int(\x+12)}\let\nodename\pgfmathresult
\node[sans] (\nodename) at (25.5+\x*3-27,33.5) {\nodename};
}
% now draw the first half points
\foreach \x in {0,3,...,15}
\dpoint;
\foreach \x in {0,3,...,15}
\upoint;
% draw the bar and set the anchors for bar and the doubling cube
\draw[very thick,fill=brown](18,0) -- (18,32) -- (20,32) -- (20,0) -- cycle;
\node (barcenter) at (19,14) {};
\node (black double) at (40, 2) {};
\node (white double) at (40, 30) {};
\node (neutral double) at (40,12.5) {};
% draw the other half of the points
\foreach \x in {20,23,...,35}
\dpoint;
\foreach \x in {20,23,...,35}
\upoint;
\end{pgfonlayer}
}
% commands to place markers on a point and set its state
% these are used for setting the initial board and for users
% to make arbitrary board configurations
% placement is still a little off (some overlap)
% first for a black point
\newcommand{\blackpoint}[2]{%
\global\csname c@bk@pt#1\endcsname #2\relax
\setstate{#1}{black}
% check to see if we're on an up point or a down point
\pgfmathparse{ifthenelse(#1>12,"below","above")}\let\pos\pgfmathresult
\begin{pgfonlayer}{pieces}
\foreach \x in {1,...,#2}
\node[fill=\black,style=stone,\pos=.5*\x-.45 of #1] {};
\end{pgfonlayer}}
% same again for a white point
\newcommand{\whitepoint}[2]{%
\global\csname c@bk@pt#1\endcsname #2\relax
\setstate{#1}{white}
\pgfmathparse{ifthenelse(#1>12,"below","above")}\let\pos\pgfmathresult
\begin{pgfonlayer}{pieces}
\foreach \x in {1,...,#2}
\node[fill=\white,style=stone,\pos=.5*\x-.45 of #1] {};
\end{pgfonlayer}}
% now a generic version of the command for use in displaying the board
% this is really an internal command
\newcommand{\placepoint}[2]{%
\let\ptname#1
\ifnumcomp{#2}{<}{1}
{}
{\pgfmathparse{ifthenelse(#1>12,"below","above")}\let\pos\pgfmathresult
\begin{pgfonlayer}{pieces}
\foreach \x in {1,...,#2}
\node[fill=\usestate{\ptname},style=stone,\pos=.5*\x-.45 of \ptname] {};
\end{pgfonlayer}
}
}
% command to place pieces on the bar
\newcommand*{\onbar}[2]{%
\begin{pgfonlayer}{board}
\foreach \x in {1,...,#2}
\node[fill=\csname#1\endcsname,style=stone,above=.5*\x-.35 of barcenter)] {};
\end{pgfonlayer}
}
% user command to set a double
% syntax is \double{<owner>}{amount}
\newcommand*{\double}[2]{%
\let\doublenum#2
\ifstrequal{#1}{neutral}
{\gdef\doublestate{neutral double}}
{\ifstrequal{#1}{white}
{\gdef\cubepos{below}\gdef\doublestate{white double}}
{\gdef\cubepos{above}\gdef\doublestate{black double}}
}
}
% internal command to place the doubling cube in the correct place
\newcommand*{\placedouble}{
\node[draw,style=cube, \cubepos=.5cm of \doublestate %
,font={\bfseries\sffamily}] {\doublenum};}
% command to set a new game and display it
\newcommand*{\newgame}[1][\defaultscale]{%
\begin{tikzpicture}[scale=#1]
\drawboard
\whitepoint{1}{2}
\whitepoint{12}{5}
\whitepoint{17}{3}
\whitepoint{19}{5}
\blackpoint{24}{2}
\blackpoint{13}{5}
\blackpoint{8}{3}
\blackpoint{6}{5}
\double{neutral}{2}
\placedouble
\end{tikzpicture}}
% commands to move first black, then white
\newcommand\blackmove[4]{
\advance\csname c@bk@pt#1\endcsname -1\relax
\ifnumcomp{\the\csname c@bk@pt#1\endcsname}{=}{0}
{\expandafter\gdef\csname bk@state#1\endcsname{none}}
{\expandafter\gdef\csname bk@state#1\endcsname{black}}
\ifnumcomp{#2}{=}{0}{}{\advance\csname c@bk@pt#2\endcsname 1\relax}
\expandafter\gdef\csname bk@state#2\endcsname{black}
\advance\csname c@bk@pt#3\endcsname -1\relax
\ifnumcomp{\the\csname c@bk@pt#3\endcsname}{=}{0}
{\expandafter\gdef\csname bk@state#1\endcsname{none}}
{\expandafter\gdef\csname bk@state#3\endcsname{black}}
\ifnumcomp{#4}{=}{0}{}{\advance\csname c@bk@pt#4\endcsname 1\relax}
\expandafter\gdef\csname bk@state#4\endcsname{black}
}
\newcommand\whitemove[4]{
\advance\csname c@bk@pt#1\endcsname -1\relax
\ifnumcomp{\the\csname c@bk@pt#1\endcsname}{=}{0}
{\expandafter\gdef\csname bk@state#1\endcsname{none}}
{\expandafter\gdef\csname bk@state#1\endcsname{white}}
\ifnumcomp{#2}{=}{0}{}{\advance\csname c@bk@pt#2\endcsname 1\relax}
\expandafter\gdef\csname bk@state#2\endcsname{white}
\advance\csname c@bk@pt#3\endcsname -1\relax
\ifnumcomp{\the\csname c@bk@pt#3\endcsname}{=}{0}
{\expandafter\gdef\csname bk@state#1\endcsname{none}}
{\expandafter\gdef\csname bk@state#3\endcsname{white}}
\ifnumcomp{#4}{=}{0}{}{\advance\csname c@bk@pt#4\endcsname 1\relax}
\expandafter\gdef\csname bk@state#4\endcsname{white}
}
% command to display the current state of the board
\newcommand{\displayboard}{%
\par\vspace{\betweengameskip}
\begin{tikzpicture}[scale=\defaultscale]
\drawboard
\foreach \x in {1,...,24}{
\placepoint{\x}{\the\csname c@bk@pt\x\endcsname}}
\placedouble
\end{tikzpicture}
}
\endinput
% Still to be added:
% Displaying the dice (easy, but I can't be bothered)
Sample document
% This is a test document for the tikz-backgammon package.
\documentclass[12pt]{article}
\usepackage{tikz-backgammon}
\begin{document}
\newgame
\blackmove{13}{8}{8}{5}
\whitemove{1}{7}{1}{7}
\double{white}{4}
\blackmove{24}{18}{24}{18}
\blackmove{8}{2}{8}{2}
\blackmove{8}{4}{13}{10}
\whitemove{12}{16}{12}{15}
\displayboard
\end{document}
Output
!
from the automatically inserted code. Then another user can easily add the image. If you edit the code before you have enough rep to include images, you'll need to remove the!
s from both image inclusions (as you'll need to do to add the second image since I've added the first - if I'd thought about it, I'd've waited before adding the first! Sorry!).@
character and typing the nickname of that particular user.