Exemple #1
0
        /**
         * <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());
        }
Exemple #2
0
        /**
         * <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;
        }
Exemple #3
0
 public RiverGen(IRandomGen rand, World world, Landmass landmass, int length)
 {
     _rand            = rand;
     _world           = world;
     _landmass        = landmass;
     _allCoords       = new HashSet <Coords>();
     _requestedLength = length;
 }
Exemple #4
0
        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);
        }
Exemple #5
0
        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);
        }
Exemple #6
0
        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));
            }
        }