- Blackout
- Faster Than Light
- Hex Board
- Invariants
- Listening To OEIS
- Logic Gates
- Penrose Maze
- Syntactic Sugar
- Terminal Colors

- Traffic Engineering with Portals, Part II
- Traffic Engineering with Portals
- Algebra and Data Types
- What's a Confidence Interval?

- Hilbert's Curve
- Preventing Log4j with Capabilities
- Traffic Engineering with Portals, Part II
- Traffic Engineering with Portals
- Algebra and Data Types
- What's a Confidence Interval?
- Uncalibrated quantum experiments act clasically
- Pixel to Hex
- Linear vs Binary Search
- There and Back Again
- Tree Editor Survey
- Rust Quick Reference
- The Prisoners' Lightbulb
- Notes on Concurrency
- It's a blog now!

A triangular Hex board. Print two copies and tape them together to make an 11x11 board.

There are just three fully symmetric ways to arrange points on a plane:

Pattern 1: • • • • • • • • • • • • • • • • • • • • • • • • • Pattern 2: • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • Pattern 3: • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • •

Some board games let you place pieces in one of these patterns: checkers, chess, and Go use Pattern 1, while hex and chinese checkers use Pattern 2. I don’t know of any game that uses the third.

You might think that these three patterns of points are just the three regular tesselations of the plane: a square grid, a triangular grid, and a hexagonal grid. And they are, but which one is which is actually ambiguous!

In the US, we are used to placing pieces at the center of tiles. By this convention, Pattern 1 comes from a square grid, Pattern 2 comes from a hexagonal grid, and Pattern 3 comes from a triangular grid.

But Go uses a different convention - you place pieces at the intersections of
the lines. Go still uses a square grid; you just place the pieces differently.
By *this* convention, Pattern 1 (still) comes from a square grid, Pattern 2
comes from a triangular grid, and Pattern 3 comes from a hexagonal grid. So the
hex and triangular grids are swapped. There’s a name for this: triangular and
hexagonal tilings are duals of each
other, and a square grid is its own dual.

Anyhow, all of this means that there are two kinds of boards you can play Hex on. You can either play on a hexagonal grid and place pieces on the tiles, or play on a triangular grid and place pieces on the intersections. I find that I prefer the latter. But there’s a surprising lack of triangular hex board grids on the internet, though, so I wrote my own in Postscript. I wanted it to fit Go stones and be at least size 11, making it too big to fit on one page. So here is:

```
%!PS
%%Orientation: Landscape
% Take param array , and bind each param.
% e.g. 8 3 [/x /y] params x y sub -> 5
/params {
dup length 1 sub -1 0 % Iterate over array in reverse
{1 index exch get 3 -1 roll def} % Define each parameter
for pop % Pop the array
} def
% Use /params to define a function.
% Just don't use recursion :-/
% Or re-use variable names in functions that call each other...
/func {
/params cvx exch /bind cvx /exec cvx
5 packedarray cvx
def
} def
/halve {2 div} def
/inch {72 mul} def
/mm {inch 25.4 div} def
/ratio 30 cos def
/pagewidth 11 inch def
/pageheight 8.5 inch def
/tostring {20 string cvs} def
/drawline {newpath 4 2 roll moveto lineto stroke} def
/addpt {a b c d} {a c add b d add} func
/boardsize 7 def
/cells {0.84 inch mul} def
/border 0.4 inch def
% Put (0, 0) in the lower-left corner of the landscaped page
90 rotate 0 pageheight neg translate
/Ariel findfont 20 scalefont setfont
% The Drawing %
/S_iter 500 def
/S { % debugging
100 S_iter moveto tostring show
/S_iter S_iter 20 sub def
} def
/cellcoord {x y} {
x cells
y cells halve add
border add
y cells ratio mul
border add
} func
/gridline {a b c d} {
a b cellcoord c d cellcoord drawline
} func
/thickgridline {5 setlinewidth gridline 1 setlinewidth} def
% unused
/parellelogram {s} {
/parellelogram_iter {i} {
i 0 i s gridline
0 i s i gridline
i 0 0 i gridline
i s s i gridline
} func
0 1 s {parellelogram_iter} for
} func
/triangle {s} {
% draw the triangular grid
/triangle_iter {i} {
i 0 i s i sub gridline
0 i s i sub i gridline
i 0 0 i gridline
} func
0 1 s {triangle_iter} for
% draw the edge labels
-0.3 0.3 -0.3 s thickgridline
0.25 -0.25 cellcoord s -0.25 cellcoord drawline
0.30 -0.35 cellcoord s 0.05 add -0.35 cellcoord drawline
} func
11 triangle
showpage
```