diff --git a/island/generators.ts b/island/generators.ts index 5c0b884..fc89887 100644 --- a/island/generators.ts +++ b/island/generators.ts @@ -91,10 +91,17 @@ export const ERODED_LOBE: LobeGeneratorConstructor = return true; }; -export const BIG_ISLANDS = [BIG_BEACH, BIG_MOUNTAIN]; +/** form low-lying beach with eroded sections */ +export const NO_ISLAND: LobeGeneratorConstructor = + (islands: IslandGrid, basePos: number) => () => { + return true; + }; + +export const BIG_ISLANDS = [BIG_MOUNTAIN, BIG_BEACH]; export const ALL_ISLANDS = [ BIG_MOUNTAIN, SMALL_BEACH, + BIG_BEACH, FOREST_LOBE, ERODED_LOBE, ]; diff --git a/island/grid.ts b/island/grid.ts index da3001c..d90e286 100644 --- a/island/grid.ts +++ b/island/grid.ts @@ -1,6 +1,11 @@ import { Prng, mulberry32 } from "../lib/prng"; import { BEACH, ICECAP } from "./data"; -import { ALL_ISLANDS, BIG_ISLANDS, LobeGenerator } from "./generators"; +import { + ALL_ISLANDS, + BIG_ISLANDS, + LobeGenerator, + NO_ISLAND, +} from "./generators"; export class IslandGrid { data: number[]; @@ -14,25 +19,27 @@ export class IslandGrid { this.data = Array(width * height).fill(0); this.rng = mulberry32(seed); - this.generators.push(this.choose(BIG_ISLANDS)(this, this.data.length >> 1)); - this.generators.push( - this.choose(ALL_ISLANDS)( - this, - this.xy( - (width >> 1) + (this.rng() % 48) - 24, - (height >> 1) + (this.rng() % 48) - 24 - ) - ) - ); - this.generators.push( - this.choose(ALL_ISLANDS)( - this, - this.xy( - (width >> 1) + (this.rng() % 48) - 24, - (height >> 1) + (this.rng() % 48) - 24 - ) - ) - ); + const islandBag = this.shuffle([ + this.choose(BIG_ISLANDS), + this.choose(BIG_ISLANDS), + this.choose(ALL_ISLANDS), + this.choose(ALL_ISLANDS), + this.choose(ALL_ISLANDS), + this.choose(ALL_ISLANDS), + NO_ISLAND, + NO_ISLAND, + ]); + + const islandCount = islandBag.length; + const spacing = (Math.PI * 2) / islandCount; + for (let i = 0; i < islandCount; i++) { + const y = height / 2 + (Math.sin(spacing * i) * height) / 4; + const x = width / 2 + (Math.cos(spacing * i) * width) / 4; + + console.log("xy", x | 0, y | 0); + + this.generators.push(islandBag[i](this, this.xy(x | 0, y | 0))); + } } public xy(x: number, y: number): number { @@ -121,6 +128,15 @@ export class IslandGrid { return list[this.rng() % list.length]; } + public shuffle<T>(list: T[]) { + const shuffled = list.slice(); + for (let i = 0; i < shuffled.length - 1; i++) { + const swapIndex = (this.rng() % (shuffled.length - i)) + i; + [shuffled[i], shuffled[swapIndex]] = [shuffled[swapIndex], shuffled[i]]; + } + return shuffled; + } + public dropWithin(tiles: number[]) { if (tiles.length > 0) { this.drop(this.choose(tiles)); diff --git a/lib/prng.ts b/lib/prng.ts index 6af760c..b2671c9 100644 --- a/lib/prng.ts +++ b/lib/prng.ts @@ -1,5 +1,7 @@ export type Prng = () => number; +export const UINT_MAX = 0xffffffff; + export function mulberry32(state: number) { return function () { let t = (state += 0x6d2b79f5);