Esempio n. 1
0
        /// <summary>
        ///   Makes summary text
        /// </summary>
        /// <param name="previousPopulations">If provided comparisons to previous populations is included</param>
        /// <param name="playerReadable">if true ids are removed from the output</param>
        /// <param name="effects">if not null these effects are applied to the population numbers</param>
        public string MakeSummary(PatchMap previousPopulations = null,
                                  bool playerReadable          = false, List <ExternalEffect> effects = null)
        {
            const bool resolveMoves = true;

            var builder = new StringBuilder(500);

            string PatchString(Patch patch)
            {
                var builder2 = new StringBuilder(80);

                if (!playerReadable)
                {
                    builder2.Append(patch.ID);
                }

                builder2.Append(" ");
                builder2.Append(patch.Name);

                return(builder2.ToString());
            }

            void OutputPopulationForPatch(Species species, Patch patch, long population)
            {
                if (population > 0)
                {
                    builder.Append("  ");
                    builder.Append(PatchString(patch));
                    builder.Append(" ");
                    builder.Append(TranslationServer.Translate("POPULATION"));
                    builder.Append(" ");
                    builder.Append(population);
                }
                else
                {
                    builder.Append("  ");
                    builder.Append(" went extinct in ");
                    builder.Append(PatchString(patch));
                }

                if (previousPopulations != null)
                {
                    builder.Append(" ");
                    builder.Append(TranslationServer.Translate("PREVIOUS"));
                    builder.Append(" ");
                    builder.Append(previousPopulations.GetPatch(patch.ID).GetSpeciesPopulation(species));
                }

                builder.Append("\n");
            }

            foreach (var entry in results.Values)
            {
                builder.Append(playerReadable ? entry.Species.FormattedName : entry.Species.FormattedIdentifier);
                builder.Append(":\n");

                if (entry.MutatedProperties != null)
                {
                    builder.Append(" ");
                    builder.Append(TranslationServer.Translate("RUNRESULT_HAS_A_MUTATION"));

                    if (!playerReadable)
                    {
                        builder.Append(", ");
                        builder.Append(TranslationServer.Translate("RUNRESULT_GENE_CODE"));
                        builder.Append(" ");
                        builder.Append(entry.MutatedProperties.StringCode);
                    }

                    builder.Append("\n");
                }

                if (entry.SpreadToPatches.Count > 0)
                {
                    builder.Append(" ");
                    builder.Append(TranslationServer.Translate("RUNRESULT_SPREAD_TO_PATCHES"));
                    builder.Append("\n");

                    foreach (var spreadEntry in entry.SpreadToPatches)
                    {
                        if (playerReadable)
                        {
                            builder.Append("  ");
                            builder.Append(string.Format(CultureInfo.CurrentCulture,
                                                         TranslationServer.Translate("RUNRESULT_BY_SENDING_POPULATION"),
                                                         spreadEntry.To.Name, spreadEntry.Population, spreadEntry.From.Name));
                        }
                        else
                        {
                            builder.Append("  ");
                            builder.Append(spreadEntry.To.Name);
                            builder.Append(" pop: ");
                            builder.Append(spreadEntry.Population);
                            builder.Append(" from: ");
                            builder.Append(spreadEntry.From.Name);
                        }

                        builder.Append("\n");
                    }
                }

                builder.Append(" ");
                builder.Append(TranslationServer.Translate("RUNRESULT_POP_IN_PATCHES"));
                builder.Append("\n");

                foreach (var patchPopulation in entry.NewPopulationInPatches)
                {
                    long adjustedPopulation = patchPopulation.Value;

                    if (resolveMoves)
                    {
                        adjustedPopulation +=
                            CountSpeciesSpreadPopulation(entry.Species, patchPopulation.Key);
                    }

                    // Apply external effects
                    if (effects != null && previousPopulations != null &&
                        previousPopulations.CurrentPatch.ID == patchPopulation.Key.ID)
                    {
                        foreach (var effect in effects)
                        {
                            if (effect.Species == entry.Species)
                            {
                                adjustedPopulation +=
                                    effect.Constant + (long)(effect.Species.Population * effect.Coefficient)
                                    - effect.Species.Population;
                            }
                        }
                    }

                    // As the populations are added to all patches, even when the species is not there, we remove those
                    // from output if there is currently no population in a patch and there isn't one in
                    // previousPopulations
                    var include = false;

                    if (adjustedPopulation > 0)
                    {
                        include = true;
                    }
                    else if (previousPopulations != null)
                    {
                        if (previousPopulations.GetPatch(patchPopulation.Key.ID).GetSpeciesPopulation(entry.Species) >
                            0)
                        {
                            include = true;
                        }
                    }

                    if (include)
                    {
                        OutputPopulationForPatch(entry.Species, patchPopulation.Key, adjustedPopulation);
                    }
                }

                // Also print new patches the species moved to (as the moves don't get
                // included in newPopulationInPatches
                if (resolveMoves)
                {
                    foreach (var spreadEntry in entry.SpreadToPatches)
                    {
                        var found = false;

                        var to = spreadEntry.To;

                        foreach (var populationEntry in entry.NewPopulationInPatches)
                        {
                            if (populationEntry.Key == to)
                            {
                                found = true;
                                break;
                            }
                        }

                        if (!found)
                        {
                            OutputPopulationForPatch(entry.Species, to,
                                                     CountSpeciesSpreadPopulation(entry.Species, to));
                        }
                    }
                }

                if (GetGlobalPopulation(entry.Species, resolveMoves) <= 0)
                {
                    builder.Append(" ");
                    builder.Append("went extinct from the planet");
                    builder.Append("\n");
                }

                if (playerReadable)
                {
                    builder.Append("\n");
                }
            }

            return(builder.ToString());
        }
Esempio n. 2
0
        /// <summary>
        ///   Makes summary text
        /// </summary>
        /// <param name="previousPopulations">If provided comparisons to previous populations is included</param>
        /// <param name="playerReadable">if true ids are removed from the output</param>
        /// <param name="effects">if not null these effects are applied to the population numbers</param>
        /// <returns>The generated summary text</returns>
        public LocalizedStringBuilder MakeSummary(PatchMap previousPopulations = null,
                                                  bool playerReadable          = false, List <ExternalEffect> effects = null)
        {
            const bool resolveMigrations = true;
            const bool resolveSplits     = true;

            var builder = new LocalizedStringBuilder(500);

            LocalizedStringBuilder PatchString(Patch patch)
            {
                var builder2 = new LocalizedStringBuilder(80);

                if (!playerReadable)
                {
                    builder2.Append(patch.ID);
                }

                builder2.Append(' ');
                builder2.Append(new LocalizedString(patch.Name));

                return(builder2);
            }

            void OutputPopulationForPatch(Species species, Patch patch, long population)
            {
                builder.Append("  ");
                var patchName = PatchString(patch);

                if (population > 0)
                {
                    builder.Append(patchName);
                    builder.Append(' ');
                    builder.Append(new LocalizedString("POPULATION"));
                    builder.Append(' ');
                    builder.Append(population);
                }
                else
                {
                    // For some reason this line had one more space padding than the case that the population
                    // wasn't extinct in this patch

                    builder.Append(new LocalizedString("WENT_EXTINCT_IN", patchName));
                }

                if (previousPopulations != null)
                {
                    builder.Append(' ');
                    builder.Append(new LocalizedString("PREVIOUS"));
                    builder.Append(' ');
                    builder.Append(previousPopulations.GetPatch(patch.ID).GetSpeciesPopulation(species));
                }

                builder.Append('\n');
            }

            foreach (var entry in
                     results.Values.OrderByDescending(s => s.Species.PlayerSpecies)
                     .ThenBy(s => s.Species.FormattedName))
            {
                builder.Append(playerReadable ? entry.Species.FormattedName : entry.Species.FormattedIdentifier);
                builder.Append(":\n");

                if (entry.SplitFrom != null)
                {
                    builder.Append(' ');
                    builder.Append(new LocalizedString("RUN_RESULT_SPLIT_FROM",
                                                       playerReadable ? entry.SplitFrom.FormattedName : entry.SplitFrom.FormattedIdentifier));

                    builder.Append('\n');
                }

                if (entry.NewlyCreated != null)
                {
                    builder.Append(' ');

                    switch (entry.NewlyCreated.Value)
                    {
                    case NewSpeciesType.FillNiche:
                        builder.Append(new LocalizedString("RUN_RESULT_NICHE_FILL"));
                        break;

                    case NewSpeciesType.SplitDueToMutation:
                        builder.Append(new LocalizedString("RUN_RESULT_SELECTION_PRESSURE_SPLIT"));
                        break;

                    default:
                        GD.PrintErr("Unhandled newly created species type: ", entry.NewlyCreated.Value);
                        builder.Append(entry.NewlyCreated.Value);
                        break;
                    }

                    builder.Append('\n');
                }

                if (entry.SplitOff != null)
                {
                    if (entry.SplitOffPatches == null)
                    {
                        throw new InvalidOperationException("List of split off patches is null");
                    }

                    builder.Append(' ');
                    builder.Append(new LocalizedString("RUN_RESULT_SPLIT_OFF_TO",
                                                       playerReadable ? entry.SplitOff.FormattedName : entry.SplitOff.FormattedIdentifier));
                    builder.Append('\n');

                    foreach (var patch in entry.SplitOffPatches)
                    {
                        builder.Append("   ");

                        builder.Append(new LocalizedString(patch.Name));
                        builder.Append('\n');
                    }
                }

                if (entry.MutatedProperties != null)
                {
                    builder.Append(' ');
                    builder.Append(new LocalizedString("RUN_RESULT_HAS_A_MUTATION"));

                    if (!playerReadable)
                    {
                        builder.Append(", ");
                        builder.Append(new LocalizedString("RUN_RESULT_GENE_CODE"));
                        builder.Append(' ');
                        builder.Append(entry.MutatedProperties.StringCode);
                    }

                    builder.Append('\n');
                }

                if (entry.SpreadToPatches.Count > 0)
                {
                    builder.Append(' ');
                    builder.Append(new LocalizedString("RUN_RESULT_SPREAD_TO_PATCHES"));
                    builder.Append('\n');

                    foreach (var spreadEntry in entry.SpreadToPatches)
                    {
                        if (playerReadable)
                        {
                            builder.Append("  ");
                            builder.Append(new LocalizedString("RUN_RESULT_BY_SENDING_POPULATION",
                                                               new LocalizedString(spreadEntry.To.Name), spreadEntry.Population,
                                                               new LocalizedString(spreadEntry.From.Name)));
                        }
                        else
                        {
                            builder.Append("  ");
                            builder.Append(new LocalizedString(spreadEntry.To.Name));
                            builder.Append(" pop: ");
                            builder.Append(spreadEntry.Population);
                            builder.Append(" from: ");
                            builder.Append(new LocalizedString(spreadEntry.From.Name));
                        }

                        builder.Append('\n');
                    }
                }

                builder.Append(' ');
                builder.Append(new LocalizedString("RUN_RESULT_POP_IN_PATCHES"));
                builder.Append('\n');

                foreach (var patchPopulation in entry.NewPopulationInPatches)
                {
                    long adjustedPopulation = patchPopulation.Value;

                    if (resolveMigrations)
                    {
                        adjustedPopulation +=
                            CountSpeciesSpreadPopulation(entry.Species, patchPopulation.Key);
                    }

                    if (resolveSplits)
                    {
                        if (entry.SplitOffPatches?.Contains(patchPopulation.Key) == true)
                        {
                            // All population splits off
                            adjustedPopulation = 0;
                        }
                    }

                    // Apply external effects
                    if (effects != null && previousPopulations != null &&
                        previousPopulations.CurrentPatch.ID == patchPopulation.Key.ID)
                    {
                        foreach (var effect in effects)
                        {
                            if (effect.Species == entry.Species)
                            {
                                adjustedPopulation +=
                                    effect.Constant + (long)(effect.Species.Population * effect.Coefficient)
                                    - effect.Species.Population;
                            }
                        }
                    }

                    // As the populations are added to all patches, even when the species is not there, we remove those
                    // from output if there is currently no population in a patch and there isn't one in
                    // previousPopulations
                    var include = false;

                    if (adjustedPopulation > 0)
                    {
                        include = true;
                    }
                    else
                    {
                        if (previousPopulations?.GetPatch(patchPopulation.Key.ID).GetSpeciesPopulation(entry.Species) >
                            0)
                        {
                            include = true;
                        }
                    }

                    if (include)
                    {
                        OutputPopulationForPatch(entry.Species, patchPopulation.Key, adjustedPopulation);
                    }
                }

                // Also print new patches the species moved to (as the moves don't get
                // included in newPopulationInPatches
                if (resolveMigrations)
                {
                    foreach (var spreadEntry in entry.SpreadToPatches)
                    {
                        var found = false;

                        var to = spreadEntry.To;

                        foreach (var populationEntry in entry.NewPopulationInPatches)
                        {
                            if (populationEntry.Key == to)
                            {
                                found = true;
                                break;
                            }
                        }

                        if (!found)
                        {
                            OutputPopulationForPatch(entry.Species, to,
                                                     CountSpeciesSpreadPopulation(entry.Species, to));
                        }
                    }
                }

                // Print populations from splits
                // Warning suppressed on resolveSplits to allow keeping the variable
                // ReSharper disable once RedundantLogicalConditionalExpressionOperand
                if (resolveSplits && entry.SplitFrom != null)
                {
                    var splitFrom = results[entry.SplitFrom];

                    // Skip if the SplitFrom variable was used just to indicate this didn't pop out of thin air
                    if (splitFrom.SplitOff == entry.Species)
                    {
                        foreach (var patchPopulation in splitFrom.SplitOffPatches)
                        {
                            OutputPopulationForPatch(entry.Species, patchPopulation,
                                                     splitFrom.NewPopulationInPatches[patchPopulation]);
                        }
                    }
                }

                if (GetGlobalPopulation(entry.Species, resolveMigrations, resolveSplits) <= 0)
                {
                    builder.Append(' ');
                    builder.Append(new LocalizedString("WENT_EXTINCT_FROM_PLANET"));
                    builder.Append('\n');
                }

                if (playerReadable)
                {
                    builder.Append('\n');
                }
            }

            return(builder);
        }
Esempio n. 3
0
        /// <summary>
        ///   Makes summary text
        /// </summary>
        /// <param name="previousPopulations">If provided comparisons to previous populations is included</param>
        /// <param name="playerReadable">if true ids are removed from the output</param>
        /// <param name="effects">if not null these effects are applied to the population numbers</param>
        public string MakeSummary(PatchMap previousPopulations = null,
                                  bool playerReadable          = false, List <ExternalEffect> effects = null)
        {
            const bool resolveMoves = true;

            var builder = new StringBuilder(500);

            string PatchString(Patch patch)
            {
                var builder2 = new StringBuilder(80);

                if (!playerReadable)
                {
                    builder2.Append(patch.ID);
                }

                builder2.Append(" ");
                builder2.Append(patch.Name);

                return(builder2.ToString());
            }

            void OutputPopulationForPatch(Species species, Patch patch, int population)
            {
                builder.Append("  ");

                builder.Append(PatchString(patch));

                builder.Append(" population: ");
                builder.Append(Math.Max(population, 0));

                if (previousPopulations != null)
                {
                    builder.Append(" previous: ");
                    builder.Append(previousPopulations.GetPatch(patch.ID).GetSpeciesPopulation(species));
                }

                builder.Append("\n");
            }

            foreach (var entry in results.Values)
            {
                builder.Append(playerReadable ? entry.Species.FormattedName : entry.Species.FormattedIdentifier);
                builder.Append(":\n");

                if (entry.MutatedProperties != null)
                {
                    builder.Append(" has a mutation");

                    if (!playerReadable)
                    {
                        builder.Append(", gene code: ");
                        builder.Append(entry.MutatedProperties.StringCode);
                    }

                    builder.Append("\n");
                }

                if (entry.SpreadToPatches.Count > 0)
                {
                    builder.Append(" spread to patches:\n");

                    foreach (var spreadEntry in entry.SpreadToPatches)
                    {
                        if (playerReadable)
                        {
                            builder.Append("  ");
                            builder.Append(spreadEntry.To.Name);
                            builder.Append(" by sending: ");
                            builder.Append(spreadEntry.Population);
                            builder.Append(" population");
                            builder.Append(" from patch: ");
                            builder.Append(spreadEntry.From.Name);
                        }
                        else
                        {
                            builder.Append("  ");
                            builder.Append(spreadEntry.To.Name);
                            builder.Append(" pop: ");
                            builder.Append(spreadEntry.Population);
                            builder.Append(" from: ");
                            builder.Append(spreadEntry.From.Name);
                        }

                        builder.Append("\n");
                    }
                }

                builder.Append(" population in patches:\n");

                foreach (var patchPopulation in entry.NewPopulationInPatches)
                {
                    var adjustedPopulation = patchPopulation.Value;

                    if (resolveMoves)
                    {
                        adjustedPopulation +=
                            CountSpeciesSpreadPopulation(entry.Species, patchPopulation.Key);
                    }

                    // Apply external effects
                    if (effects != null && previousPopulations != null &&
                        previousPopulations.CurrentPatch.ID == patchPopulation.Key.ID)
                    {
                        foreach (var effect in effects)
                        {
                            if (effect.Species == entry.Species)
                            {
                                adjustedPopulation += effect.Amount;
                            }
                        }
                    }

                    // As the populations are added to all patches, even when the species is not there, we remove those
                    // from output if there is currently no population in a patch and there isn't one in
                    // previousPopulations
                    bool include = false;

                    if (adjustedPopulation > 0)
                    {
                        include = true;
                    }
                    else if (previousPopulations != null)
                    {
                        if (previousPopulations.GetPatch(patchPopulation.Key.ID).GetSpeciesPopulation(entry.Species) >
                            0)
                        {
                            include = true;
                        }
                    }

                    if (include)
                    {
                        OutputPopulationForPatch(entry.Species, patchPopulation.Key, adjustedPopulation);
                    }
                }

                // Also print new patches the species moved to (as the moves don't get
                // included in newPopulationInPatches
                if (resolveMoves)
                {
                    foreach (var spreadEntry in entry.SpreadToPatches)
                    {
                        bool found = false;

                        var to = spreadEntry.To;

                        foreach (var populationEntry in entry.NewPopulationInPatches)
                        {
                            if (populationEntry.Key == to)
                            {
                                found = true;
                                break;
                            }
                        }

                        if (!found)
                        {
                            OutputPopulationForPatch(entry.Species, to,
                                                     CountSpeciesSpreadPopulation(entry.Species, to));
                        }
                    }
                }

                if (playerReadable)
                {
                    builder.Append("\n");
                }
            }

            return(builder.ToString());
        }