コード例 #1
0
ファイル: WorldGen.cs プロジェクト: mdmooney/WorldGen
        /**
         * <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;
        }
コード例 #2
0
        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);
        }
コード例 #3
0
ファイル: RiverGen.cs プロジェクト: mdmooney/WorldGen
        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);
        }
コード例 #4
0
        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));
        }
コード例 #5
0
ファイル: RandomTable.cs プロジェクト: mdmooney/WorldGen
        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);
        }
コード例 #6
0
 public Coords RandomCoords()
 {
     return(new Coords(Hexes[_rand.GenerateInt(Hexes.Count)]));
 }
コード例 #7
0
ファイル: HexMap.cs プロジェクト: mdmooney/WorldGen
        public Landmass GetRandomLandmass()
        {
            int r = _rand.GenerateInt(Landmasses.Count);

            return(Landmasses[r]);
        }
コード例 #8
0
ファイル: WorldGen.cs プロジェクト: mdmooney/WorldGen
        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));
            }
        }
コード例 #9
0
        /** <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);
        }