# Typeset large Go boards

I have need to typeset some very large Go boards, much larger than normal 19x19 boards, as part of a project I am undertaking in infinite Go, similar to my projects in infinite chess. Can you help me typeset very large Go boards,such as the following comparatively tiny instance:

I am aware of the LaTeX package igo, which seems to produce high-quality Go board images, and while I don't have much experience with it, it does seem to be flexible on board size. I can imagine placing several of these boards next to each other, if need be, in order to make large boards. That is what I had had to do to make my various infinite chess positions, and it worked fine.

I was not actually able to get the igo package working on my (miktek, Windows) system, however, and so I am very sorry that I cannot provide a minimal working example.

Meanwhile, I find the input format used in the igo package to be inconvenient for the typical infinite Go positions, which have many dozens of stones. With the igo format, one evidently types something like

\white{b4,c4,d4,e4,f4,g3,g2,c3}
\black{b3,b2,c2,d3,e3,f3,f2}
\begin{center}
\shortstack{\showgoban\\White to kill}
\end{center}


to get the image:

Thus, one specifies the coordinates of each stone separately.

It would be much more convenient for me, however, to be able to specify the position something like this:

 showgoboard{........\\
.WWWWW..\\
.BWBBBW.\\
.BB..BW.\\
........\\}


or something similar, and also with (much) larger board sizes.

The main point is that with the design of infinite go positions, one is often copying and pasting parts of a position or shifting everything by one unit or two units up or to the right, and so on, and this would be extremely irritating with the coordinate-style igo notation, but it would be easy with my notation. I want a notation system that allows one easily to copy parts of a position as a block into other parts of the board.

Can someone help me out? I would like either a Go board package that can accept something like my notation, or else a translation macro that would convert my notation or something like it into the notation accepted by igo or another Go package.

• Just some idea: I'd probably use a single TikZ grid instead of several boards placed next to each other. And since my TeX programming skills are pretty non-existent, I'd probably use some scripting language to translate your desired input into the right coordinates. But I am sure someone will have a better clue about this. – Uwe Ziegenhagen May 14 '18 at 3:51
• @UweZiegenhagen I'd rather use a Go-specific package, since I will also need to label stones and locations, etc., and I would expect that most of them can do that kind of thing very well. I'd rather not end up writing my own Go package. – JDH May 14 '18 at 3:54
• If you are going to be copying and pasting positions, I think it would be beneficial to define macros: \whitetokill takes two arguments and typesets your example at that location, \line{b}{5,6}{50,6} typesets the semi-infinite black line in your drawing, etc. But that's all beyond my TeX abilities. – Teepeemm May 15 '18 at 1:12
• The point is that the positions will be huge, and the design of them will involve dozens of minor adjustments and movings-around of portions. I want to lay them out and work with them in ASCII, where they can be visualized, rather than with an opaque coordinate representation. – JDH May 15 '18 at 1:21

## First proposition

Here is simple solution via TikZ (note: don't use . as empty intersection).

\documentclass[tikz,margin=2mm]{standalone}
\usepackage{etoolbox}
\usepackage{xparse}
\tikzset{
@go line/.code args={#1#2#3!}{
\edef\myrest{#3}
\edef\myletter{#2}
\draw (#1,-\mycount) +(0,-.5) -- +(0,.5) +(.5,0) -- +(-.5,0);
\ifdefstring{\myletter}{W}{
\path[draw,fill=white] (#1,-\mycount) circle (.4);
}{
\ifdefstring{\myletter}{B}{
\path[draw,fill=black] (#1,-\mycount) circle (.4);
}{}
}
\ifdefstring{\myrest}{}{}{
\pgfmathsetmacro\mynext{int(#1+1)}
\pgfkeysalso{@go line={\mynext}#3!}
}
},
go line/.style={@go line={0}#1!},
}
\NewDocumentCommand\showgoboard{m}{
\begin{tikzpicture}[x=\mygounit,y=\mygounit]
\edef\myconf{#1}
\foreach [count=\mycount] \myline in \myconf {
\tikzset{go line/.expanded=\myline}
}
\end{tikzpicture}
}
\def\mygounit{5mm}
\begin{document}
\showgoboard{
--------,
-WWWWW--,
-BWBBBW-,
-BB--BW-,
--------
}
\end{document}


## Second proposition

Enhanced version with better use of pgfkeys and possible annotations. The (customisable) parser uses the following convention:

• . (a point) is an error!
• B as black stone
• W as white stone
• - (a minus) as empty point
• any other symbol as annotation letter
\documentclass[tikz,margin=2mm]{standalone}
\usepackage{lmodern}
\usepackage{etoolbox}
\usepackage{xparse}
\tikzset{
@go draw intersection/.code 2 args={
\draw[line width=.5\pgflinewidth] (#1,-#2) +(0,-.5) -- +(0,.5) +(.5,0) -- +(-.5,0);
},
@go draw stone/.code n args={3}{
\path[draw,fill=#3] (#1,-#2) circle (.4);
},
@go draw annot/.code n args={3}{
\pgfmathsetmacro\gofsa{\gounit*.8}
\pgfmathsetmacro\gofsb{\gofsa*1.2}
\path (#1,-#2)
node[fill=white,inner sep=.1em,node font=\fontsize{\gofsa pt}{\gofsb pt}\selectfont,anchor=mid]
{#3};
},
@go draw W/.style 2 args={@go draw stone={#1}{#2}{white}},
@go draw B/.style 2 args={@go draw stone={#1}{#2}{black}},
@go draw -/.style 2 args={},
@go line/.code args={#1#2#3!}{
\pgfkeysalso{
@go draw intersection={#1}{\gocount},
@go draw #2/.try={#1}{\gocount}
}
\ifbool{pgfkeyssuccess}{}{\pgfkeysalso{@go draw annot={#1}{\gocount}{#2}}}
\edef\gorest{#3}
\ifdefstring{\gorest}{}{}{
\pgfmathsetmacro\gonext{int(#1+1)}
\pgfkeysalso{@go line={\gonext}#3!}
}
},
go line/.style={@go line={0}#1!},
}
\NewDocumentCommand\showgoboard{m}{
\begin{tikzpicture}[x=\gounit,y=\gounit,line width=\gounit*0.03]
\edef\goconf{#1}
\foreach [count=\gocount] \goline in \goconf {
\tikzset{go line/.expanded=\goline}
}
\end{tikzpicture}
}
\def\gounit{6mm}
\begin{document}
\showgoboard{
---------,
--BBcd---,
-WWWWW-e-,
-BWBBBW--,
-BB-aBWb-,
---------
}
\end{document}


If you are willing to use LuaLaTex, converting your notation into the igo notation is reasonably simple:

    \documentclass[10pt,a4paper]{article}
\usepackage{luacode}

\newcommand{\white}[1]{WHITE:#1\\}
\newcommand{\black}[1]{BLACK:#1\\}
\newbox\tmp
\newenvironment{go}{
\setbox\tmp\vbox\bgroup{}
\directlua{startrecording()}
}{
\egroup
\directlua{stoprecording()}
}

\begin{luacode*}
do
local board = {}

-- record a part (line) of the go board
board = board .. buf .. "\n"
end

function startrecording()
-- start recording the go board; called before the go environment starts
board = ""
end

function row_to_char(row)
-- converts a row number to a character (0=>a, 1=>b, 2=>c, etc)
return string.char(65+row):lower()
end

function stoprecording()
-- called when the go environment ends
-- converts the board notation into a string for white & black

-- removes the callback to stop recording

local row = 0               -- current row number
local col = 0               -- current column
local white = ""            -- the string of white positions
local black = ""            -- the string of black positions
local c_char = ""           -- helper variable containing the current character

for pos = 1 , board:len() do  -- iterate over the board string
c_char = board:sub(pos,pos):lower()
print("At pos"..row_to_char(row)..col.."("..pos.."), char:"..board:sub(pos,pos))
if c_char == '.' then
col = col + 1
elseif c_char == 'w' then
col = col + 1
white = white..','..row_to_char(row)..col
elseif c_char == 'b' then
col = col + 1
black = black..','..row_to_char(row)..col
elseif c_char == '\n' then
col = 0
row = row + 1
end
end

-- output the commands \white{white position} \black{black position}
tex.print("\\white{"..white:sub(2).."}\\black{"..black:sub(2).."}")
end

end
\end{luacode*}

\begin{document}
\begin{go}
..W..W..
BB.BB..B
........
WWBBWWBB
\end{go}
\end{document}

• Thanks, Jonathan! I'll give this a try and see if it will work for me. It looks very promising. – JDH May 14 '18 at 11:28