Skip to content

Instantly share code, notes, and snippets.

@hoverbird
Created September 21, 2025 23:48
Show Gist options
  • Select an option

  • Save hoverbird/9f115f3d7a8a99f9bfb3e4b262111a44 to your computer and use it in GitHub Desktop.

Select an option

Save hoverbird/9f115f3d7a8a99f9bfb3e4b262111a44 to your computer and use it in GitHub Desktop.
HexGrid.ts — classic set of utils for dealing wtih hexagonal grids by Red Blob Games, updated to use modern TypeScript standards and practices
<!--
// Based on the classic utilities released by Red Blob Games, detailed here: http://www.redblobgames.com/grids/hexagons/
// Updated from their generated .ts code to use modern TypeScript style/standards by @hoverbird
// Original and updated code area released as CC0 -- No Rights Reserved: https://creativecommons.org/public-domain/cc0/
// Code provided as-is with no warranties or guarantees.
The code now follows all Deno-friendly TypeScript standards:
- ✅ **No `erasableSyntaxOnly` violations** - Explicit property declarations instead of constructor parameter properties
- ✅ **No `var` keywords** - All replaced with appropriate `let`/`const`
- ✅ **Proper type annotations** - `string` instead of `String`, no implicit `any`
- ✅ **Modern TypeScript practices** - Block-scoped declarations, immutable where appropriate
-->
export class Point {
public x: number;
public y: number;
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
}
export class Hex {
public q: number;
public r: number;
public s: number;
constructor(q: number, r: number, s: number) {
if (Math.round(q + r + s) !== 0) throw "q + r + s must be 0";
this.q = q;
this.r = r;
this.s = s;
}
public add(b: Hex): Hex {
return new Hex(this.q + b.q, this.r + b.r, this.s + b.s);
}
public subtract(b: Hex): Hex {
return new Hex(this.q - b.q, this.r - b.r, this.s - b.s);
}
public scale(k: number): Hex {
return new Hex(this.q * k, this.r * k, this.s * k);
}
public rotateLeft(): Hex {
return new Hex(-this.s, -this.q, -this.r);
}
public rotateRight(): Hex {
return new Hex(-this.r, -this.s, -this.q);
}
public static directions: Hex[] = [new Hex(1, 0, -1), new Hex(1, -1, 0), new Hex(0, -1, 1), new Hex(-1, 0, 1), new Hex(-1, 1, 0), new Hex(0, 1, -1)];
public static direction(direction: number): Hex {
return Hex.directions[direction];
}
public neighbor(direction: number): Hex {
return this.add(Hex.direction(direction));
}
public static diagonals: Hex[] = [new Hex(2, -1, -1), new Hex(1, -2, 1), new Hex(-1, -1, 2), new Hex(-2, 1, 1), new Hex(-1, 2, -1), new Hex(1, 1, -2)];
public diagonalNeighbor(direction: number): Hex {
return this.add(Hex.diagonals[direction]);
}
public len(): number {
return (Math.abs(this.q) + Math.abs(this.r) + Math.abs(this.s)) / 2;
}
public distance(b: Hex): number {
return this.subtract(b).len();
}
public round(): Hex {
let qi: number = Math.round(this.q);
let ri: number = Math.round(this.r);
let si: number = Math.round(this.s);
const q_diff: number = Math.abs(qi - this.q);
const r_diff: number = Math.abs(ri - this.r);
const s_diff: number = Math.abs(si - this.s);
if (q_diff > r_diff && q_diff > s_diff) {
qi = -ri - si;
}
else
if (r_diff > s_diff) {
ri = -qi - si;
}
else {
si = -qi - ri;
}
return new Hex(qi, ri, si);
}
public lerp(b: Hex, t: number): Hex {
return new Hex(this.q * (1.0 - t) + b.q * t, this.r * (1.0 - t) + b.r * t, this.s * (1.0 - t) + b.s * t);
}
public linedraw(b: Hex): Hex[] {
const N: number = this.distance(b);
const a_nudge: Hex = new Hex(this.q + 1e-06, this.r + 1e-06, this.s - 2e-06);
const b_nudge: Hex = new Hex(b.q + 1e-06, b.r + 1e-06, b.s - 2e-06);
const results: Hex[] = [];
const step: number = 1.0 / Math.max(N, 1);
for (let i = 0; i <= N; i++) {
results.push(a_nudge.lerp(b_nudge, step * i).round());
}
return results;
}
}
export class OffsetCoord {
public col: number;
public row: number;
constructor(col: number, row: number) {
this.col = col;
this.row = row;
}
public static EVEN: number = 1;
public static ODD: number = -1;
public static qoffsetFromCube(offset: number, h: Hex): OffsetCoord {
const parity: number = h.q & 1;
const col: number = h.q;
const row: number = h.r + (h.q + offset * parity) / 2;
if (offset !== OffsetCoord.EVEN && offset !== OffsetCoord.ODD) {
throw "offset must be EVEN (+1) or ODD (-1)";
}
return new OffsetCoord(col, row);
}
public static qoffsetToCube(offset: number, h: OffsetCoord): Hex {
const parity: number = h.col & 1;
const q: number = h.col;
const r: number = h.row - (h.col + offset * parity) / 2;
const s: number = -q - r;
if (offset !== OffsetCoord.EVEN && offset !== OffsetCoord.ODD) {
throw "offset must be EVEN (+1) or ODD (-1)";
}
return new Hex(q, r, s);
}
public static roffsetFromCube(offset: number, h: Hex): OffsetCoord {
const parity: number = h.r & 1;
const col: number = h.q + (h.r + offset * parity) / 2;
const row: number = h.r;
if (offset !== OffsetCoord.EVEN && offset !== OffsetCoord.ODD) {
throw "offset must be EVEN (+1) or ODD (-1)";
}
return new OffsetCoord(col, row);
}
public static roffsetToCube(offset: number, h: OffsetCoord): Hex {
const parity: number = h.row & 1;
const q: number = h.col - (h.row + offset * parity) / 2;
const r: number = h.row;
const s: number = -q - r;
if (offset !== OffsetCoord.EVEN && offset !== OffsetCoord.ODD) {
throw "offset must be EVEN (+1) or ODD (-1)";
}
return new Hex(q, r, s);
}
public static qoffsetFromQdoubled(offset: number, h: DoubledCoord): OffsetCoord {
const parity: number = h.col & 1;
return new OffsetCoord(h.col, (h.row + offset * parity) / 2);
}
public static qoffsetToQdoubled(offset: number, h: OffsetCoord): DoubledCoord {
const parity: number = h.col & 1;
return new DoubledCoord(h.col, 2 * h.row - offset * parity);
}
public static roffsetFromRdoubled(offset: number, h: DoubledCoord): OffsetCoord {
const parity: number = h.row & 1;
return new OffsetCoord((h.col + offset * parity) / 2, h.row);
}
public static roffsetToRdoubled(offset: number, h: OffsetCoord): DoubledCoord {
const parity: number = h.row & 1;
return new DoubledCoord(2 * h.col - offset * parity, h.row);
}
}
export class DoubledCoord {
public col: number;
public row: number;
constructor(col: number, row: number) {
this.col = col;
this.row = row;
}
public static qdoubledFromCube(h: Hex): DoubledCoord {
const col: number = h.q;
const row: number = 2 * h.r + h.q;
return new DoubledCoord(col, row);
}
public qdoubledToCube(): Hex {
const q: number = this.col;
const r: number = (this.row - this.col) / 2;
const s: number = -q - r;
return new Hex(q, r, s);
}
public static rdoubledFromCube(h: Hex): DoubledCoord {
const col: number = 2 * h.q + h.r;
const row: number = h.r;
return new DoubledCoord(col, row);
}
public rdoubledToCube(): Hex {
const q: number = (this.col - this.row) / 2;
const r: number = this.row;
const s: number = -q - r;
return new Hex(q, r, s);
}
}
export class Orientation {
public f0: number;
public f1: number;
public f2: number;
public f3: number;
public b0: number;
public b1: number;
public b2: number;
public b3: number;
public start_angle: number;
constructor(f0: number, f1: number, f2: number, f3: number, b0: number, b1: number, b2: number, b3: number, start_angle: number) {
this.f0 = f0;
this.f1 = f1;
this.f2 = f2;
this.f3 = f3;
this.b0 = b0;
this.b1 = b1;
this.b2 = b2;
this.b3 = b3;
this.start_angle = start_angle;
}
}
export class Layout {
public orientation: Orientation;
public size: Point;
public origin: Point;
constructor(orientation: Orientation, size: Point, origin: Point) {
this.orientation = orientation;
this.size = size;
this.origin = origin;
}
public static pointy: Orientation = new Orientation(Math.sqrt(3.0), Math.sqrt(3.0) / 2.0, 0.0, 3.0 / 2.0, Math.sqrt(3.0) / 3.0, -1.0 / 3.0, 0.0, 2.0 / 3.0, 0.5);
public static flat: Orientation = new Orientation(3.0 / 2.0, 0.0, Math.sqrt(3.0) / 2.0, Math.sqrt(3.0), 2.0 / 3.0, 0.0, -1.0 / 3.0, Math.sqrt(3.0) / 3.0, 0.0);
public hexToPixel(h: Hex): Point {
const M: Orientation = this.orientation;
const size: Point = this.size;
const origin: Point = this.origin;
const x: number = (M.f0 * h.q + M.f1 * h.r) * size.x;
const y: number = (M.f2 * h.q + M.f3 * h.r) * size.y;
return new Point(x + origin.x, y + origin.y);
}
public pixelToHexFractional(p: Point): Hex {
const M: Orientation = this.orientation;
const size: Point = this.size;
const origin: Point = this.origin;
const pt: Point = new Point((p.x - origin.x) / size.x, (p.y - origin.y) / size.y);
const q: number = M.b0 * pt.x + M.b1 * pt.y;
const r: number = M.b2 * pt.x + M.b3 * pt.y;
return new Hex(q, r, -q - r);
}
public pixelToHexRounded(p: Point): Hex {
return this.pixelToHexFractional(p).round();
}
public hexCornerOffset(corner: number): Point {
const M: Orientation = this.orientation;
const size: Point = this.size;
const angle: number = 2.0 * Math.PI * (M.start_angle - corner) / 6.0;
return new Point(size.x * Math.cos(angle), size.y * Math.sin(angle));
}
public polygonCorners(h: Hex): Point[] {
const corners: Point[] = [];
const center: Point = this.hexToPixel(h);
for (let i = 0; i < 6; i++) {
const offset: Point = this.hexCornerOffset(i);
corners.push(new Point(center.x + offset.x, center.y + offset.y));
}
return corners;
}
}
class Tests {
constructor() { }
public static equalHex(name: string, a: Hex, b: Hex): void {
if (!(a.q === b.q && a.s === b.s && a.r === b.r)) {
complain(name);
}
}
public static equalOffsetcoord(name: string, a: OffsetCoord, b: OffsetCoord): void {
if (!(a.col === b.col && a.row === b.row)) {
complain(name);
}
}
public static equalDoubledcoord(name: string, a: DoubledCoord, b: DoubledCoord): void {
if (!(a.col === b.col && a.row === b.row)) {
complain(name);
}
}
public static equalInt(name: string, a: number, b: number): void {
if (!(a === b)) {
complain(name);
}
}
public static equalHexArray(name: string, a: Hex[], b: Hex[]): void {
Tests.equalInt(name, a.length, b.length);
for (let i = 0; i < a.length; i++) {
Tests.equalHex(name, a[i], b[i]);
}
}
public static testHexArithmetic(): void {
Tests.equalHex("hex_add", new Hex(4, -10, 6), new Hex(1, -3, 2).add(new Hex(3, -7, 4)));
Tests.equalHex("hex_subtract", new Hex(-2, 4, -2), new Hex(1, -3, 2).subtract(new Hex(3, -7, 4)));
}
public static testHexDirection(): void {
Tests.equalHex("hex_direction", new Hex(0, -1, 1), Hex.direction(2));
}
public static testHexNeighbor(): void {
Tests.equalHex("hex_neighbor", new Hex(1, -3, 2), new Hex(1, -2, 1).neighbor(2));
}
public static testHexDiagonal(): void {
Tests.equalHex("hex_diagonal", new Hex(-1, -1, 2), new Hex(1, -2, 1).diagonalNeighbor(3));
}
public static testHexDistance(): void {
Tests.equalInt("hex_distance", 7, new Hex(3, -7, 4).distance(new Hex(0, 0, 0)));
}
public static testHexRotateRight(): void {
Tests.equalHex("hex_rotate_right", new Hex(1, -3, 2).rotateRight(), new Hex(3, -2, -1));
}
public static testHexRotateLeft(): void {
Tests.equalHex("hex_rotate_left", new Hex(1, -3, 2).rotateLeft(), new Hex(-2, -1, 3));
}
public static testHexRound(): void {
const a: Hex = new Hex(0.0, 0.0, 0.0);
const b: Hex = new Hex(1.0, -1.0, 0.0);
const c: Hex = new Hex(0.0, -1.0, 1.0);
Tests.equalHex("hex_round 1", new Hex(5, -10, 5), new Hex(0.0, 0.0, 0.0).lerp(new Hex(10.0, -20.0, 10.0), 0.5).round());
Tests.equalHex("hex_round 2", a.round(), a.lerp(b, 0.499).round());
Tests.equalHex("hex_round 3", b.round(), a.lerp(b, 0.501).round());
Tests.equalHex("hex_round 4", a.round(), new Hex(a.q * 0.4 + b.q * 0.3 + c.q * 0.3, a.r * 0.4 + b.r * 0.3 + c.r * 0.3, a.s * 0.4 + b.s * 0.3 + c.s * 0.3).round());
Tests.equalHex("hex_round 5", c.round(), new Hex(a.q * 0.3 + b.q * 0.3 + c.q * 0.4, a.r * 0.3 + b.r * 0.3 + c.r * 0.4, a.s * 0.3 + b.s * 0.3 + c.s * 0.4).round());
}
public static testHexLinedraw(): void {
Tests.equalHexArray("hex_linedraw", [new Hex(0, 0, 0), new Hex(0, -1, 1), new Hex(0, -2, 2), new Hex(1, -3, 2), new Hex(1, -4, 3), new Hex(1, -5, 4)], new Hex(0, 0, 0).linedraw(new Hex(1, -5, 4)));
}
public static testLayout(): void {
const h: Hex = new Hex(3, 4, -7);
const flat: Layout = new Layout(Layout.flat, new Point(10.0, 15.0), new Point(35.0, 71.0));
Tests.equalHex("layout", h, flat.pixelToHexRounded(flat.hexToPixel(h)));
const pointy: Layout = new Layout(Layout.pointy, new Point(10.0, 15.0), new Point(35.0, 71.0));
Tests.equalHex("layout", h, pointy.pixelToHexRounded(pointy.hexToPixel(h)));
}
public static testOffsetRoundtrip(): void {
for (let q = -2; q < 3; q++) {
for (let r = -2; r < 3; r++) {
const cube: Hex = new Hex(q, r, -q - r);
Tests.equalHex("conversion_roundtrip odd-q", cube, OffsetCoord.qoffsetToCube(OffsetCoord.ODD, OffsetCoord.qoffsetFromCube(OffsetCoord.ODD, cube)));
Tests.equalHex("conversion_roundtrip odd-r", cube, OffsetCoord.roffsetToCube(OffsetCoord.ODD, OffsetCoord.roffsetFromCube(OffsetCoord.ODD, cube)));
Tests.equalHex("conversion_roundtrip even-q", cube, OffsetCoord.qoffsetToCube(OffsetCoord.EVEN, OffsetCoord.qoffsetFromCube(OffsetCoord.EVEN, cube)));
Tests.equalHex("conversion_roundtrip even-r", cube, OffsetCoord.roffsetToCube(OffsetCoord.EVEN, OffsetCoord.roffsetFromCube(OffsetCoord.EVEN, cube)));
}
}
for (let col = -2; col < 3; col++) {
for (let row = -2; row < 3; row++) {
const offset: OffsetCoord = new OffsetCoord(col, row);
Tests.equalOffsetcoord("conversion_roundtrip odd-q", offset, OffsetCoord.qoffsetFromCube(OffsetCoord.ODD, OffsetCoord.qoffsetToCube(OffsetCoord.ODD, offset)));
Tests.equalOffsetcoord("conversion_roundtrip odd-r", offset, OffsetCoord.roffsetFromCube(OffsetCoord.ODD, OffsetCoord.roffsetToCube(OffsetCoord.ODD, offset)));
Tests.equalOffsetcoord("conversion_roundtrip even-q", offset, OffsetCoord.qoffsetFromCube(OffsetCoord.EVEN, OffsetCoord.qoffsetToCube(OffsetCoord.EVEN, offset)));
Tests.equalOffsetcoord("conversion_roundtrip even-r", offset, OffsetCoord.roffsetFromCube(OffsetCoord.EVEN, OffsetCoord.roffsetToCube(OffsetCoord.EVEN, offset)));
}
}
}
public static testOffsetFromCube(): void {
Tests.equalOffsetcoord("offset_from_cube odd-r", new OffsetCoord(-2, 2), OffsetCoord.roffsetFromCube(OffsetCoord.ODD, new Hex(-3, 2, 1)));
Tests.equalOffsetcoord("offset_from_cube odd-r", new OffsetCoord(1, -1), OffsetCoord.roffsetFromCube(OffsetCoord.ODD, new Hex(2, -1, -1)));
Tests.equalOffsetcoord("offset_from_cube even-r", new OffsetCoord(-2, 2), OffsetCoord.roffsetFromCube(OffsetCoord.EVEN, new Hex(-3, 2, 1)));
Tests.equalOffsetcoord("offset_from_cube even-r", new OffsetCoord(2, -1), OffsetCoord.roffsetFromCube(OffsetCoord.EVEN, new Hex(2, -1, -1)));
Tests.equalOffsetcoord("offset_from_cube odd-q", new OffsetCoord(-2, 2), OffsetCoord.qoffsetFromCube(OffsetCoord.ODD, new Hex(-2, 3, -1)));
Tests.equalOffsetcoord("offset_from_cube odd-q", new OffsetCoord(-1, -2), OffsetCoord.qoffsetFromCube(OffsetCoord.ODD, new Hex(-1, -1, 2)));
Tests.equalOffsetcoord("offset_from_cube even-q", new OffsetCoord(-2, 2), OffsetCoord.qoffsetFromCube(OffsetCoord.EVEN, new Hex(-2, 3, -1)));
Tests.equalOffsetcoord("offset_from_cube even-q", new OffsetCoord(-1, -1), OffsetCoord.qoffsetFromCube(OffsetCoord.EVEN, new Hex(-1, -1, 2)));
}
public static testOffsetToCube(): void {
Tests.equalHex("offset_to_cube odd-r", new Hex(-3, 2, 1), OffsetCoord.roffsetToCube(OffsetCoord.ODD, new OffsetCoord(-2, 2)));
Tests.equalHex("offset_to_cube odd-r", new Hex(2, -1, -1), OffsetCoord.roffsetToCube(OffsetCoord.ODD, new OffsetCoord(1, -1)));
Tests.equalHex("offset_to_cube even-r", new Hex(-3, 2, 1), OffsetCoord.roffsetToCube(OffsetCoord.EVEN, new OffsetCoord(-2, 2)));
Tests.equalHex("offset_to_cube even-r", new Hex(2, -1, -1), OffsetCoord.roffsetToCube(OffsetCoord.EVEN, new OffsetCoord(2, -1)));
Tests.equalHex("offset_to_cube odd-q", new Hex(-2, 3, -1), OffsetCoord.qoffsetToCube(OffsetCoord.ODD, new OffsetCoord(-2, 2)));
Tests.equalHex("offset_to_cube odd-q", new Hex(-1, -1, 2), OffsetCoord.qoffsetToCube(OffsetCoord.ODD, new OffsetCoord(-1, -2)));
Tests.equalHex("offset_to_cube even-q", new Hex(-2, 3, -1), OffsetCoord.qoffsetToCube(OffsetCoord.EVEN, new OffsetCoord(-2, 2)));
Tests.equalHex("offset_to_cube even-q", new Hex(-1, -1, 2), OffsetCoord.qoffsetToCube(OffsetCoord.EVEN, new OffsetCoord(-1, -1)));
}
public static testOffsetToDoubled(): void {
for (let col = -2; col < 3; col++) {
for (let row = -2; row < 3; row++) {
const offset: OffsetCoord = new OffsetCoord(col, row);
Tests.equalDoubledcoord("offset_to_doubled loop odd-q", DoubledCoord.qdoubledFromCube(OffsetCoord.qoffsetToCube(OffsetCoord.ODD, offset)), OffsetCoord.qoffsetToQdoubled(OffsetCoord.ODD, offset));
Tests.equalDoubledcoord("offset_to_doubled loop even-q", DoubledCoord.qdoubledFromCube(OffsetCoord.qoffsetToCube(OffsetCoord.EVEN, offset)), OffsetCoord.qoffsetToQdoubled(OffsetCoord.EVEN, offset));
Tests.equalDoubledcoord("offset_to_doubled loop odd-r", DoubledCoord.rdoubledFromCube(OffsetCoord.roffsetToCube(OffsetCoord.ODD, offset)), OffsetCoord.roffsetToRdoubled(OffsetCoord.ODD, offset));
Tests.equalDoubledcoord("offset_to_doubled loop even-r", DoubledCoord.rdoubledFromCube(OffsetCoord.roffsetToCube(OffsetCoord.EVEN, offset)), OffsetCoord.roffsetToRdoubled(OffsetCoord.EVEN, offset));
const qdoubled: DoubledCoord = new DoubledCoord(col * 2 + (row & 1), row);
Tests.equalOffsetcoord("offset_from_doubled loop odd-q", OffsetCoord.qoffsetFromCube(OffsetCoord.ODD, qdoubled.qdoubledToCube()), OffsetCoord.qoffsetFromQdoubled(OffsetCoord.ODD, qdoubled));
Tests.equalOffsetcoord("offset_from_doubled loop even-q", OffsetCoord.qoffsetFromCube(OffsetCoord.EVEN, qdoubled.qdoubledToCube()), OffsetCoord.qoffsetFromQdoubled(OffsetCoord.EVEN, qdoubled));
const rdoubled: DoubledCoord = new DoubledCoord(col, row * 2 + (col & 1));
Tests.equalOffsetcoord("offset_from_doubled loop odd-r", OffsetCoord.roffsetFromCube(OffsetCoord.ODD, rdoubled.rdoubledToCube()), OffsetCoord.roffsetFromRdoubled(OffsetCoord.ODD, rdoubled));
Tests.equalOffsetcoord("offset_from_doubled loop even-r", OffsetCoord.roffsetFromCube(OffsetCoord.EVEN, rdoubled.rdoubledToCube()), OffsetCoord.roffsetFromRdoubled(OffsetCoord.EVEN, rdoubled));
}
}
}
public static testOffsetFromDoubled(): void {
}
public static testDoubledRoundtrip(): void {
for (let q = -2; q < 3; q++) {
for (let r = -2; r < 3; r++) {
const cube: Hex = new Hex(q, r, -q - r);
Tests.equalHex("conversion_roundtrip doubled-q", cube, DoubledCoord.qdoubledFromCube(cube).qdoubledToCube());
Tests.equalHex("conversion_roundtrip doubled-r", cube, DoubledCoord.rdoubledFromCube(cube).rdoubledToCube());
}
}
for (let col = -2; col < 3; col++) {
for (let row = -2; row < 3; row++) {
const qdoubled: DoubledCoord = new DoubledCoord(col * 2 + (row & 1), row);
Tests.equalDoubledcoord("conversion_roundtrip doubled-q", qdoubled, DoubledCoord.qdoubledFromCube(qdoubled.qdoubledToCube()));
const rdoubled: DoubledCoord = new DoubledCoord(col, row * 2 + (col & 1));
Tests.equalDoubledcoord("conversion_roundtrip doubled-r", rdoubled, DoubledCoord.rdoubledFromCube(rdoubled.rdoubledToCube()));
}
}
}
public static testDoubledFromCube(): void {
Tests.equalDoubledcoord("doubled_from_cube doubled-q", new DoubledCoord(1, 5), DoubledCoord.qdoubledFromCube(new Hex(1, 2, -3)));
Tests.equalDoubledcoord("doubled_from_cube doubled-r", new DoubledCoord(4, 2), DoubledCoord.rdoubledFromCube(new Hex(1, 2, -3)));
}
public static testDoubledToCube(): void {
Tests.equalHex("doubled_to_cube doubled-q", new Hex(1, 2, -3), new DoubledCoord(1, 5).qdoubledToCube());
Tests.equalHex("doubled_to_cube doubled-r", new Hex(1, 2, -3), new DoubledCoord(4, 2).rdoubledToCube());
}
public static testAll(): void {
Tests.testHexArithmetic();
Tests.testHexDirection();
Tests.testHexNeighbor();
Tests.testHexDiagonal();
Tests.testHexDistance();
Tests.testHexRotateRight();
Tests.testHexRotateLeft();
Tests.testHexRound();
Tests.testHexLinedraw();
Tests.testLayout();
Tests.testOffsetRoundtrip();
Tests.testOffsetFromCube();
Tests.testOffsetToCube();
Tests.testOffsetToDoubled();
Tests.testOffsetFromDoubled();
Tests.testDoubledRoundtrip();
Tests.testDoubledFromCube();
Tests.testDoubledToCube();
}
}
// Tests
function complain(name: string) { console.log("FAIL", name); }
Tests.testAll();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment