Skip to content

Commit

Permalink
feat: calculate tiles in range 2
Browse files Browse the repository at this point in the history
 + unit test

```js
function tilesInRangeRec(
  tileId: TileID,
  range: number,
  acc: TileID[]
): TileID[] {
  const neighbourTiles = tilesInRange1Cached(tileId);
  if (range === 1) {
    return addAll(acc, neighbourTiles);
  }
  const tiles = neighbourTiles.flatMap((tileId) =>
    tilesInRangeRec(tileId, range - 1, acc)
  );
  return addAll(acc, tiles);
}
```
  • Loading branch information
manuartero committed Jan 9, 2023
1 parent 8a5a4c8 commit e012982
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 47 deletions.
50 changes: 50 additions & 0 deletions src/models/tiles-in-range.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { tilesInRange } from "./tiles-in-range";

describe("tilesInRange()", () => {
/**
* [ ] [X] [X]
* [ ] [X] [.] [X]
* [ ] [ ] [X] [X] [ ]
*
*/
it("returns tilesID[] in range 1 from origin tile", () => {
const got = tilesInRange("1,-2", { range: 1 });
const expected = ["1,-3", "2,-3", "0,-2", "2,-2", "1,-1", "2,-1"];
expect(got.sort()).toEqual(expected.sort());
});

/**
* [ ] [ ] [X] [X] [X]
* [ ] [ ] [X] [X] [X] [X]
* [ ] [ ] [X] [X] [.] [X] [X]
* [ ] [ ] [ ] [X] [X] [X] [X] [ ]
* [ ] [ ] [ ] [X] [X] [X] [ ]
* [ ] [ ] [ ] [ ] [ ] [ ]
* [ ] [ ] [ ] [ ] [ ]
*
*/
it("returns tilesID[] in range 2 from origin tile", () => {
const got = tilesInRange("1,-1", { range: 2 });
const expected = [
"0,-3",
"1,-3",
"2,-3",
"-1,-2",
"0,-2",
"1,-2",
"2,-2",
"-1,-1",
"0,-1",
"2,-1",
"3,-1",
"-1,0",
"0,0",
"1,0",
"2,0",
"0,1",
"1,1",
"2,1",
];
expect(got.sort()).toEqual(expected.sort());
});
});
68 changes: 68 additions & 0 deletions src/models/tiles-in-range.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { asTileID, coordinates } from "./tiles";

const NEIGHBOUR_TILES_MEM_CACHE = {} as Record<TileID, TileID[]>;

export function tilesInRange(
tileId: TileID,
{ range }: { range?: number } = {}
) {
return tilesInRangeRec(tileId, range || 1, []).filter((t) => t !== tileId);
}

function tilesInRangeRec(
tileId: TileID,
range: number,
acc: TileID[]
): TileID[] {
const neighbourTiles = tilesInRange1Cached(tileId);
if (range === 1) {
return addAll(acc, neighbourTiles);
}
const tiles = neighbourTiles.flatMap((tileId) =>
tilesInRangeRec(tileId, range - 1, acc)
);
return addAll(acc, tiles);
}

function addAll<T>(a: T[], b: T[]) {
return Array.from(new Set([...a, ...b]));
}

function tilesInRange1Cached(tileId: TileID) {
if (!NEIGHBOUR_TILES_MEM_CACHE[tileId]) {
NEIGHBOUR_TILES_MEM_CACHE[tileId] = tilesInRange1(tileId);
}
return NEIGHBOUR_TILES_MEM_CACHE[tileId];
}

function tilesInRange1(tileId: TileID) {
const { x, y } = coordinates(tileId);

return range1Variance(y).flatMap((variance) => {
const tileIdStr = asTileID({
x: x + variance[0],
y: y + variance[1],
});
return tileIdStr ? [tileIdStr] : [];
});
}

function range1Variance(y: number) {
return y % 2 === 0
? [
[0, -1],
[+1, -1],
[-1, 0],
[+1, 0],
[0, +1],
[+1, +1],
]
: [
[-1, -1],
[0, -1],
[-1, 0],
[+1, 0],
[-1, +1],
[0, +1],
];
}
14 changes: 0 additions & 14 deletions src/models/tiles.test.ts

This file was deleted.

33 changes: 0 additions & 33 deletions src/models/tiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
* [ ] [ ] [ ] [ ] [ ] [ ]
* [ ] [ ] [ ] [ ] [ ]
*
* =>
*
* [-2,-3] [-1,-3] [+0,-3] [1,-3] [2,-3]
*
Expand Down Expand Up @@ -101,35 +100,3 @@ export function asTileID({ x, y }: { x: number; y: number }): TileID | null {
export function row(n: -3 | -2 | -1 | 0 | 1 | 2 | 3): TileID[] {
return tiles.filter((id) => coordinates(id).y === n);
}

export function tilesInRange(tile: TileID, { range } = { range: 1 }): TileID[] {
const { x, y } = coordinates(tile);

// TODO use range param instead of fixed array?
const range1Movements =
y % 2 === 0
? [
[0, -1],
[+1, -1],
[-1, 0],
[+1, 0],
[0, +1],
[+1, +1],
]
: [
[-1, -1],
[0, -1],
[-1, 0],
[+1, 0],
[-1, +1],
[0, +1],
];

return range1Movements.flatMap((variance) => {
const tileIdStr = asTileID({
x: x + variance[0],
y: y + variance[1],
});
return tileIdStr ? [tileIdStr] : [];
});
}

0 comments on commit e012982

Please sign in to comment.