/** * <summary> * WorldGenerator constructor requires a HexMap, which will hold the * world that is about to be generated. * * Does some basic setup, like determining how many landmasses will * exist in the world and how many Hexes they should contain, but does * not perform any actual generation. * </summary> * <param name="map">HexMap to generate a world in.</param> */ public WorldGenerator(World world, IRandomGen rand) { _rand = rand; _world = world; int worldTotal = (_world.Map.Width * _world.Map.Height); double overallTotalDec = (double)worldTotal; int totalLandHexes = (int)(overallTotalDec * WORLD_RATIO); int remainingHexes = totalLandHexes; var landmasses = new List <Landmass>(); int numLandmasses = _rand.GenerateInt(1, MAX_LANDMASSES); for (int i = 0; i < numLandmasses; i++) { Landmass landmass = new Landmass(rand); int massHexes; if (i != numLandmasses - 1) { massHexes = _rand.GenerateInt(1, remainingHexes / 2); } else { massHexes = remainingHexes; } remainingHexes -= massHexes; landmass.TotalHexes = landmass.RemainingHexes = massHexes; landmasses.Add(landmass); } _world.Map.Landmasses = landmasses; }
public void ResolveWildcard(string pool, int affinity) { var poolList = _aspectGlossary.GetPool(pool).ToList(); int i = _rand.GenerateInt(poolList.Count); string aspect = poolList[i]; // make sure we're not overwriting an existing affinity while (GetAffinity(aspect) != 0) { i = _rand.GenerateInt(poolList.Count); aspect = poolList[i]; } SetAffinity(poolList[i], affinity); }
private bool Extend() { RiverSegment lastSeg = _river.LastSeg; Coords lastLoc = lastSeg.Location; // Try to get downhill hexes first, if possible var adj = _world.Map.GetFilteredAdjacency(lastLoc, (x => !DoublesBack(x) && IsLowerOrWater(lastLoc, x))); // Nothing lower; need to do a lateral move if (adj.Count == 0) { adj = _world.Map.GetFilteredAdjacency(lastLoc, (x => !DoublesBack(x) && IsLateral(lastLoc, x))); } // Nowhere to go, can't extend if (adj.Count == 0) { return(false); } var adjList = adj.ToList(); var candidate = adjList[_rand.GenerateInt(adjList.Count)]; if (_world.Map.IsWaterAt(candidate.Value)) { _river.Terminate(candidate.Key); return(false); } _river.Extend(candidate.Key, candidate.Value); _allCoords.Add(candidate.Value); return(true); }
public Biome SelectBiome(Hex.TemperatureLevel temperature, Hex.HumidityLevel humidity) { var validBiomes = Biomes.Where(x => x.TemperatureRange.Contains(temperature) && x.HumidityRange.Contains(humidity)); if (validBiomes.Count() == 0) { return(null); } int i = _rand.GenerateInt(validBiomes.Count()); return(validBiomes.ElementAt(i)); }
public T Roll() { if (_table.Count == 0) { return(default(T)); } if (_table.Count == 1) { return(_table.First().Item2); } int r = _rand.GenerateInt(_max + 1); // modified binary search to get closest match int low = 0; int high = _table.Count - 1; while (low <= high) { int mid = (low + high) / 2; if (r < _table[mid].Item1) { high = mid - 1; } else if (r > _table[mid].Item1) { low = mid + 1; } else { return(_table[mid].Item2); } } if (high < 0) { return(_table[low].Item2); } return(((_table[low].Item1 - r) < (r - _table[high].Item1)) ? _table[low].Item2 : _table[high].Item2); }
public Coords RandomCoords() { return(new Coords(Hexes[_rand.GenerateInt(Hexes.Count)])); }
public Landmass GetRandomLandmass() { int r = _rand.GenerateInt(Landmasses.Count); return(Landmasses[r]); }
private void FillLandmass(Landmass mass) { // Elevation // Pick a number of passes; a range of the total number of // elements in the enum works best int passes = _rand.GenerateInt(1, 5); List <Coords> eleHexes = new List <Coords>(mass.Hexes); HeightExpander hEx = new HeightExpander(_rand, _world.Map); LayeredExpansion layered = new LayeredExpansion(_rand, hEx, eleHexes, 0.6, 0.8); layered.Expand(passes); // Rivers int totalRiverHexes = mass.TotalHexes / 20; int remainingHexes = totalRiverHexes; while (remainingHexes > 0) { if (remainingHexes == 1) { break; } int riverLength = _rand.GenerateInt(2, remainingHexes); RiverGen rgen = new RiverGen(_rand, _world, mass, riverLength); int genLength = rgen.Generate(); if (genLength > 1) { remainingHexes -= genLength; rgen.Commit(); _world.Rivers.Add(rgen.GenRiver); } } // Temperature SetTemperatures(); // Humidity passes = _rand.GenerateInt(1, 5); List <Coords> humiHexes = new List <Coords>(mass.Hexes); HumidityExpander humEx = new HumidityExpander(_rand, _world.Map); layered = new LayeredExpansion(_rand, humEx, humiHexes, 0.6, 0.8); layered.Expand(passes); // Biomes BiomeExpander bioEx; List <Coords> bioHexes = new List <Coords>(mass.Hexes); int tenPercent = mass.TotalHexes / 10; while (bioHexes.Count > 0) { int expandThisRound = bioHexes.Count; if (expandThisRound > tenPercent) { double fraction = _rand.GenerateDouble() / 2.0; expandThisRound = (int)(expandThisRound * fraction); } bioEx = new BiomeExpander(_rand, _world.Map, _world.Biomes); var placedCoords = bioEx.Expand(bioHexes, expandThisRound); bioHexes.RemoveAll(x => placedCoords.Contains(x)); } }
/** <summary> * Expand the given property in the map, within a set of coords predetermined * to point to hexes valid for expansion. * </summary> * <param name="validHexes">List of all coords containing hexes which are valid to expand to.</param> * <param name="size">The number of hexes to expand.</param> * <return>The list of all coords whose corresponding hexes were modified by this expansion.</return> */ public List <Coords> Expand(List <Coords> validHexes, int size) { int width = _map.Width; int height = _map.Height; _totalHexes = _remainingHexes = size; _validHexes = validHexes; // list of coords to be expanded out from, but which have not been expanded from yet List <Coords> unexpanded = new List <Coords>(); // list of coords to expand from again List <Coords> expandAgain = new List <Coords>(); List <Coords> rv = new List <Coords>(); // Select a valid hex at random to start from bool placedSeed = false; int attempts = 0; int totalValidHexes = validHexes.Count; while (!placedSeed && (attempts < totalValidHexes)) { int i = _rand.GenerateInt(totalValidHexes); Coords seedCoords = validHexes[i]; if (CanExpandFirst(seedCoords)) { placedSeed = ModHex(seedCoords); if (placedSeed) { _remainingHexes--; rv.Add(seedCoords); unexpanded.Add(seedCoords); continue; } } attempts++; } while ((_remainingHexes > 0) && !_finalizeEarly) { if (unexpanded.Count == 0) { if (AllowsReexpansion && (expandAgain.Count() > 0)) { unexpanded = expandAgain; } else { break; } } // Pick a hex to expand at random from the unexpanded list Coords startPoint = unexpanded[_rand.GenerateInt(unexpanded.Count)]; Dictionary <Hex.Side, Coords> adj = GetFilteredAdjacency(startPoint); // Determine at random how many hexes will be affected in this expansion // (i.e. how many adjacent hexes we'll attempt to modify in this round) int roll = RollBaseExpansion(adj.Count + 1) + RollModifier(); List <Hex.Side> contigs = FindNContiguousValidSides(startPoint, roll); if (contigs.Count > 0) { Hex.Side placeSide = contigs[_rand.GenerateInt(contigs.Count)]; int count = 0; // Try to modify as many contiguous hexes as we randomly determined we would while (count < roll) { if (adj.ContainsKey(placeSide)) { Coords placeLoc = adj[placeSide]; bool placed = ModHex(placeLoc); if (placed) { rv.Add(placeLoc); _remainingHexes--; unexpanded.Add(placeLoc); } } placeSide = Hex.RotateSideClockwise(placeSide); count++; } } // We've now expanded from these coords; remove them from the unexpanded list unexpanded.Remove(startPoint); // But if there are more adjacent hexes to expand to than we expanded into this round, // we can add this hex into the expand-again list if (roll < adj.Count) { expandAgain.Add(startPoint); } } // Go through all remaining Coords that were not expanded from, and do something with // their adjacent hexes, depending on the implementation of FinishAdjacentUnexpanded(). foreach (Coords remainder in unexpanded) { Dictionary <Hex.Side, Coords> toGo = GetFilteredAdjacency(remainder); foreach (Coords toGoInstance in toGo.Values) { FinishAdjacentUnexpanded(toGoInstance); } } return(rv); }