/** * <summary> * Primary work method of this class, generating the entire world in * the given HexMap. * * This will very likely be split into smaller methods in the near future. * </summary> */ public void Generate() { List <Task> taskList = new List <Task>(); for (int i = 0; i < _world.Map.Landmasses.Count; i++) { Landmass mass = _world.Map.Landmasses[i]; List <Coords> allCoords = _world.Map.GetAllCoords(); LandmassExpander lEx = new LandmassExpander(_rand, _world.Map); mass.Hexes = lEx.Expand(allCoords, mass.TotalHexes); mass.TotalHexes = mass.Hexes.Count; // Create shore/shallow water hexes adjacent to each hex of this landmass foreach (Coords owned in mass.Hexes) { if (_world.Map.BordersOcean(owned)) { List <Coords> shoreHexes = _world.Map.GetAdjacentOceanHexes(owned); foreach (Coords shoreCoords in shoreHexes) { _world.Map.SetTypeAt(shoreCoords, Hex.HexType.Shore); mass.ShoreHexes.Add(shoreCoords); } } } Task t = Task.Run(() => FillLandmass(mass)); taskList.Add(t); } Task.WaitAll(taskList.ToArray()); }
/** * <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 RiverGen(IRandomGen rand, World world, Landmass landmass, int length) { _rand = rand; _world = world; _landmass = landmass; _allCoords = new HashSet <Coords>(); _requestedLength = length; }
public void GenerateRace() { if (_raceGen == null) { _raceGen = new RaceGen(); } if (_raceGen.IsEmpty()) { return; } Landmass mass = _world.Map.GetRandomLandmass(); AffinityMap massAffinity = _world.Map.GetAffinitiesForLandmass(mass); Race genRace = _raceGen.GenerateRace(massAffinity); Console.WriteLine("Rolled race: " + genRace); Console.WriteLine(genRace.Affinities); // arbitrarily low number to start with int highest = -50; // random coordinates as default Coords candidate = mass.RandomCoords(); int tick = 0; int tenPercent = mass.Count / 10; bool tenPercentMore = false; foreach (Coords coords in mass.CoordsFromRandomPoint()) { if (tick >= tenPercent) { break; } AffinityMap hexAffinities = _world.Map.GetAffinitiesForCoords(coords); int sim = genRace.Affinities.GetSimilarityTo(hexAffinities); if (sim > highest) { highest = sim; candidate = coords; } if (!tenPercentMore && highest > 0) { tenPercentMore = true; } if (tenPercentMore) { tick++; } } Console.WriteLine("Placing at : " + candidate); Console.WriteLine(_world.Map.GetAffinitiesForCoords(candidate)); Console.WriteLine("--> Final Score: " + highest); Console.WriteLine("------------------"); _world.PlaceRaceAt(genRace, candidate); }
public AffinityMap GetAffinitiesForLandmass(Landmass landmass) { if (!Landmasses.Contains(landmass)) { throw new KeyNotFoundException("Tried to get affinities for a landmass that is not in this HexMap."); } if (landmass.Affinities == null) { var totalAffinityScore = new Dictionary <string, int>(); foreach (Coords coords in landmass.Hexes) { Hex hex = GetHexAt(coords); AffinityMap affinities = hex.Affinities; foreach (var aspect in affinities.AspectList) { if (!totalAffinityScore.ContainsKey(aspect)) { totalAffinityScore[aspect] = 0; } totalAffinityScore[aspect] += affinities.GetAffinity(aspect); } } AffinityMap newAffinityMap = new AffinityMap(_rand); foreach (var aspect in totalAffinityScore.Keys) { int score = totalAffinityScore[aspect]; int affinity = score / landmass.TotalHexes; // don't allow 0 here; just weak affinities if (affinity == 0) { affinity = (score > 0) ? 1 : -1; } newAffinityMap.SetAffinity(aspect, affinity); } landmass.Affinities = newAffinityMap; } return(landmass.Affinities); }
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)); } }