private static void AppendToStreamGrowth(int[,,] etherResistanceEnvironment, HashSet <ElementPoint> streamPath, HashSet <EtherStreamGrowthDirection> streamGrowth, ElementPoint growthPoint, out int totalWeights) { totalWeights = 0; ElementPoint[] directionalPoints = new ElementPoint[] { growthPoint.CloneWithOffset(1, 0, 0), growthPoint.CloneWithOffset(0, 1, 0), growthPoint.CloneWithOffset(0, 0, 1), growthPoint.CloneWithOffset(-1, 0, 0), growthPoint.CloneWithOffset(0, -1, 0), growthPoint.CloneWithOffset(0, 0, -1) }; foreach (ElementPoint directionalPoint in directionalPoints) { if (!streamPath.Contains(directionalPoint) && etherResistanceEnvironment.WithinBounds(directionalPoint)) { int directionalWeight = etherResistanceEnvironment.AtPoint(growthPoint) - etherResistanceEnvironment.AtPoint(directionalPoint) + 1; if (directionalWeight > 0) { streamGrowth.Add(new EtherStreamGrowthDirection() { From = growthPoint, To = directionalPoint, Weight = directionalWeight }); totalWeights += directionalWeight; } } } }
private static void GrowEarthCrystal(int[,,] earthCrystalEnvironment, int waterSize, int woodSize, int windSize, Random rand) { int maxEarth = (waterSize - 2) * (woodSize - 2); Dictionary <int, int> earthLimits = new Dictionary <int, int>(); int totalEarth = 0; for (int i = 1; i < windSize - 1; i++) { double fractionAlongWorld = i / (double)(windSize - 1); double spinalValue = SpinalOperations.WorldSpinalValue(fractionAlongWorld, 1.27); int earthLimit = (int)(maxEarth * spinalValue); totalEarth += earthLimit; earthLimits.Add(i, earthLimit); } List <ElementPoint> growthLocations = new List <ElementPoint>(); for (int wind = 1; wind < (windSize - 1) / 2; wind++) { for (int wood = 1; wood < woodSize - 1; wood++) { for (int water = 1; water < waterSize - 1; water++) { if (EnvironmentMakerOperations.HasNeighborOfValueOrLess(water, wood, wind, -1, earthCrystalEnvironment)) { growthLocations.Add(new ElementPoint() { waterPosition = water, woodPosition = wood, windPosition = wind }); } } } } while (totalEarth > 0) { int numberOfPossibleLocations = growthLocations.Count; int growthChoice = rand.Next(0, numberOfPossibleLocations); ElementPoint growthPoint = growthLocations[growthChoice]; growthLocations.Remove(growthPoint); earthCrystalEnvironment.SetPoint(growthPoint, -1); earthLimits[growthPoint.windPosition]--; if (earthLimits[growthPoint.windPosition] == 0) { growthLocations.RemoveAll((p) => p.windPosition == growthPoint.windPosition); } totalEarth--; int upperLayer = growthPoint.windPosition + 1; if (earthLimits.ContainsKey(upperLayer) && earthLimits[upperLayer] != 0) { ElementPoint topPoint = growthPoint.CloneWithOffset(0, 1, 0); if (!growthLocations.Contains(topPoint) && earthCrystalEnvironment.WithinBounds(topPoint) && earthCrystalEnvironment.AtPoint(topPoint) == 0) { growthLocations.Add(topPoint); } } if (earthLimits[growthPoint.windPosition] != 0) { ElementPoint rightPoint = growthPoint.CloneWithOffset(1, 0, 0); if (!growthLocations.Contains(rightPoint) && earthCrystalEnvironment.WithinBounds(rightPoint) && earthCrystalEnvironment.AtPoint(rightPoint) == 0) { growthLocations.Add(rightPoint); } ElementPoint forwardPoint = growthPoint.CloneWithOffset(0, 0, 1); if (!growthLocations.Contains(forwardPoint) && earthCrystalEnvironment.WithinBounds(forwardPoint) && earthCrystalEnvironment.AtPoint(forwardPoint) == 0) { growthLocations.Add(forwardPoint); } ElementPoint leftPoint = growthPoint.CloneWithOffset(-1, 0, 0); if (!growthLocations.Contains(leftPoint) && earthCrystalEnvironment.WithinBounds(leftPoint) && earthCrystalEnvironment.AtPoint(leftPoint) == 0) { growthLocations.Add(leftPoint); } ElementPoint backPoint = growthPoint.CloneWithOffset(0, 0, -1); if (!growthLocations.Contains(backPoint) && earthCrystalEnvironment.WithinBounds(backPoint) && earthCrystalEnvironment.AtPoint(backPoint) == 0) { growthLocations.Add(backPoint); } } int lowerLayer = growthPoint.windPosition - 1; if (earthLimits.ContainsKey(lowerLayer) && earthLimits[lowerLayer] != 0) { ElementPoint bottomPoint = growthPoint.CloneWithOffset(0, -1, 0); if (!growthLocations.Contains(bottomPoint) && earthCrystalEnvironment.WithinBounds(bottomPoint) && earthCrystalEnvironment.AtPoint(bottomPoint) == 0) { growthLocations.Add(bottomPoint); } } } }
private static void GrowStream(int[,,] etherResistanceEnvironment, int[,,] streamEnvironment, ElementPoint corner) { Random rand = new Random(); int streamLength = 20 * streamEnvironment.GetLength(0); ElementPoint newGrowth = corner; HashSet <ElementPoint> streamPath = new HashSet <ElementPoint>() { newGrowth }; HashSet <ElementPoint> validBuds = new HashSet <ElementPoint>() { newGrowth }; streamEnvironment.SetPoint(newGrowth, streamEnvironment.AtPoint(newGrowth) + 1); HashSet <EtherStreamGrowthDirection> streamGrowth = new HashSet <EtherStreamGrowthDirection>(); ElementPoint growthBud = corner; while (streamLength > 0) { AppendToStreamGrowth(etherResistanceEnvironment, streamPath, streamGrowth, growthBud, out int totalWeights); if (streamGrowth.Count == 0) { break; } if (totalWeights == 0) { validBuds.Remove(growthBud); streamGrowth.RemoveWhere(direction => direction.To == growthBud); growthBud = ChooseNewGrowthBud(validBuds, rand); continue; } EtherStreamGrowthDirection growthChoice = null; int choice = rand.Next(totalWeights) + 1; foreach (EtherStreamGrowthDirection growth in streamGrowth) { int growthWeight = growth.Weight; choice -= growthWeight; if (choice <= 0) { growthChoice = growth; break; } } newGrowth = growthChoice.To; streamPath.Add(newGrowth); validBuds.Add(newGrowth); streamEnvironment.SetPoint(newGrowth, streamEnvironment.AtPoint(newGrowth) + 1); streamGrowth.Remove(growthChoice); streamGrowth.RemoveWhere(direction => direction.To == newGrowth); growthBud = ChooseNewGrowthBud(validBuds, rand); streamLength--; } }