Skip to content

Commit

Permalink
Allow initializing hex with constructor function
Browse files Browse the repository at this point in the history
  • Loading branch information
butzopower committed Jan 1, 2022
1 parent 545512a commit 78ac12f
Show file tree
Hide file tree
Showing 2 changed files with 162 additions and 142 deletions.
12 changes: 10 additions & 2 deletions src/hexgrid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,18 @@ export class Hex<T = void> {
export class HexGrid<T = void> {
private readonly hexArray: Hex<T>[][]

constructor(width: number, height: number) {
constructor(
width: number,
height: number,
initializeFn?: () => T,
) {
this.hexArray = Array.from(new Array(height))
.map((_, y) => Array.from(new Array(width))
.map((_, x) => new Hex(this, x, y)));
.map((_, x) => {
const hex = new Hex(this, x, y);
hex.content = initializeFn ? initializeFn() : undefined;
return hex;
}));
}

at(x: number, y: number): Hex<T> {
Expand Down
292 changes: 152 additions & 140 deletions tests/hexgrid.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,150 +4,162 @@ import * as fc from "fast-check";
import { HexGrid } from "../src/hexgrid";

describe('a hex grid', () => {
describe('with a single hex', () => {
it('has no neighbors', () => {
const grid = new HexGrid(1, 1);
const hex = grid.at(0, 0);
expect(hex.neighbors).to.be.empty;
});
});

describe('a completely horizontal map', () => {
it('has neighbors left and right of tiles', () => {
const grid = new HexGrid(5, 1);

expect(grid.at(0, 0).neighbors).to.have.members([grid.at(1, 0)]);
expect(grid.at(1, 0).neighbors).to.have.members([grid.at(0, 0), grid.at(2, 0)]);
expect(grid.at(2, 0).neighbors).to.have.members([grid.at(1, 0), grid.at(3, 0)]);
expect(grid.at(3, 0).neighbors).to.have.members([grid.at(2, 0), grid.at(4, 0)]);
expect(grid.at(4, 0).neighbors).to.have.members([grid.at(3, 0)]);
});
});

describe('a completely vertical map', () => {
it('has neighbors above and below of tiles', () => {
const grid = new HexGrid(1, 5);

expect(grid.at(0, 0).neighbors).to.have.members([grid.at(0, 1)]);
expect(grid.at(0, 1).neighbors).to.have.members([grid.at(0, 0), grid.at(0, 2)]);
expect(grid.at(0, 2).neighbors).to.have.members([grid.at(0, 1), grid.at(0, 3)]);
expect(grid.at(0, 3).neighbors).to.have.members([grid.at(0, 2), grid.at(0, 4)]);
expect(grid.at(0, 4).neighbors).to.have.members([grid.at(0, 3)]);
describe('checking neighbors', () => {
describe('with a single hex', () => {
it('has no neighbors', () => {
const grid = new HexGrid(1, 1);
const hex = grid.at(0, 0);
expect(hex.neighbors).to.be.empty;
});
});

describe('a completely horizontal map', () => {
it('has neighbors left and right of tiles', () => {
const grid = new HexGrid(5, 1);

expect(grid.at(0, 0).neighbors).to.have.members([grid.at(1, 0)]);
expect(grid.at(1, 0).neighbors).to.have.members([grid.at(0, 0), grid.at(2, 0)]);
expect(grid.at(2, 0).neighbors).to.have.members([grid.at(1, 0), grid.at(3, 0)]);
expect(grid.at(3, 0).neighbors).to.have.members([grid.at(2, 0), grid.at(4, 0)]);
expect(grid.at(4, 0).neighbors).to.have.members([grid.at(3, 0)]);
});
});

describe('a completely vertical map', () => {
it('has neighbors above and below of tiles', () => {
const grid = new HexGrid(1, 5);

expect(grid.at(0, 0).neighbors).to.have.members([grid.at(0, 1)]);
expect(grid.at(0, 1).neighbors).to.have.members([grid.at(0, 0), grid.at(0, 2)]);
expect(grid.at(0, 2).neighbors).to.have.members([grid.at(0, 1), grid.at(0, 3)]);
expect(grid.at(0, 3).neighbors).to.have.members([grid.at(0, 2), grid.at(0, 4)]);
expect(grid.at(0, 4).neighbors).to.have.members([grid.at(0, 3)]);
});
});

describe('a full map', () => {
// A B C
// D E F
// Z Y X
// W V U
let grid: HexGrid;

beforeEach(() => {
grid = new HexGrid(3, 4);
});

it('A is neighbors to B and D', () => {
expect(grid.at(0, 0).neighbors).to.have.members([grid.at(0, 1), grid.at(1, 0)]);
});

it('B is neighbors to A, C, D, and E', () => {
expect(grid.at(1, 0).neighbors).to.have.members([
grid.at(0, 0),
grid.at(2, 0),
grid.at(0, 1),
grid.at(1, 1),
]);
});

it('C is neighbors to B, E, and F', () => {
expect(grid.at(2, 0).neighbors).to.have.members([
grid.at(1, 0),
grid.at(1, 1),
grid.at(2, 1),
]);
});

it('D is neighbors to A, B, E, Z, and Y', () => {
expect(grid.at(0, 1).neighbors).to.have.members([
grid.at(0, 0),
grid.at(1, 0),
grid.at(1, 1),
grid.at(0, 2),
grid.at(1, 2),
]);
});

it('E is neighbors to B, C, D, F, Y, and X', () => {
expect(grid.at(1, 1).neighbors).to.have.members([
grid.at(1, 0),
grid.at(2, 0),
grid.at(0, 1),
grid.at(2, 1),
grid.at(1, 2),
grid.at(2, 2),
]);
});

it('F is neighbors to C, E, and X', () => {
expect(grid.at(2, 1).neighbors).to.have.members([
grid.at(2, 0),
grid.at(1, 1),
grid.at(2, 2),
]);
});

it('Z is neighbors to D, Y, and W', () => {
expect(grid.at(0, 2).neighbors).to.have.members([
grid.at(0, 1),
grid.at(1, 2),
grid.at(0, 3),
]);
});

it('Y is neighbors to D, E, Z, X, W, and V', () => {
expect(grid.at(1, 2).neighbors).to.have.members([
grid.at(0, 1),
grid.at(1, 1),
grid.at(0, 2),
grid.at(2, 2),
grid.at(0, 3),
grid.at(1, 3),
]);
});

it('X is neighbors to E, F, Y, V, and U', () => {
expect(grid.at(2, 2).neighbors).to.have.members([
grid.at(1, 1),
grid.at(2, 1),
grid.at(1, 2),
grid.at(1, 3),
grid.at(2, 3),
]);
});

it('W is neighbors to Z, Y, and V', () => {
expect(grid.at(0, 3).neighbors).to.have.members([
grid.at(0, 2),
grid.at(1, 2),
grid.at(1, 3),
]);
});

it('V is neighbors to Y, X, W, and U', () => {
expect(grid.at(1, 3).neighbors).to.have.members([
grid.at(1, 2),
grid.at(2, 2),
grid.at(0, 3),
grid.at(2, 3),
]);
});

it('U is neighbors to V and X', () => {
expect(grid.at(2, 3).neighbors).to.have.members([
grid.at(2, 2),
grid.at(1, 3),
]);
});
});
});

describe('a full map', () => {
// A B C
// D E F
// Z Y X
// W V U
let grid: HexGrid;

beforeEach(() => {
grid = new HexGrid(3, 4);
});

it('A is neighbors to B and D', () => {
expect(grid.at(0, 0).neighbors).to.have.members([grid.at(0, 1), grid.at(1, 0)]);
});

it('B is neighbors to A, C, D, and E', () => {
expect(grid.at(1, 0).neighbors).to.have.members([
grid.at(0, 0),
grid.at(2, 0),
grid.at(0, 1),
grid.at(1, 1),
]);
});

it('C is neighbors to B, E, and F', () => {
expect(grid.at(2, 0).neighbors).to.have.members([
grid.at(1, 0),
grid.at(1, 1),
grid.at(2, 1),
]);
});

it('D is neighbors to A, B, E, Z, and Y', () => {
expect(grid.at(0, 1).neighbors).to.have.members([
grid.at(0, 0),
grid.at(1, 0),
grid.at(1, 1),
grid.at(0, 2),
grid.at(1, 2),
]);
});

it('E is neighbors to B, C, D, F, Y, and X', () => {
expect(grid.at(1, 1).neighbors).to.have.members([
grid.at(1, 0),
grid.at(2, 0),
grid.at(0, 1),
grid.at(2, 1),
grid.at(1, 2),
grid.at(2, 2),
]);
});

it('F is neighbors to C, E, and X', () => {
expect(grid.at(2, 1).neighbors).to.have.members([
grid.at(2, 0),
grid.at(1, 1),
grid.at(2, 2),
]);
});

it('Z is neighbors to D, Y, and W', () => {
expect(grid.at(0, 2).neighbors).to.have.members([
grid.at(0, 1),
grid.at(1, 2),
grid.at(0, 3),
]);
});

it('Y is neighbors to D, E, Z, X, W, and V', () => {
expect(grid.at(1, 2).neighbors).to.have.members([
grid.at(0, 1),
grid.at(1, 1),
grid.at(0, 2),
grid.at(2, 2),
grid.at(0, 3),
grid.at(1, 3),
]);
});

it('X is neighbors to E, F, Y, V, and U', () => {
expect(grid.at(2, 2).neighbors).to.have.members([
grid.at(1, 1),
grid.at(2, 1),
grid.at(1, 2),
grid.at(1, 3),
grid.at(2, 3),
]);
});

it('W is neighbors to Z, Y, and V', () => {
expect(grid.at(0, 3).neighbors).to.have.members([
grid.at(0, 2),
grid.at(1, 2),
grid.at(1, 3),
]);
});

it('V is neighbors to Y, X, W, and U', () => {
expect(grid.at(1, 3).neighbors).to.have.members([
grid.at(1, 2),
grid.at(2, 2),
grid.at(0, 3),
grid.at(2, 3),
]);
});
describe('constructing a grid', () => {
it('allows hex content to be initialized', () => {
fc.assert(fc.property(fc.anything(), thing => {
const grid = new HexGrid<unknown>(1, 1, () => thing);

it('U is neighbors to V and X', () => {
expect(grid.at(2, 3).neighbors).to.have.members([
grid.at(2, 2),
grid.at(1, 3),
]);
expect(grid.at(0, 0).content).to.eql(thing);
}));
});
});
});
Expand Down

0 comments on commit 78ac12f

Please sign in to comment.