PageSourceSearch

https://agormley3424.github.io/worldbuilder/js/biomeAgent.js

js agormley3424.github.io collected 2026-10-03 08:33:34 UTC 3,109 bytes, 114 lines download raw bytes

1/* global
2  noise
3*/
4/* jshint esversion: 6 */
5
6class BiomeAgent {
7  generate (map) {
8    /*
9    Assigns water to be ocean or lake as appropriate for a whole map.
10    Also assigns coastpoints as land adjacent to ocean.
11    */
12    this.approximateLakes(map);
13    const unvisitedLakes = map.getPointsOfType('lake');
14    const visitedLakes = [];
15    while (unvisitedLakes.length > 0) {
16      const lakePoint = unvisitedLakes.pop();
17      visitedLakes.push(lakePoint);
18      if (this.findOcean(lakePoint, map, visitedLakes)) {
19        this.assignOcean(lakePoint, map);
20      }
21    }
22  }
23
24  defineShore (map) {
25    const c = map.getPointsOfType('coast');
26    const shoreList = [];
27    for (const p of c) {
28      if (map.getNeighborsOfType(p, 'ocean').length > 0) {
29        shoreList.push(p);
30      }
31    }
32    return shoreList;
33  }
34
35  approximateLakes (map) {
36    /*
37    Overestimates the number of lake points in the map
38    */
39    const shorePoints = this.defineShore(map);
40    for (const b of shorePoints) {
41      const oceanPoints = map.getNeighborsOfType(b, 'ocean');
42      for (const o of oceanPoints) {
43        const direction = b.dir(o);
44        this._moveAlong(o, direction, map);
45      }
46    }
47  }
48
49  _moveAlong (point, direction, map) {
50    /*
51    Helper function for approximateLakes, recursively checks a line of water to determine if it's a set of lake or ocean points.
52    */
53    if (point === null) {
54      return 'ocean';
55    } else if (point.getBiome() !== 'ocean') {
56      return 'lake';
57    } else {
58      const type = this._moveAlong(map.getNeighbor(point, direction), direction, map);
59      point.setBiome(type);
60      return type;
61    }
62  }
63
64  findOcean (point, map, visitedLakes) {
65    /*
66    Returns true if the point is connected to an ocean point, otherwise false.
67    */
68    const fringe = [];
69    fringe.push(point);
70    while (fringe.length > 0) {
71      const parent = fringe.pop();
72      if (parent === null) {
73        console.log('biomeAgent error in findOcean: point is null');
74        return null;
75      } else if (parent.getBiome() === 'ocean') {
76        return true;
77      } else if (parent.getBiome() === 'lake') {
78        const successors = map.getNeighbors(parent);
79        for (const s of successors) {
80          if (!visitedLakes.includes(s)) {
81            fringe.push(s);
82            visitedLakes.push(s);
83          }
84        }
85      }
86    }
87    return false;
88  }
89
90  assignOcean (point, map) {
91    /*
92    Discovers and sets the biomes of all reachable lake points from point ocean.
93    */
94    const fringe = [];
95    const visitedNodes = [];
96    fringe.push(point);
97    while (fringe.length > 0) {
98      const parent = fringe.pop();
99      if (parent === null) {
100        console.log('biomeAgent error in findOcean: point is null');
101        return null;
102      } else if (parent.getBiome() === 'lake') {
103        parent.setBiome('ocean');
104        const successors = map.getNeighbors(parent);
105        for (const s of successors) {
106          if (!visitedNodes.includes(s)) {
107            fringe.push(s);
108            visitedNodes.push(s);
109          }
110        }
111      }
112    }
113  }
114}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.