diff --git a/README.md b/README.md index b974a90c..2ab0148f 100644 --- a/README.md +++ b/README.md @@ -333,7 +333,7 @@ These methods exist in v3 and they need to be considered for v4. - [x] toString - [x] width - [ ] grid functions (these should apply to multiple hexes): - - [ ] ? distance + - [x] distance - [x] hexToPoint - [x] pointToHex - [x] get diff --git a/src/grid/functions/distance.test.ts b/src/grid/functions/distance.test.ts new file mode 100644 index 00000000..f77103eb --- /dev/null +++ b/src/grid/functions/distance.test.ts @@ -0,0 +1,9 @@ +import { createHexPrototype } from '../../hex' +import { distance } from './distance' + +test('returns the number of hexes between the passed 2 hexes (excluding the last hex)', () => { + const hexPrototype = createHexPrototype({ orientation: 'pointy' }) + const result = distance(hexPrototype, { q: 1, r: 3 }, { q: 8, r: 7 }) + + expect(result).toBe(11) +}) diff --git a/src/grid/functions/distance.ts b/src/grid/functions/distance.ts new file mode 100644 index 00000000..454ec62e --- /dev/null +++ b/src/grid/functions/distance.ts @@ -0,0 +1,12 @@ +import { HexCoordinates, HexPrototype } from '../../hex' +import { assertCubeCoordinates } from '../../utils' + +export function distance( + hexPrototype: Pick, + from: HexCoordinates, + to: HexCoordinates, +) { + const { q: fromQ, r: fromR, s: fromS = -fromQ - fromR } = assertCubeCoordinates(from, hexPrototype) + const { q: toQ, r: toR, s: toS = -toQ - toR } = assertCubeCoordinates(to, hexPrototype) + return Math.max(Math.abs(fromQ - toQ), Math.abs(fromR - toR), Math.abs(fromS - toS)) +} diff --git a/src/grid/functions/index.ts b/src/grid/functions/index.ts index 4f955545..0b422c55 100644 --- a/src/grid/functions/index.ts +++ b/src/grid/functions/index.ts @@ -1,3 +1,4 @@ +export * from './distance' export * from './flatTraverse' export * from './inStore' export * from './neighborOf' diff --git a/src/grid/grid.test.ts b/src/grid/grid.test.ts index ce74e2e2..c639f848 100644 --- a/src/grid/grid.test.ts +++ b/src/grid/grid.test.ts @@ -104,6 +104,15 @@ describe('pointToHex()', () => { }) }) +describe('distance()', () => { + test('returns the distance between the passed 2 hexes', () => { + const grid = new Grid(hexPrototype) + const result = grid.distance({ q: -3, r: 11 }, { q: 15, r: 1 }) + + expect(result).toBe(18) + }) +}) + describe('getHex()', () => { test('returns a hex from the store when present in the store', () => { const coordinates = { q: 1, r: 2 } diff --git a/src/grid/grid.ts b/src/grid/grid.ts index be36c709..d06d241b 100644 --- a/src/grid/grid.ts +++ b/src/grid/grid.ts @@ -1,5 +1,5 @@ import { createHex, Hex, HexCoordinates, Point, pointToCube } from '../hex' -import { flatTraverse } from './functions' +import { distance, flatTraverse } from './functions' import { Callback, Traverser } from './types' export class Grid { @@ -52,6 +52,10 @@ export class Grid { return this.getHex(pointToCube(point, this.hexPrototype)) } + distance(from: HexCoordinates, to: HexCoordinates) { + return distance(this.hexPrototype, from, to) + } + update(callback: (grid: Grid) => Grid | void) { let nextGrid = this._clone(this._getPrevHexes) nextGrid = callback(nextGrid) || nextGrid diff --git a/src/utils/assertCubeCoordinates.ts b/src/utils/assertCubeCoordinates.ts new file mode 100644 index 00000000..1987c968 --- /dev/null +++ b/src/utils/assertCubeCoordinates.ts @@ -0,0 +1,10 @@ +import { CubeCoordinates, HexCoordinates, HexPrototype, offsetToCube } from '../hex' +import { isOffset } from './isOffset' + +export function assertCubeCoordinates( + coordinates: HexCoordinates, + hexPrototype: Pick, +): CubeCoordinates { + const { q, r, s = -q - r } = isOffset(coordinates) ? offsetToCube(coordinates, hexPrototype) : coordinates + return { q, r, s } +} diff --git a/src/utils/index.ts b/src/utils/index.ts index 6888c347..a7776d10 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,3 +1,4 @@ +export * from './assertCubeCoordinates' export * from './isAxial' export * from './isFunction' export * from './isObject'