TransWikia.com

Typesetting boardgame positions using ttf font

TeX - LaTeX Asked by Michael Ras on April 7, 2021

For presenting positions in the game of backgammon, there is a commercially developed, but free for personal use,
without modifications, font called eXtremeGammon. The ttf font file is available from the eXtreme Gammon site
ttf file. I was hoping to use this font for typesetting notes and references using LaTeX. I took the advice from the
accepted answer to an earlier TeX Stackexchange post, Installing TTF fonts in LaTeX, on using ttf fonts in LaTeX by
using XeTeX rather than LaTeX.

I have two problems with this approach:

1) Some characters in the font are not found by XeLaTeX, eg. digraphs and the £ character. The font does work with these
characters outside TeX and the characters do appear with a symbol when studying the ttf file using FontForge. The
following simple example outputs a pdf file from XeLaTeX, but containins only the symbol for the @-character.

documentclass{article}
usepackage{fontspec}
setromanfont{eXtremeGammon}
begin{document}
ñ © @ £
end{document}

The only thing I can understand as related in the log file is these lines:

Missing character: There is no ñ in font eXtreme Gammon/ICU!
Missing character: There is no © in font eXtreme Gammon/ICU!
Missing character: There is no £ in font eXtreme Gammon/ICU!

I tried using the tip from this earlier posting related to inputting characters to XeLaTeX Foreign characters in XeLaTeX, but it did not change anything for me.

2) The goal is to be able to typeset positions with end result as in this picture
enter image description here

which is an image of how browsers render the font. The font works by individual characters being eg. a black disc on the middle fifth of a downward triangle with white background, a white disc on the lowest fifth of an upward triangle with lined background or eg. a part of the playing frame. In order to have the characters “connect” and not have holes in the resulting position I add offinterlineskip. However, this still leaves very thin horizontal empty lines in the diagram after some lines. Here is a simple example that draws a downward white triangle using the font. The spacing is better but not quite right at all lines, even with offinterlineskip

documentclass{article}
usepackage{fontspec}
setromanfont{eXtremeGammon}
begin{document}
offinterlineskip %% Still leaves thin vertical lines of empty space
                  %% after some lines. Problem in font itself ?
noindent 
A
B
C
D
E
end{document}

Here is image of the triangle in the pdf output with thin empty lines in two spots:

enter image description here

A last note is that the eg. the triangles does not look nearly as “sharp” as in a browser when it is rendered using a CSS sheet with @font-face, so perhaps this overall strategy on how to typeset these positions in TeX is flawed ?

UPDATE: Regarding part 1) I tried running Leo Liu’s answer to Generating a table of glyphs with XeLaTeX and it turns out that only for values i in the range from 32 to 160 are there any for which iffontcharfonti is true
despite there being more characters with symbols in the ttf font then the number of trues here. I haven’t worked much with LaTeX and fonts but I am starting to think if this could be some sort of encoding problem ? The following
post could be relevant Font has glyph but XeLaTeX reports “Missing character”. How would I check the following from the last comment in that post: if this font is to old and doesn’t use unicode ?

2 Answers

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}letfillstylepgfmathresult}
newcommand*{WB}{pgfmathifthenelse{mod(x,2)==0}{0}{1}letfillstylepgfmathresult}
% 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=footnotesizesffamily},
                cube/.style={minimum size=.5cm}
                }
% initialization
defcubepos{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}{2baselineskip}
% 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@ptx}
expandaftergdefcsname bk@statexendcsname{none}
}

% some debugging commands
newcommand*showpoint[1]{thecsname c@bk@pt#1endcsname}
newcommand*setstate[2]{expandaftergdefcsname bk@state#1endcsname{#2}}
newcommand*usestate[1]{csname bk@state#1endcsname}

% 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)}letnodenamepgfmathresult
        node[sans] (nodename) at (25.5-x*3-6,-1.5)  {nodename};
        pgfmathparse{int(25-x)}letnodenamepgfmathresult
        node[sans] (nodename) at (39.5-x*3,33.5)  {nodename};
        pgfmathparse{int(x+12)}letnodenamepgfmathresult
         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]{%
  globalcsname c@bk@pt#1endcsname #2relax
  setstate{#1}{black}
% check to see if we're on an up point or a down point
  pgfmathparse{ifthenelse(#1>12,"below","above")}letpospgfmathresult
  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]{%
  globalcsname c@bk@pt#1endcsname #2relax
  setstate{#1}{white}
  pgfmathparse{ifthenelse(#1>12,"below","above")}letpospgfmathresult
  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]{%
  letptname#1
  ifnumcomp{#2}{<}{1}
     {}
     {pgfmathparse{ifthenelse(#1>12,"below","above")}letpospgfmathresult
      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#1endcsname,style=stone,above=.5*x-.35 of barcenter)] {};
      end{pgfonlayer}
}
% user command to set a double
% syntax is double{<owner>}{amount}
newcommand*{double}[2]{%
  letdoublenum#2
  ifstrequal{#1}{neutral}
     {gdefdoublestate{neutral double}}
     {ifstrequal{#1}{white}
        {gdefcubepos{below}gdefdoublestate{white double}}
        {gdefcubepos{above}gdefdoublestate{black double}}
     }
}
% internal command to place the doubling cube in the correct place
newcommand*{placedouble}{
   node[draw,style=cube, cubepos=.5cm of doublestate %
  ,font={bfseriessffamily}] {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  

newcommandblackmove[4]{
    advancecsname c@bk@pt#1endcsname -1relax
    ifnumcomp{thecsname c@bk@pt#1endcsname}{=}{0}
        {expandaftergdefcsname bk@state#1endcsname{none}}
        {expandaftergdefcsname bk@state#1endcsname{black}}
    ifnumcomp{#2}{=}{0}{}{advancecsname c@bk@pt#2endcsname 1relax}
    expandaftergdefcsname bk@state#2endcsname{black}
    advancecsname c@bk@pt#3endcsname -1relax
    ifnumcomp{thecsname c@bk@pt#3endcsname}{=}{0}
        {expandaftergdefcsname bk@state#1endcsname{none}}
        {expandaftergdefcsname bk@state#3endcsname{black}}
    ifnumcomp{#4}{=}{0}{}{advancecsname c@bk@pt#4endcsname 1relax}
    expandaftergdefcsname bk@state#4endcsname{black}
}

newcommandwhitemove[4]{
    advancecsname c@bk@pt#1endcsname -1relax
    ifnumcomp{thecsname c@bk@pt#1endcsname}{=}{0}
        {expandaftergdefcsname bk@state#1endcsname{none}}
        {expandaftergdefcsname bk@state#1endcsname{white}}
    ifnumcomp{#2}{=}{0}{}{advancecsname c@bk@pt#2endcsname 1relax}
    expandaftergdefcsname bk@state#2endcsname{white}
    advancecsname c@bk@pt#3endcsname -1relax
    ifnumcomp{thecsname c@bk@pt#3endcsname}{=}{0}
        {expandaftergdefcsname bk@state#1endcsname{none}}
        {expandaftergdefcsname bk@state#3endcsname{white}}
    ifnumcomp{#4}{=}{0}{}{advancecsname c@bk@pt#4endcsname 1relax}
    expandaftergdefcsname bk@state#4endcsname{white}
}

% command to display the current state of the board
newcommand{displayboard}{%
  parvspace{betweengameskip}
  begin{tikzpicture}[scale=defaultscale]
        drawboard
        foreach x in {1,...,24}{
            placepoint{x}{thecsname c@bk@ptxendcsname}}
        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

output of sample document

Answered by Alan Munn on April 7, 2021

I know it's been a while, and this question has even resulted in a new package, which is amazing ;) However, I just stumbled upon this question and managed to create a beautiful board with the extremegammon font. One needs the fancyvrb package, which lets you define a new verbatim environment (board) which is basically verbatim without any line height (taken from xelatex — remove line spacing in verbatim environment). Then, you have to set the mono font to the one offered by extreme gammon (I put the font into ~/.fonts and ran fc-cache). The whole thing gets compiled with lualatex, I'm currently using the version that comes with TeXLive 2019. The example board is taken from the website (I added rolls by just using simple numbers for the dice), but you can export a position from extreme gammon into the font.

documentclass{scrartcl}
% from the fontspec documentation, chp. 4.2: Specifically choosing the NFSS family
usepackage{fontspec}
usepackage{fancyvrb}
fvset{fontfamily=myverbatimfont}
newfontfamilyverbatimfont[NFSSFamily=myverbatimfont]{eXtreme Gammon}
% create a new verbatim environment that uses the gammon font (with its new name)
DefineVerbatimEnvironment{board}{Verbatim}{%
  formatcom={baselineskip=-maxdimenlineskip=0pt},
  fontfamily=myverbatimfont
}
begin{document}
begin{board}
 ñ¡²±²¢ò
 ðPAZAZA@ @ZAPAFKð
 ðQBGB[B@ @[BGBGBð
 ðRCHCC@ @CHCHCð
 ðIDIDID@ @]DIDIDð
 ðJEJEJE@ @ÛEJEJEð
'ð      @ @ 3  1 ð
 ðejejej@ @ejejejð
 ðxididi@ @dididið
 ðwhchmh@ @mhchchð
 ðvgbglg@ @lglgb{ð
 ðupapkf@ @kfkfazð
 ó£´³´¤ô
end{board}
end{document}

Here's how it looks:

Board rendered with the eXtreme Gammon font

Answered by drm on April 7, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP