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.