Beispiel #1
0
        /// <summary>
        /// Computes the number of <see cref="MapSquarePivot"/> for a chunk of the current biome, in the specified context.
        /// </summary>
        /// <param name="totalSquaresCount">Total count of squares in the continent.</param>
        /// <param name="chunkCoeff">Number real of squares in a <see cref="BiomeSizePivot.Small"/> chunk.</param>
        /// <param name="humidity">Level of <see cref="HumidityPivot"/> at the current latitude.</param>
        /// <param name="age">Age of the map.</param>
        /// <returns>Number of squares </returns>
        internal int ChunkSquaresCount(int totalSquaresCount, double chunkCoeff, HumidityPivot humidity, AgePivot age)
        {
            if (age == AgePivot.New)
            {
                if (Age == AgePivot.Old)
                {
                    chunkCoeff += 1.5;
                }
                else if (Age == AgePivot.New)
                {
                    chunkCoeff -= 1.5;
                }
            }
            else if (age == AgePivot.Old)
            {
                if (Age == AgePivot.Old)
                {
                    chunkCoeff -= 1.5;
                }
                else if (Age == AgePivot.New)
                {
                    chunkCoeff += 1.5;
                }
            }

            var realRatio = AppearanceRate;

            if (humidity == HumidityPivot.Dry)
            {
                if (Humidity == HumidityPivot.Dry)
                {
                    realRatio *= 2;
                }
                else if (Humidity == HumidityPivot.Wet)
                {
                    realRatio /= 2;
                }
            }
            else if (humidity == HumidityPivot.Wet)
            {
                if (Humidity == HumidityPivot.Dry)
                {
                    realRatio /= 2;
                }
                else if (Humidity == HumidityPivot.Wet)
                {
                    realRatio *= 2;
                }
            }

            return((int)Math.Round((totalSquaresCount * (realRatio * 3)) / ((int)Size * chunkCoeff)));
        }
Beispiel #2
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="mapSize">Map size.</param>
        /// <param name="mapShape">Map shape.</param>
        /// <param name="landCoverage">Map land coverage.</param>
        /// <param name="temperature">Map temperature.</param>
        /// <param name="age">Map age.</param>
        /// <param name="humidity">Map humidity.</param>
        /// <param name="playerCivilization">Human player civilization.</param>
        /// <param name="playerGender">The <see cref="PlayerPivot.Gender"/> value.</param>
        /// <param name="iaPlayersCount">Number of IA civilizations (except barbarians).</param>
        /// <param name="randomCityNames">Sets <c>True</c> to active random city names for the human player.</param>
        /// <exception cref="ArgumentNullException"><paramref name="playerCivilization"/> is <c>Null</c>.</exception>
        /// <exception cref="ArgumentException"><paramref name="iaPlayersCount"/> invalid.</exception>
        public EnginePivot(SizePivot mapSize, LandShapePivot mapShape, LandCoveragePivot landCoverage, TemperaturePivot temperature,
                           AgePivot age, HumidityPivot humidity, CivilizationPivot playerCivilization,
                           bool playerGender, int iaPlayersCount, bool randomCityNames)
        {
            if (playerCivilization == null)
            {
                throw new ArgumentNullException(nameof(playerCivilization));
            }
            iaPlayersCount = iaPlayersCount < 0 ? 0 : iaPlayersCount;
            if (iaPlayersCount > CivilizationPivot.GetCivilizations(false).Count / (6 - (int)mapSize))
            {
                throw new ArgumentException("The IA players count is too high for this map size !", nameof(iaPlayersCount));
            }

            Map = new MapPivot(mapSize, mapShape, landCoverage, temperature, age, humidity);

            List <MapSquarePivot> excludedSpots = new List <MapSquarePivot>();

            HumanPlayer = new PlayerPivot(this, playerCivilization, false, GetRandomLocation(excludedSpots), playerGender, randomCityNames);

            var allCivs = CivilizationPivot.GetCivilizations(false);

            for (int i = 0; i < iaPlayersCount; i++)
            {
                CivilizationPivot iaCiv = null;
                do
                {
                    iaCiv = allCivs.ElementAt(Tools.Randomizer.Next(0, allCivs.Count));
                }while (HumanPlayer.Civilization == iaCiv || _opponentPlayers.Any(ia => ia.Civilization == iaCiv));
                _opponentPlayers.Add(new PlayerPivot(this, iaCiv, true, GetRandomLocation(excludedSpots), Tools.Randomizer.Next(0, 2) == 0, false));
            }

            BarbarianPlayer = new PlayerPivot(this, CivilizationPivot.Barbarian, true, null, false, true);

            // Sets war between every civilizations.
            for (int i = 0; i < Players.Count - 1; i++)
            {
                for (int j = i + 1; j < Players.Count; j++)
                {
                    Players.ElementAt(i).SwitchPeaceStatusWithOpponent(Players.ElementAt(j));
                }
            }

            CurrentTurn = 0;
        }
Beispiel #3
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="mapSize"><see cref="SizePivot"/></param>
        /// <param name="mapShape"><see cref="LandShapePivot"/></param>
        /// <param name="landCoverage"><see cref="LandCoveragePivot"/></param>
        /// <param name="temperature"><see cref="TemperaturePivot"/></param>
        /// <param name="age"><see cref="AgePivot"/></param>
        /// <param name="humidity"><see cref="HumidityPivot"/></param>
        internal MapPivot(SizePivot mapSize, LandShapePivot mapShape, LandCoveragePivot landCoverage,
                          TemperaturePivot temperature, AgePivot age, HumidityPivot humidity)
        {
            var continentCount = mapShape == LandShapePivot.Pangaea ? 1 : (
                mapShape == LandShapePivot.Continent ? Tools.Randomizer.Next(CONTINENT_COUNT_MIN, CONTINENT_COUNT_MAX + 1) :
                Tools.Randomizer.Next(ISLAND_COUNT_MIN, ISLAND_COUNT_MAX + 1)
                );
            var landRatio = LAND_COVERAGE_RATIOS[landCoverage];

            _huts             = new List <HutPivot>();
            Height            = MINIMAL_HEIGHT * (int)mapSize;
            Width             = Height * RATIO_WIDTH_HEIGHT;
            GlobalTemperature = temperature;
            _mapSquareList    = new MapSquarePivot[Height, Width];

            var continentInfos = new List <List <MapSquarePivot> >();

            var boundaries = new List <ContinentBlueprint>();
            Action <ContinentBlueprint> SplitX = delegate(ContinentBlueprint contPick)
            {
                var splitX = Tools.Randomizer.Next((int)Math.Floor(MIN_SPLIT_RATIO * contPick.Width), (int)Math.Floor(MAX_SPLIT_RATIO * contPick.Width));
                boundaries.Add(new ContinentBlueprint(splitX, contPick.Height, contPick.StartX, contPick.StartY));
                boundaries.Add(new ContinentBlueprint(contPick.Width - splitX, contPick.Height, contPick.StartX + splitX, contPick.StartY));
            };
            Action <ContinentBlueprint> SplitY = delegate(ContinentBlueprint contPick)
            {
                var splitY = Tools.Randomizer.Next((int)Math.Floor(MIN_SPLIT_RATIO * contPick.Height), (int)Math.Floor(MAX_SPLIT_RATIO * contPick.Height));
                boundaries.Add(new ContinentBlueprint(contPick.Width, splitY, contPick.StartX, contPick.StartY));
                boundaries.Add(new ContinentBlueprint(contPick.Width, contPick.Height - splitY, contPick.StartX, contPick.StartY + splitY));
            };
            Action <int, bool> Split = delegate(int pickIndex, bool inY)
            {
                var contPick = boundaries[pickIndex];
                if (inY)
                {
                    SplitY(contPick);
                }
                else
                {
                    SplitX(contPick);
                }
                boundaries.Remove(contPick);
            };

            List <int> ranges = new List <int>();
            var        cpt    = ISLAND_COUNT_MAX;

            while (cpt > 1)
            {
                ranges.Add(cpt);
                cpt /= 2;
            }

            for (int i = 1; i <= continentCount; i++)
            {
                if (boundaries.Count == 0)
                {
                    boundaries.Add(new ContinentBlueprint(Width, Height, 0, 0));
                }
                else
                {
                    var nextTypeI = ranges.Where(x => x > boundaries.Count).Min();
                    Split(
                        Tools.Randomizer.Next(0, nextTypeI - boundaries.Count),
                        ranges.Any(x => x == Math.Sqrt(nextTypeI))
                        );
                }
            }

            var cIndex = 0;

            foreach (var boundary in boundaries)
            {
                continentInfos.Add(ConvertContinentBlueprintToMapSquares(landRatio, boundary, cIndex));
                cIndex++;
            }

            // sets chunks
            var chunksByType = BiomePivot.ChunkAppearanceBiomes.ToDictionary(b => b, b => new List <List <Tuple <int, int> > >());
            var rivers       = new List <List <Tuple <int, int> > >();
            var huts         = new List <Tuple <int, int> >();

            foreach (var fullLand in continentInfos)
            {
                fullLand.ForEach(msloc => _mapSquareList[msloc.Row, msloc.Column] = msloc);
                var continentLand = fullLand.Where(ms => !ms.Biome.IsSeaType).ToList();

                var chunksCountByType =
                    BiomePivot.ChunkAppearanceBiomes
                    .ToDictionary(b => b, b => b.ChunkSquaresCount(continentLand.Count, CHUNK_SIZE_RATIO, humidity, age));

                var topY    = continentLand.Min(x => x.Row);
                var leftX   = continentLand.Min(x => x.Column);
                var bottomY = continentLand.Max(x => x.Row);
                var rightX  = continentLand.Max(x => x.Column);
                // Squares count in height for one square in width
                var ratioHeightWidth = (int)Math.Round((bottomY - topY + 1) / (double)(rightX - leftX + 1));

                foreach (var chunkType in chunksByType.Keys)
                {
                    chunksByType[chunkType].AddRange(FiilContinentBlueprintWithBiomeChunks(
                                                         chunksCountByType[chunkType],
                                                         chunkType.SizeInt * CHUNK_SIZE_RATIO,
                                                         topY, leftX, bottomY, rightX, ratioHeightWidth, chunkType.Temperatures));
                }

                // Rivers count on the continent.
                var riversCount = (int)Math.Round(continentLand.Count * BiomePivot.River.AppearanceRate);

                for (int i = 0; i < riversCount; i++)
                {
                    var river = new List <Tuple <int, int> >();

                    // Random river starting point.
                    var riverPt = new Tuple <int, int>(
                        Tools.Randomizer.Next(topY, bottomY),
                        Tools.Randomizer.Next(leftX, rightX)
                        );

                    // The river can go in two directions [(bottom or top) and (left or right)]
                    var forbiddenDirection1 = (DirectionPivot)Tools.Randomizer.Next(2, 4);
                    var forbiddenDirection2 = (DirectionPivot)Tools.Randomizer.Next(0, 2);

                    // Loops until the river reachs the coast, or another river.
                    while (riverPt.Item1 >= topY &&
                           riverPt.Item1 <= bottomY &&
                           riverPt.Item2 >= leftX &&
                           riverPt.Item2 <= rightX &&
                           !rivers.Any(r => r.Any(rsquare => rsquare.Item1 == riverPt.Item1 && rsquare.Item2 == riverPt.Item2)))
                    {
                        river.Add(riverPt);

                        DirectionPivot currentDirection;
                        do
                        {
                            // Picks a random direction, which can't be a forbidden one.
                            currentDirection = (DirectionPivot)Tools.Randomizer.Next(0, 4);
                        }while (currentDirection == forbiddenDirection1 || currentDirection == forbiddenDirection2);

                        riverPt = new Tuple <int, int>(
                            riverPt.Item1 + (currentDirection == DirectionPivot.Bottom ? 1 : (currentDirection == DirectionPivot.Top ? -1 : 0)),
                            riverPt.Item2 + (currentDirection == DirectionPivot.Right ? 1 : (currentDirection == DirectionPivot.Left ? -1 : 0))
                            );
                    }

                    rivers.Add(river);
                }

                // Huts count on the continent.
                var hutsCount = (int)Math.Round(continentLand.Count * HUT_APPEARANCE_RATE);

                // Creates hut locations.
                for (int i = 0; i < hutsCount; i++)
                {
                    Tuple <int, int> hutPoint;
                    do
                    {
                        hutPoint = new Tuple <int, int>(
                            Tools.Randomizer.Next(topY, bottomY),
                            Tools.Randomizer.Next(leftX, rightX)
                            );
                    }while (huts.Any(h => h.Item1 == hutPoint.Item1 && h.Item2 == hutPoint.Item2));

                    huts.Add(hutPoint);
                }
            }

            foreach (var type in chunksByType.Keys)
            {
                foreach (var chunkOfType in chunksByType[type])
                {
                    foreach (var ofType in chunkOfType)
                    {
                        var currSq = _mapSquareList[ofType.Item1, ofType.Item2];
                        currSq.ChangeBiome(type);
                    }
                }
            }

            // Overrides chunks with river squares.
            rivers.ForEach(r =>
                           r.ForEach(rSquare =>
                                     _mapSquareList[rSquare.Item1, rSquare.Item2].ChangeBiome(BiomePivot.River)));

            // Add huts.
            foreach (var hSquare in huts)
            {
                HutPivot hut      = null;
                var      location = _mapSquareList[hSquare.Item1, hSquare.Item2];
                var      typeHut  = Tools.Randomizer.Next(0, 6);
                switch (typeHut)
                {
                case 0:
                    hut = HutPivot.EmptyHut(location);
                    break;

                case 1:
                    hut = HutPivot.AdvanceHut(location);
                    break;

                case 2:
                    hut = HutPivot.BarbariansHut(location);
                    break;

                case 3:
                    hut = HutPivot.SettlerHut(location);
                    break;

                case 4:
                    hut = HutPivot.FriendlyCavalryUnitHut(location);
                    break;

                case 5:
                    hut = HutPivot.GoldHut(location);
                    break;
                }
                if (hut != null)
                {
                    _huts.Add(hut);
                }
            }
        }