29

A friend is trying to make some auto-generated bingo boards, and LaTeX seems like an obvious choice - nothing fancy, just a 5x5 table with square cells, centered text, and line wrapping if necessary. After some searching, I'm at a bit of a loss on setting the vertical height of cells, though. How can I do this?

Given the length of the terms to put in the squares (e.g. "Speech Language Pathologist") I don't think it's reasonable to go for anything but a full sheet of letter paper. (They'll be printed, special paper would be a pain, and two on a sheet is pretty small for that.) Otherwise there aren't really any hard formatting requirements - a legible size, and might as well fill the page as long as you've got it. I'm sure I can adjust details, in any case.

2
  • Greetings, and welcome to TeX.SE! Please be a bit more specific about some of your document parameters, such as the size of the sheet of paper and the size of the textblock. Mentioning any requirements regarding fonts (font type, font size) would also be helpful.
    – Mico
    Mar 28, 2012 at 3:06
  • Related Question: How do I make a square table in LaTeX? Mar 28, 2012 at 18:32

4 Answers 4

17

Randomly Generating the Nodes:

Here is a version that randomly generated the nodes using that random number generator built into pgf using the algorithm:

  • Column B contains numbers 1 - 15
  • Column I contains numbers 16 - 30
  • Column N contains numbers 31 - 45
  • Column G contains numbers 46 - 60
  • Column O contains numbers 61 - 75

enter image description here

Further Enhancements:

  • Not sure if duplicated numbers are allowed in a column, if not then this can be enhanced to loop if a previously used number is generated
  • Add a fancy border and label the columns: B, I, N, G, O

Code:

\documentclass{article}
\usepackage{xstring}
\usepackage{tikz}
\usetikzlibrary{calc}

%    Column B contains numbers 1 - 15
%    Column I contains numbers 16 - 30
%    Column N contains numbers 31 - 45
%    Column G contains numbers 46 - 60
%    Column O contains numbers 61 - 75

\def\NumOfColumns{5}%
\def\Sequence{1/A/1/15, 2/B/16/30, 3/C/31/45, 4/D/46/60, 5/E/61/71}%

\newcommand{\Size}{2.5cm}
\tikzset{Square/.style={
    inner sep=0pt,
    text width=\Size, 
    minimum size=\Size,
    draw=black,
    fill=yellow!20,
    align=center,
    }
}

\begin{document}
\begin{tikzpicture}[draw=black, ultra thick, x=\Size,y=\Size]
    \foreach \row/\rowLetter/\MinNumber/\MaxNumber in \Sequence{%
        \foreach \col/\colLetter/\MinNumber/\MaxNumber in \Sequence {%
            \pgfmathtruncatemacro{\value}{\col+\NumOfColumns*(\row-1)}
            \def\NodeText{\pgfmathparse{random(\MinNumber,\MaxNumber)}\pgfmathresult}
            \pgfmathsetmacro{\ColRowProduce}{\col*\row}
            \IfEq{\ColRowProduce}{9}{% If is center square
                \node [Square] at ($(\col,-\row)-(0.5,0.5)$) {\Huge Free Space};
            }{
                \node [Square] at ($(\col,-\row)-(0.5,0.5)$) {\Huge \NodeText};
            }
        }
    }
\end{tikzpicture}
\end{document}

Manually Specifying the Nodes:

I am not sure how you want to set the contents of each cell to be specified, so I provided individual \Node<col><row> macros that you can fill in. If there is an algorithm for choosing those then that too can be automated.

The following uses TikZ nodes. You can change the setting of \Size to specify the length of the side of the square.

enter image description here

Code:

\documentclass{article}
\usepackage{xstring}
\usepackage{tikz}
\usetikzlibrary{calc}

\newcommand{\Size}{2.5cm}% Adjust size of square as desired

\def\NumOfColumns{5}%
\def\Sequence{1/A, 2/B, 3/C, 4/D, 5/E}% This needs to match \NumOfColumns 

\tikzset{Square/.style={
    inner sep=0pt,
    text width=\Size, 
    minimum size=\Size,
    draw=black,
    fill=yellow!20,
    align=center
    }
}

% Define the contents of the cells here.
\newcommand{\NodeAA}{Node $(1,1)$}%
\newcommand{\NodeAB}{Node $(1,2)$}%
\newcommand{\NodeAC}{Node $(1,3)$}%
\newcommand{\NodeAD}{Node $(1,4)$}%
\newcommand{\NodeAE}{Node $(1,5)$}%

\newcommand{\NodeBA}{Node $(2,1)$}%
\newcommand{\NodeBB}{Node $(2,2)$}%
\newcommand{\NodeBC}{Node $(2,3)$}%
\newcommand{\NodeBD}{Node $(2,4)$}%
\newcommand{\NodeBE}{Node $(2,5)$}%

\newcommand{\NodeCA}{Node $(3,1)$}%
\newcommand{\NodeCB}{Node $(3,2)$}%
\newcommand{\NodeCC}{Node $(3,3)$}%
\newcommand{\NodeCD}{Node $(3,4)$}%
\newcommand{\NodeCE}{Node $(3,5)$}%

\newcommand{\NodeDA}{Node $(4,1)$}%
\newcommand{\NodeDB}{Node $(5,2)$}%
\newcommand{\NodeDC}{Node $(5,3)$}%
\newcommand{\NodeDD}{Node $(5,4)$}%
\newcommand{\NodeDE}{Node $(5,5)$}%

\newcommand{\NodeEA}{Node $(5,1)$}%
\newcommand{\NodeEB}{Node $(5,2)$}%
\newcommand{\NodeEC}{Node $(5,3)$}%
\newcommand{\NodeED}{Node $(5,4)$}%
\newcommand{\NodeEE}{Node $(5,5)$}%

\begin{document}
\begin{tikzpicture}[draw=black, ultra thick, x=\Size,y=\Size]
    \foreach \col/\colLetter in \Sequence {%
        \foreach \row/\rowLetter in \Sequence{%
            \pgfmathtruncatemacro{\value}{\col+\NumOfColumns*(\row-1)}
            \def\NodeText{\expandafter\csname Node\rowLetter\colLetter\endcsname}
            \node [Square] at ($(\col,-\row)-(0.5,0.5)$) {\NodeText};
        }
    }
\end{tikzpicture}
\end{document}
5
  • This looks great. I'm generating a lot of different sets of "node" values, so my use is a little different, but it certainly does what I wanted! I'm surprised the better answer (so far) wasn't just some fancy tabular environment.
    – Cascabel
    Mar 28, 2012 at 3:59
  • @Jefromi: Well that's a reason why one should always compose a fully compilable MWE, at least up to what you have so far so that the solution you get actually works for you. Updated version randomly generates the nodes based on the algorithm described. Mar 28, 2012 at 4:23
  • No, I mean this does work for me - I like getting minimal working examples as answers. I'm perfectly happy having the generation outside of TeX, and that's not at all part of the question, because I'm doing some smart things that I'd rather do with a full programming language.
    – Cascabel
    Mar 28, 2012 at 4:42
  • Great answer ! I was wondering how you would do if you wanted to have to color of the square be an argument ? So that each square can have its own. Thanks !
    – Riff
    Jul 19, 2016 at 16:04
  • 1
    @Nicolas:Welcome to TeX.SE. I would just add one more paramater to the slash separated list that is passed to the \foreach. If that does not achieve the desired results, please aks a new question. You can reference this question and please include a MWE to set up the problem. Feel free to cut and paste and use this as a starting point. Jul 19, 2016 at 19:32
34
\documentclass[border=20pt]{standalone}
\usepackage[thinlines]{easytable}
\begin{document}

\huge
\begin{TAB}(e,2cm,2cm){|c:c:c:c:c|}{|c:c:c:c:c|}
1 & 2 & 3 & 4 & 5 \\
6 & 7 &   &   &   \\
  &   &   &   &   \\
  &   &   &   &   \\
  &   &   &   &     
\end{TAB}
\end{document}

enter image description here

4
13

The following very nice article by Will Robertson published in the PracTeX Journal describes how to make a square cells environment using basic array techniques. I haven't included any specific code for entering the cells; depending on how the cells are generated I might be inclined to use the datatool package and read in the boards from a CSV file. This would be simple to adapt to this table style.

Square cells: an array cooking lesson

Here's an example:

% This code written by Will Robertson and published in PracTeX Journal 2005-2
% "Square cells: an array cooking lesson"
% Modified for line wrapping

\documentclass{article}
\usepackage{array}
\usepackage{calc}

\newlength\celldim
\newlength\fontheight
\newlength\extraheight
\newcounter{sqcolumns}

\newcolumntype{S}{
 @{}
 >{\centering \rule[-0.5\extraheight]{0pt}{\fontheight + \extraheight}%
 \begin{minipage}{\celldim}\centering}
 p{\celldim}
 <{\end{minipage}} 
 @{} }

\newcolumntype{Z}{ @{} >{\centering} p{\celldim} @{} }

\newenvironment{squarecells}[1]
  {\setlength\celldim{4.5em}%
   \settoheight\fontheight{A}%
   \setlength\extraheight{\celldim - \fontheight}%
   \setcounter{sqcolumns}{#1 - 1}%
   \begin{tabular}{|S|*{\value{sqcolumns}}{Z|}}\hline}
% squarecells tabular goes here
  {\end{tabular}}

\newcommand\nl{\tabularnewline\hline}

\begin{document}
  \Huge
  \begin{squarecells}{4}
    This is a long line & 3  & 2  & 13 \nl
    5  & 10 & 11 & 8  \nl
    9  & 6  & 7  & 12 \nl
    4  & 15 & 14 & 1  \nl
  \end{squarecells}
\end{document}

output of code

3
  • This seems to sometimes do some weird things when the text in the cells wraps - the first line centered and second line going to the bottom of the cell.
    – Cascabel
    Mar 28, 2012 at 3:42
  • @Jefromi I've updated the answer to solve the wrapping problem. Thanks for pointing it out.
    – Alan Munn
    Mar 28, 2012 at 4:10
  • Can it be modified to work with multirow{}{}{}? Nov 7, 2020 at 13:41
2

Using the tabstackengine package introduced at Writing a table with equally spaced columns, based on the widest column, we have the following MWE. You can control the size of the box and rule thicknesses with the definitions of \fboxsep, \fboxrule, \mystrutwidth, and \mystrutdepth.

\documentclass{article}
\usepackage{tabstackengine}
\usepackage{fixltx2e}
% YOU CONTROL THE NEXT FOUR LINES
\fboxsep=3pt
\fboxrule=.8pt
\def\mystrutwidth{2.5\baselineskip}
\def\mystrutdepth{1\baselineskip}
%
\def\mystrut{\rule[-\mystrutdepth]{0ex}{\mystrutwidth}}
\newcommand\bngo[1]{\kern-\fboxrule\fbox{\mystrut\makebox[\mystrutwidth]{#1}}}%
\setstackgap{L}{\mystrutwidth+2\fboxsep+\fboxrule}
\begin{document}
\tabbedLongstack{
\bngo{8} & \bngo{29} & \bngo{45} & \bngo{54} & \bngo{68}\\
\bngo{9} & \bngo{19} & \bngo{40} & \bngo{49} & \bngo{67}\\
\bngo{15} & \bngo{24} & \stackanchor{Free}{Space} & \bngo{46} & \bngo{71}\\
\bngo{7} & \bngo{26} & \bngo{32} & \bngo{60} & \bngo{64}\\
\bngo{14} & \bngo{28} & \bngo{37} & \bngo{46} & \bngo{66}
}
\end{document}

enter image description here

3
  • Nice! Any way to avoid wrapping every cell element with \bngo{}?
    – PatrickT
    Sep 23, 2022 at 1:28
  • 1
    @PatrickT It might be possible if every cell of the table were to be wrapped in \bngo. However, the example above has one cell (the center) that is not wrapped. Sep 26, 2022 at 13:08
  • Thanks Steven, good to know.
    – PatrickT
    Sep 27, 2022 at 19:44

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .