import { BEACH, ICECAP, LIGHT_FOREST, MOUNTAIN, WATER } from "./data"; import { IslandGrid } from "./grid"; export type IsDone = boolean; export type LobeGenerator = () => IsDone; export type LobeGeneratorConstructor = ( islands: IslandGrid, basePos: number ) => LobeGenerator; /** form mountain with icecap */ export const BIG_MOUNTAIN: LobeGeneratorConstructor = (islands: IslandGrid, basePos: number) => () => { const mountainTiles = islands.floodSearch( basePos, (tile) => tile > MOUNTAIN ); islands.dropWithin(mountainTiles); return mountainTiles.some((pos) => islands.data[pos] == ICECAP); }; /** form low-lying beach */ export const BEACH_LOBE: LobeGeneratorConstructor = (islands: IslandGrid, basePos: number) => () => { const islandTiles = islands.floodSearch(basePos, (tile) => tile > WATER); const shoreTiles = islandTiles.filter((pos) => islands.data[pos] == WATER); islands.dropWithin(shoreTiles); return true; }; /** form forested zone */ export const FOREST_LOBE: LobeGeneratorConstructor = (islands: IslandGrid, basePos: number) => () => { const islandTiles = islands.floodSearch(basePos, (tile) => tile > WATER); // grow shore const shoreTiles = islandTiles.filter((pos) => islands.data[pos] == WATER); islands.dropWithin(shoreTiles); // seed beach const beachTiles = islandTiles.filter((pos) => islands.data[pos] == BEACH); islands.dropWithin(beachTiles); // expand forest const forestLobe = islands.floodSearch(basePos, (tile) => tile > BEACH); const forestTiles = forestLobe.filter( (pos) => islands.data[pos] == LIGHT_FOREST ); islands.dropWithin(forestTiles); islands.dropWithin(forestTiles); islands.dropWithin(forestTiles); return true; }; /** form low-lying beach with eroded sections */ export const ERODED_LOBE: LobeGeneratorConstructor = (islands: IslandGrid, basePos: number) => () => { const islandTiles = islands.floodSearch(basePos, (tile) => tile > WATER); const shoreTiles = islandTiles.filter((pos) => islands.data[pos] == WATER); islands.dropWithin(shoreTiles); // erode if (islandTiles.length > 1) { const erodePos = islandTiles[islands.rng() % islandTiles.length]; islands.data[erodePos] = Math.max(islands.data[erodePos] - 1, WATER); } return true; }; export const BIG_ISLANDS = [BIG_MOUNTAIN]; export const ALL_ISLANDS = [BIG_MOUNTAIN, BEACH_LOBE, FOREST_LOBE, ERODED_LOBE];