public override TerrainGrid Generate(Vector size, FreqDict freqs = null, Random rand = null) { freqs = freqs ?? _defaultFreqs; UpdateFreqs(ref freqs); NormalizeFreqs(ref freqs); rand = rand ?? new Random(); var terrain = new Grid<TerrainType>(size); var heightGrid = _topographyGenerator.Generate(terrain.Size, rand); heightGrid = _filters.OpenClose(heightGrid); var sortedPoints = heightGrid.GetPoints().ToList(); sortedPoints.Sort((lhs, rhs) => (heightGrid[lhs] - heightGrid[rhs])); int numTiles = size.x * size.y; int numWaterTiles = (int)(numTiles * freqs[TerrainTypes.Water]); var waterTiles = sortedPoints.Take(numWaterTiles); foreach (var point in waterTiles) terrain[point] = TerrainTypes.Water; int numMountainTiles = (int)(numTiles * freqs[TerrainTypes.Mountain]); var mountainTiles = sortedPoints.Skip(numTiles - numMountainTiles); foreach (var point in mountainTiles) terrain[point] = TerrainTypes.Mountain; var landTiles = new HashSet<Vector>(terrain.GetPoints()); landTiles.ExceptWith(waterTiles); landTiles.ExceptWith(mountainTiles); AddLandTiles(ref terrain, landTiles.ToList(), freqs, rand); return terrain; }
private void UpdateFreqs(ref FreqDict freqs) { var terrainValues = ((TerrainType[])Enum.GetValues(typeof(TerrainType))); foreach (var terrainValue in terrainValues) if (!freqs.ContainsKey(terrainValue)) freqs[terrainValue] = _defaultFreqs[terrainValue]; }
private void NormalizeFreqs(ref FreqDict freqs) { double sum = freqs.Values.Sum(); var terrainValues = ((TerrainType[])Enum.GetValues(typeof(TerrainType))); foreach (var key in terrainValues) freqs[key] = freqs[key] / sum; }
private void AddLandTiles(ref TerrainGrid terrain, List<Vector> landTiles, FreqDict freqs, Random rand) { var heightGrid = _topographyGenerator.Generate(terrain.Size, rand); heightGrid = _filters.OpenClose(heightGrid); landTiles.Sort((lhs, rhs) => (heightGrid[lhs] - heightGrid[rhs])); int numTiles = terrain.Size.x * terrain.Size.y; foreach (var terrainType in TerrainTypes.Land) { int numTerrainTiles = (int)(freqs[terrainType] * numTiles); var tiles = landTiles.Take(numTerrainTiles); foreach(var point in tiles) terrain[point] = terrainType; landTiles.RemoveRange(0, numTerrainTiles); } }