TikZ-PGF – Drawing Hex Boards

tikz-pgf

I need to draw a Hex board. I would like to be able to mark each hexagon and mark the size. Being able to control the thickness of the lines would be nice, but it is not something I need to have. Could anyone suggest a simple way of doing this?

Here is a picture of what I had in mind:

http://i.imgur.com/VUkqMYE.png

EDIT: Cmhughes brought up some pointers on making this post better, so here it goes!

I have found very little material to help me through this. However, I found this on the stackexchange forum. I have tried modifying the code (from the first answer) to fit my needs (as shown in the picture), but every time I change something the graph does some very weird things, like creating a large line of hexagons in what appears to be a random direction.

My problem, then, is that I have no idea how I would modify the code to make it a Hex board, rather than a Hex map.

This is the code I am referring to:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{shapes}

\begin{document}
  \begin{tikzpicture}[
    hexa/.style={ 
      shape=regular polygon,
      regular polygon sides=6,
      minimum size=1cm,
      draw,
      inner sep=0,
      anchor=south,
      fill=lightgray!85!blue,
      rotate=30
    }
  ]
    \foreach \j in {0,...,5}{%
      \pgfmathsetmacro\end{5+\j} 
      \foreach \i in {0,...,\end}{%
        \node[hexa] (h\i;\j) at ({(\i-\j/2)*sin(60)},{\j*0.75}) {};
      }
    }
    \foreach \j in {0,...,4}{%
      \pgfmathsetmacro\end{9-\j} 
      \foreach \i in {0,...,\end}{%
        \pgfmathtruncatemacro\k{\j+6}  
        \node[hexa] (h\i;\k) at ({(\i+\j/2-2)*sin(60)},{4.5+\j*0.75}) {};
      }
    }
    \foreach \k in {0,...,10} {%
      \node[circle,red,minimum size=1cm] at (h3;\k) {3;\k};
    }
    \foreach \k in {0,...,10} {%
      \node[circle,blue,minimum size=1cm] at (h1;\k) {1;\k};
    }
  \end{tikzpicture}
\end{document}

Does anyone have any pointers on how to modify the code?

Further, does anyone know how to mark the sides, like in the picture, and how to create a random-looking marking of the hexagons (although I this may have to simply be a lot of copying and pasting)?

Best Answer

enter image description here

This MWE with Asymptote uses struct hexboard from hexboard.asy module (attached). The board hb is created with the command hexboard hb=hexboard(11,xo); is 11 cells wide, the marks are prepared in the array of strings string[] xo;

Cell nodes and directions are as follows (direction is named after the node of destination):

enter image description here

The thick line is constructed by the start cell, optional prefix and suffix (if the line goes outside the grid), the node number to start with and a sequence of the directions. For example a command

hb.oline((-10,0), prefix=(0,-1),3,4,5,0);

uses the node 3 of the bottom cell (-10,0) as a starting point, prepends it with the line from below point (0,-1) and continue with directions 4,5 and 0 (4 segments in total).

Position of the leftmost cell is (0,0), rightmost cell is (n-1,0) the top is at (0,n-1), and the bottom is at (0,-(n-1)).

%
% hexboard.tex :
%
\begin{filecontents*}{hexboard.asy}
struct hexboard{
  int n;
  string[] xo;
  string xmark,omark;
  real dx,dy;

  pen gridPen;
  pen xCellBg;
  pen oCellBg;

  guide ghex;

  pair hexCenter(int k, int j){ // k= +/-
    return ((j+abs(k)/2)*dx,k*dy);
  }

  pair hexCorner(int k, int j, int a){ 
    return shift(hexCenter(k,j))*point(ghex,a%6);
  }

  void dot(int k, int j, int a, pen p=gridPen){
    dot(hexCorner(k,j,a),p,UnFill);
  }

  void dots(int k, int j, int a, int b, pen p=gridPen){
    for(int i=a;i<=b;++i){
      dot(hexCorner(k,j,i),p,UnFill);
    }
  }

  void oline(explicit pair start, explicit pair prefix=(0,0), explicit pair suffix=(0,0), 
         explicit pen lpen=orange+2bp+opacity(0.8) ... int[]dirs){
    pair p=hexCorner((int)start.x,(int)start.y,dirs[0]);
    guide g=(p+prefix)--p;
    for(int i=1;i<dirs.length;++i){
      p+=dir(150+(dirs[i]%6)*60);
      g=g--p;
    }
    g=g--(p+suffix);
    draw(g,lpen);
  }

  void drawHex(int k, int j){
    pen bg=(substr(xo[n-1-k],j,1)=="x")?xCellBg:oCellBg;
    filldraw(shift((j+abs(k)/2)*dx,k*dy)*ghex,bg,gridPen);
  }

  void markCell(int k, int j, string v){
    if(v=="x")v=xmark;
    if(v=="o")v=omark;
    label(v,hexCenter(k,j));
  }

  void mark(){
    assert(xo.length==2n-1);
    bool b;
    string c;
    int k;
    for(int i=0;i<n;++i){
      assert(length(xo[i])==i+1);
      k=n-1-i;
      for(int j=0;j<i+1;++j){
        c=substr(xo[i],j,1);
        drawHex(k,j);
        markCell(k,j,c);
      }
    }
    for(int i=n;i<2n-1;++i){
      assert(length(xo[i])==2n-1-i);
      k=n-1-i;
      for(int j=0;j<2n-1-i;++j){
        c=substr(xo[i],j,1);
        drawHex(k,j);
        markCell(k,j,c);
      }
    }
  }

  void operator init(int n // board width
      ,string[] xo         // board marks
      ,string xmark="$\times$"
      ,string omark="$\circ$"
      ,pen gridPen=deepblue+0.4bp
      ,pen xCellBg=palered
      ,pen oCellBg=palegreen
    ){
    this.n=n; 
    this.xo=copy(xo);
    this.xmark=xmark; this.omark=omark;
    this.xCellBg=xCellBg; this.oCellBg=oCellBg;
    this.dx=sqrt(3);
    this.dy=1+1/2;
    this.ghex=dir(90)--dir(150)--dir(210)--dir(270)--dir(330)--dir(30)--cycle;
    mark();
  }
}
\end{filecontents*}
%
\documentclass{article}
\usepackage[inline]{asymptote}
\usepackage{lmodern}
\begin{document}
\begin{figure}
\centering
\begin{asy}
size(10cm);

// === test hexboard
import hexboard;
string[] xo={
"o",
"xo",
"xxx",
"ooox",
"xxoox",
"xxoooo",
"oxxoxxo",
"xoxooxxx",
"oxooxooox",
"xooxooxooo",
"oxxxoxooxxo",
"oooxoxxoxx",
"xxxoxooxo",
"ooxooxxo",
"xxoooxo",
"ooxxxo",
"xoxoo",
"xoxx",
"oxo",
"xo",
"x",
};

hexboard hb=hexboard(11,xo);

label("$v$",hb.hexCorner(0,0,2)-(1,0),W);
label("$v^\prime$",hb.hexCorner(0,10,5)+(1,0),E);

label("$w$",hb.hexCorner(-10,0,3)-(0,1),S);
label("$w^\prime$",hb.hexCorner(10,0,0)+(0,1),N);

label("$o^\prime$",hb.hexCorner(5,0,1)-(1,0),W);
label("$x^-$",hb.hexCorner(5,5,5)+(1,0),E);

hb.oline((5,0),0,1,2,3,2,3,2,3,4,5,4,5,0,5, 4,5,0,1,0,1,2);
hb.oline((10,0), prefix=(0,1) ,suffix=(1,0)
,0
,3,2,3,2,1,0,5,0,1,2,1,2,3,4,3,4,3,2,3,2,3,4
,3,2,3,2,1,0,5,0,1,0,1,2,3,2,3,4
,3,2,3,4
,3,4,3,2,3);

hb.oline((0,0), prefix=(-1,0),2,3,2,3,4);

hb.oline((-10,0), prefix=(0,-1),3,4,5,0);

hb.dot(9,0,3);
hb.dot(7,1,4);
hb.dots(5,1,0,3);

shipout(bbox(Fill(lightyellow)));

\end{asy}
\caption{Hex Board}
\end{figure}
\end{document}
%
% Process :
%
% pdflatex hexboard.tex    
% asy hexboard-*.asy    
% pdflatex hexboard.tex