Skip to content

Commit

Permalink
feat(grid): improve types and name some anonymous functions for bette…
Browse files Browse the repository at this point in the history
…r debugging
  • Loading branch information
flauwekeul committed Apr 22, 2021
1 parent 6a65b87 commit 383dfbd
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 31 deletions.
6 changes: 3 additions & 3 deletions src/grid/functions/at.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { createHex, Hex, HexCoordinates } from '../../hex'
import { GridGeneratorFunction } from '../types'
import { Traverser } from '../types'

export const at = <T extends Hex>(coordinates: HexCoordinates): GridGeneratorFunction<T> =>
function* (currentHex) {
export const at = <T extends Hex>(coordinates: HexCoordinates): Traverser<T> =>
function* next(currentHex) {
// todo: make createHex accept hex instances or use cloneHex()?
yield createHex(Object.getPrototypeOf(currentHex), coordinates)
}
Expand Down
6 changes: 3 additions & 3 deletions src/grid/functions/move.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { createHex, Hex } from '../../hex'
import { DIRECTION_COORDINATES } from '../constants'
import { CompassDirection, GridGeneratorFunction } from '../types'
import { CompassDirection, Traverser } from '../types'

// todo: also accept a string and/or number for direction
export const move = <T extends Hex>(direction: CompassDirection): GridGeneratorFunction<T> =>
function* (currentHex) {
export const move = <T extends Hex>(direction: CompassDirection): Traverser<T> =>
function* next(currentHex) {
const { q, r } = DIRECTION_COORDINATES[direction]
const nextCoordinates = { q: currentHex.q + q, r: currentHex.r + r }
// todo: make createHex accept hex instances or use cloneHex()?
Expand Down
6 changes: 3 additions & 3 deletions src/grid/functions/repeat.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Hex } from '../../hex'
import { GridGeneratorFunction } from '../types'
import { Traverser } from '../types'

// todo: looks a lot like Grid.traverse()
export const repeat = <T extends Hex>(amount: number, command: GridGeneratorFunction<T>): GridGeneratorFunction<T> =>
function* (currentHex) {
export const repeat = <T extends Hex>(amount: number, command: Traverser<T>): Traverser<T> =>
function* next(currentHex) {
let nextHex = currentHex
for (let i = 0; i < amount; i++) {
const hexes = command(nextHex)
Expand Down
38 changes: 17 additions & 21 deletions src/grid/grid.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
import { equals, Hex, HexCoordinates } from '../hex'
import { rectangle, RectangleOptions } from './functions'
import { GridGenerator, GridGeneratorFunction } from './types'
import { GridGenerator, Traverser } from './types'

interface InternalTraverser<T extends Hex> {
(this: Grid<T>): GridGenerator<T>
}

// eslint-disable-next-line @typescript-eslint/no-empty-function
function* infiniteTraverser<T extends Hex>(): GridGenerator<T> {}

// fixme: there's a lot of duplicate iteration, use a cache (or memoisation?)
export class Grid<T extends Hex> {
static of<T extends Hex>(hexPrototype: T, traverser?: GridGeneratorFunction<T>) {
static of<T extends Hex>(hexPrototype: T, traverser?: InternalTraverser<T>) {
return new Grid(hexPrototype, traverser)
}

constructor(public hexPrototype: T, private traverser: GridGeneratorFunction<T> = infiniteTraverser) {}
constructor(public hexPrototype: T, private traverser: InternalTraverser<T> = infiniteTraverser) {}

[Symbol.iterator]() {
// todo: {} as T is a bit hacky, but making it an optional parameter is meh
return this.traverser({} as T)
return this.traverser()
}

has(coordinates: HexCoordinates) {
Expand All @@ -31,7 +34,6 @@ export class Grid<T extends Hex> {
}

clone(traverser = this.traverser) {
// todo: maybe not bind and pass grid to traverser? Tried this, but it results in a "Maximum call stack size exceeded" error
return Grid.of(this.hexPrototype, traverser.bind(this))
}

Expand All @@ -40,33 +42,28 @@ export class Grid<T extends Hex> {
return this.clone(() => rectangle(this.hexPrototype, options))
}

// inspired by https://github.com/ReactiveX/rxjs/blob/master/src/internal/util/pipe.ts
// pipe(...fns: GridOperator<T>[]): Grid<T> {
// return ((grid: Grid<T>) => fns.reduce((prev, fn) => fn(prev), grid))(this)
// }

// fixme: use generic functions for these kinds of operations
// something like https://github.com/benji6/imlazy or https://github.com/lodash/lodash/wiki/FP-Guide
each(fn: (hex: T) => void) {
const traverser = function* (this: Grid<T>) {
const each: InternalTraverser<T> = function* () {
for (const hex of this) {
fn(hex)
yield hex
}
}
return this.clone(traverser)
return this.clone(each)
}

map(fn: (hex: T) => T) {
const traverser = function* (this: Grid<T>) {
const map: InternalTraverser<T> = function* () {
for (const hex of this) {
yield fn(hex)
}
}
return this.clone(traverser)
return this.clone(map)
}

// todo: other/more args?
// todo: alias to take or takeUntil?
run(stopFn: (hex: T) => boolean = () => false) {
for (const hex of this) {
if (stopFn(hex)) {
Expand All @@ -76,14 +73,13 @@ export class Grid<T extends Hex> {
return this // or clone()? todo: when to return clone and when not?
}

traverse(...commands: GridGeneratorFunction<T>[]) {
traverse(...commands: Traverser<T>[]) {
if (commands.length === 0) {
return this // or clone()? todo: when to return clone and when not?
}
// todo: {} as T is a bit hacky, but making it an optional parameter is meh
let currentHex = this.traverser({} as T).next().value || ({ q: 0, r: 0 } as T)
let currentHex = this.traverser().next().value || ({ q: 0, r: 0 } as T)

const traverser = function* (this: Grid<T>) {
function* traverse(this: Grid<T>) {
for (const command of commands) {
const hexes = command(currentHex)
for (const hex of hexes) {
Expand All @@ -96,6 +92,6 @@ export class Grid<T extends Hex> {
}
}
}
return this.clone(traverser)
return this.clone(traverse)
}
}
2 changes: 1 addition & 1 deletion src/grid/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ export type CompassDirection = PointyCompassDirection | FlatCompassDirection

export type GridGenerator<T extends Hex> = Generator<T, void>

export interface GridGeneratorFunction<T extends Hex> {
export interface Traverser<T extends Hex> {
(currentHex: T): GridGenerator<T>
}

0 comments on commit 383dfbd

Please sign in to comment.