/// <summary> /// Kills the worst scoring organisms and gets the species ready for the next generation. /// </summary> /// <param name="topAmountToSurvive">The top amount percentage to survive.</param> /// <param name="generation">The current generation.</param> internal void PostGeneration(double topAmountToSurvive, uint generation) { // Remove all organisms from the last generation. Organisms.RemoveAll(o => o.Generation == generation - 1); // Sum all of the scores of the current generation. SpeciesScore = Organisms.Sum(organism => organism.Score); // Sort the organisms to make sure they are in other from good to bad. Organisms.Sort((a, b) => { if (a.Score < b.Score) { return(1); } if (a.Score > b.Score) { return(-1); } return(0); }); // Calculate how many organisms should survive, these will later reproduce so it doesn't matter // if there are too many surviving (eg 1.5 > 2). But, we want to make sure at least 1 survives. int organismsToSurvive = (int)Math.Ceiling(Organisms.Count * topAmountToSurvive); // Sets the current organisms to a certain amount of the top organisms that have been sorted before. Organisms = Organisms.Take(organismsToSurvive).ToList(); }
/// <summary> /// Checks if the organism is of the same species. /// It compares the given organism to a randomly chosen organism from the species. /// </summary> /// <param name="organism">The organism to check.</param> /// <param name="trainingRoomSettings">The training rooms settings.</param> /// <returns>Returns <c>true</c> if he organism is of the same species; otherwise, <c>false</c>.</returns> internal bool IsSameSpecies(Organism organism, TrainingRoomSettings trainingRoomSettings) { // If the generation is 0, only 1 species should exist. // So, there is no need check for the same species. if (organism.Generation == 0) { return(true); } // Get all organisms from the previous generation. List <Organism> lastGenOrganisms = Organisms.FindAll(org => org.Generation == organism.Generation - 1); // If the last generation does not contain any organisms, that indicates that the species is new. if (!lastGenOrganisms.Any()) { // The new species will only have organisms from the current generation. // So, we make the current organisms the representatives of the last generation. lastGenOrganisms = Organisms; } // Gets the randomly selected organism from the last generation organisms. Organism organismToCompare = lastGenOrganisms[trainingRoomSettings.Random.Next(lastGenOrganisms.Count)]; // Compares if the organism is from the same species. return(organismToCompare.IsSameSpecies(organism, trainingRoomSettings)); }
/// <summary> /// Kills the worst scoring organisms and gets the species ready for the next generation. /// </summary> /// <param name="topAmountToSurvive">The top amount percentage to survive.</param> public void PostGeneration(double topAmountToSurvive) { SpeciesScore = Organisms.Sum(organism => organism.Score); Organisms.Sort((a, b) => { if (a.Score < b.Score) { return(1); } if (a.Score > b.Score) { return(-1); } return(0); }); int organismsToSurvive = (int)Math.Ceiling(Organisms.Count * topAmountToSurvive); LastGenerationOrganisms.Clear(); LastGenerationOrganisms = Organisms.Take(organismsToSurvive).Select(organism => { Organism org = organism.Clone(); org.Generation++; return(org); }).ToList(); // TODO: Check if clone is needed, may just be useless instance creation Organisms.Clear(); }
private void BuildOrganismsList(ObservableCollection <DmsDatabaseServerViewModel> servers) { var map = new Dictionary <string, string>(); var orderedServers = servers.OrderBy(x => x.Organism.ToLower()); foreach (var server in orderedServers) { if (!map.ContainsKey(server.Organism)) { map.Add(server.Organism, server.Organism); } } var tempOrganism = m_organismFilter; Organisms.Clear(); Organisms.Add(CONST_ANY_ORGANISM); foreach (var organism in map.Values) { if (organism != "") { Organisms.Add(organism); } } SelectedOrganism = tempOrganism; }
/// <summary> /// Attempt to position the given item at the given index. If the space is occupied already it will fail. /// </summary> /// <param name="item">The item to be positioned.</param> /// <param name="x">The x index of the tile to position at.</param> /// <param name="y">The y index of the tile to position at.</param> /// <returns>True if successfully positioned, false if the space was occupied.</returns> public bool AttemptToPositionAt(GridItem item, int x, int y) { if (!InBounds(x, y) || this.tiles[x][y].HasInhabitant) { return(false); // Space occupied } this.tiles[x][y].AddInhabitant(item); item.SetInitialScreenPosition(x * Tile.TILE_SIZE, y * Tile.TILE_SIZE, Tile.TILE_SIZE, Tile.TILE_SIZE); // Add the item to the simulation and set up appropriate event handlers if (item.GetType() == typeof(Organism)) { var organism = (Organism)item; organism.DeathOccurred += OrganismDeathHandler; Organisms.Add(organism); } else if (item.GetType() == typeof(Food)) { var food = (Food)item; food.DeathOccurred += FoodEatenHandler; Foods.Add(food); } return(true); // Successfully positioned }
private double CalculateMeanLibido() { if (Population == 0) { return(0); } return(Organisms.Average(o => o.GetGeneByType(GeneEnum.Libido).CurrentValue)); }
private void RemoveTheDead() { ThisPeriodStats.Died = CurrentDyingCount; LastDyingCount = CurrentDyingCount; // Adding to a public list for db persistence DeadOrganisms.AddRange(Organisms.Where(r => r.IsDead)); Organisms.RemoveAll(r => r.IsDead); }
private void AddTheBabies() { ThisPeriodStats.Born = CurrentBabyCount; Organisms.AddRange(Babies); LastBabyCount = CurrentBabyCount; Babies.RemoveAll(r => true); }
private void Populate() { _organisms = new List <Organism>(); for (var i = 0; i < InitialOrganismCount; i++) { var organism = new Organism(this, null); Organisms.Add(organism); } }
/// <summary> /// Adds the organism if it fits this species. /// It compares the given organism to a randomly chosen organism from the species. /// </summary> /// <param name="organism">The organism to check.</param> /// <param name="randomNext">The random next.</param> /// <returns>Returns <c>true</c> if it is added; otherwise, <c>false</c>.</returns> public bool AddOrganismIfSameSpecies(Organism organism, Func <int, int> randomNext) { if (!GetRandomOrganism(randomNext).IsSameSpecies(organism)) { return(false); } organism.SpeciesId = Id; Organisms.Add(organism); return(true); }
public void RenderPlants() { // Get animals from organisms list var plantList = Organisms.Where(o => o is Plant); foreach (Plant plant in plantList) { RenderPlant(plant); } }
/// <summary> /// Kills the worst scoring organisms and gets the species ready for the next generation. /// </summary> /// <param name="topAmountToSurvive">The top amount percentage to survive.</param> /// <param name="generation">The current generation.</param> /// <param name="markForRemoval">The mark for removal action.</param> internal void PostGeneration(double topAmountToSurvive, uint generation, Action <Organism> markForRemoval) { // Mark organisms for removal. foreach (Organism organism in Organisms.Where(o => o.Generation == generation - 1)) { markForRemoval(organism); } // Increment the stagnant counter StagnantCounter++; // Remove all organisms from the last generation. Organisms.RemoveAll(o => o.Generation == generation - 1); // Sum all of the scores of the current generation. SpeciesScore = Organisms.Sum(organism => organism.Score); double highestScore = Organisms.Max(organism => organism.Score); // Check for a new high score. Update it and reset the stagnant counter if needed. if (highestScore > HighScore) { HighScore = highestScore; StagnantCounter = 0; } // Sort the organisms to make sure they are in other from good to bad. Organisms.Sort((a, b) => { if (a.Score < b.Score) { return(1); } if (a.Score > b.Score) { return(-1); } return(0); }); // Calculate how many organisms should survive, these will later reproduce so it doesn't matter // if there are too many surviving (eg 1.5 > 2). But, we want to make sure at least 1 survives. int organismsToSurvive = (int)Math.Ceiling(Organisms.Count * topAmountToSurvive); // Mark organisms for removal. foreach (Organism organism in Organisms.Skip(organismsToSurvive - 1).Take(Organisms.Count - organismsToSurvive)) { markForRemoval(organism); } // Sets the current organisms to a certain amount of the top organisms that have been sorted before. Organisms.RemoveRange(organismsToSurvive - 1, Organisms.Count - organismsToSurvive); }
/// <summary> /// Calculates the average fitness score of the species. /// </summary> public void CalculateFitnessScore() { if (Organisms.Count == 0) { AverageFitnessScore = 0; } else { AverageFitnessScore = Organisms.Average(x => x.FitnessScore); } }
public Group Join(Organism organism) { Organisms.Add(organism); organism.Group = this; organism.GroupId = Id; StorageCapacity += organism.StorageCapacity; StorageLevel += organism.StorageLevel; EconomyScore = GetEconomyScore(); MilitaryScore = GetMilitaryScore(); return(this); }
/// <summary> /// Gets the most fit organism's neural network currently in the generation. Runs <see cref="NEAT.NEATClient.Speciate"/> and <see cref="NEAT.NEATClient.EvaluateScores"/> /// first just in case it is needed. /// </summary> /// <returns>The most fit organism's neural network.</returns> public NeuralNetwork GetMostFitOrganism() { Speciate(); EvaluateScores(); Organisms.Sort(); //Sorts the organisms by fitness score, greatest to lowest. return(Organisms[0].NeuralNetwork); }
public Group Remove(Organism organism) { // we do not physically remove the organism from the group for record keeping purposes DepartedOrganisms.Add(organism); Organisms.Remove(organism); // A member is gone. Capacity is diminished. Ensure actual level does not exceed capacity. //StorageCapacity -= organism.StorageCapacity; //StorageLevel = Math.Min(StorageLevel, StorageCapacity); EconomyScore = GetEconomyScore(); MilitaryScore = GetMilitaryScore(); return(this); }
public double OrganismStealsFood(Organism organism, int killProbability) { if (Population < 2) { // Nobody to steal from return(0); } Organism victim = null; int searchCount = MaxPopulationToSupport / 10; var curIdx = Organisms.IndexOf(organism); bool killsVictim = false; for (int i = 0; i < searchCount; i++) { int foundIdx; // find random organism, ignore self do { foundIdx = RandomHelper.StandardGeneratorInstance.Next(0, Population); }while (curIdx == foundIdx); if (CanSteal(organism, Organisms[foundIdx], killProbability, out killsVictim)) { victim = Organisms[foundIdx]; break; } } if (victim == null) { return(0); } // Steal from found victim // How much is stolen? // Let's assume 50% of victim's inventory is stolen. If the victim is killed then 100% of the inventory is stolen. double stolenAmount = killsVictim ? victim.StorageLevel : victim.StorageLevel / 2; if (killsVictim) { victim.Die("Killed"); } else { victim.DecreaseStorageLevel(stolenAmount, "Stolen"); } return(stolenAmount); }
/// <summary> /// Kills all of the worst performing organisms. The percentage that will die is 1 - <see cref="NEAT.NEATClient.SurvivingPercentage"/>. /// See <see cref="NEAT.NEATClient.Evolve"/> before using! /// </summary> public void Kill() { Organisms.Sort(); //Sorts the organisms by fitness score, greatest to lowest. double num_toKill = (1 - SurvivingPercentage) * Organisms.Count; for (int i = 0; i < num_toKill; ++i) { Organism organism = Organisms[Organisms.Count - 1]; organism.Species.RemoveOrganism(organism); Organisms.RemoveAt(Organisms.Count - 1); } }
/// <summary> /// Gets a random organism from this species. /// </summary> /// <param name="generation">The current generation.</param> /// <param name="trainingRoomSettings">The training room settings.</param> /// <returns>Returns a randomly chosen <see cref="Organism"/>.</returns> internal Organism GetRandomOrganism(uint generation, TrainingRoomSettings trainingRoomSettings) { // Gets the current generation organisms. List <Organism> currentGen = Organisms.FindAll(o => o.Generation == generation); // Return the only organism or a random organism. if (currentGen.Count == 1) { return(currentGen.First()); } if (currentGen.Count > 1) { return(currentGen[trainingRoomSettings.Random.Next(currentGen.Count)]); } // Should never happen! throw new Exception($"The organisms does not contain a organism at the generation: {generation}"); }
/* Methods */ public void RenderAnimals() { // Get animals from organisms list var animalList = Organisms.Where(o => o is Animal); foreach (Animal animal in animalList) { // Set previous position to ground tile Console.SetCursorPosition( animal.LastPosition.X, animal.LastPosition.Y ); Console.ForegroundColor = ConsoleColor.DarkYellow; Console.Write(StringManager.GetExtendedAsciiCodeAsString(176)); // Update current position Console.SetCursorPosition( animal.Position.X, animal.Position.Y ); Console.ForegroundColor = animal.DisplayColor; Console.Write(animal.DisplayLetter); } }
/// <summary> /// Used when a cooperative organism is searching its vicinity for another cooperative organism that is similar minded. /// Cannot search just vicinity because if there is no one in vicinity then for many iterations this will not change /// Also individuals meet different individuals every iteration in real life. So meetings must be random /// </summary> public Organism SearchVicinityForSimilarCooperativeIndividuals(Organism organism) { if (Population < 2) { return(null); } int searchCount = MaxPopulationToSupport / 10; var curIdx = Organisms.IndexOf(organism); for (int i = 0; i < searchCount; i++) { int foundIdx; // find random organism, ignore self do { foundIdx = RandomHelper.StandardGeneratorInstance.Next(0, Population); }while (curIdx == foundIdx); if (AreMatched(organism, Organisms[foundIdx])) { return(Organisms[foundIdx]); } } return(null); }
/// <summary> /// Adds the organism to the list of organisms and sets it species id. /// </summary> /// <param name="organism">The organism to add.</param> internal void AddOrganism(Organism organism) { organism.SpeciesId = Id; Organisms.Add(organism); }
/// <summary> /// Gets a random organism. /// </summary> /// <param name="random">The random object to use.</param> /// <returns>A random organism.</returns> public Organism GetRandomOrganism(Random random) { return(Organisms.RandomValue(random)); }
/// <summary> /// Tells whether or not the given organism is in this species. /// </summary> /// <param name="organism">The organism to check.</param> /// <returns>True if the organism is present. False otherwise.</returns> public bool ContainsOrganism(Organism organism) { return(Organisms.Contains(organism)); }
/// <summary> /// Removes this organism from the species. Sets the <see cref="NEAT.Speciation.Organism.Species"/> propterty to null. /// </summary> /// <param name="organism">The organism to remove.</param> /// <returns>True if the organism is already present, therefore removed. False otherwise.</returns> public bool RemoveOrganism(Organism organism) { organism.Species = null; return(Organisms.Remove(organism)); }
/// <summary> /// Adds this organism to the species. Sets the <see cref="NEAT.Speciation.Organism.Species"/> propterty to this species. /// </summary> /// <param name="organism">The organism to add.</param> /// <returns>False if the organism is already present, therefore not added. True otherwise.</returns> public bool AddOrganism(Organism organism) { organism.Species = this; return(Organisms.Add(organism)); }
/// <summary> /// Returns an enumerator that iterates through the internal organisms. /// </summary> /// <returns>A <see cref="System.Collections.Generic.HashSet{T}.Enumerator"/>, that is the internals.</returns> public IEnumerator <Organism> GetEnumerator() { return(Organisms.GetEnumerator()); }
/// <summary> /// Gets a random organism excluding the given organism. /// </summary> /// <param name="random">The random object to use.</param> /// <param name="excluding_organism">The organism to exclude from the search.</param> /// <returns>A random organism.</returns> public Organism GetRandomOrganism(Random random, Organism excluding_organism) { return(Organisms.RandomValue(random, excluding_organism)); }
/// <summary> /// Reproduces the surviving species based on their fitness scores. Chooses the organisms in the species to mate based on fitness scores as well. Replaces the previous generation /// with the newly created organisms. Removes extinct species if necessary. Adjusts compatibility distance after replacement. /// See <see cref="NEAT.NEATClient.Evolve"/> before using! /// </summary> /// <remarks> /// Decides the amount of offspring (nk) each species (k) should be allotted via the following equation: /// <para/> /// nk = P * (Fk / Ft) /// <para/> /// Where: /// <list type="bullet"> /// <item>k: The species.</item> /// <item>nk: The number of new organisms for species k in the next generation.</item> /// <item>P: The desired new population count.</item> /// <item>Fk: The average fitness score of the species.</item> /// <item>Ft: The sum of all fitness score averages of every species.</item> /// </list> /// </remarks> public void ReproduceAndReplace() { double total_speciesFitness = Species.Sum(x => x.AverageFitnessScore); Dictionary <Species, ReproduceAndReplace_Node> stored_distributionsSpecies = new Dictionary <Species, ReproduceAndReplace_Node>(Species.Count); List <Organism> next_generation = new List <Organism>(NumOrganisms); //All of the new organisms. HashSet <Species> next_species = new HashSet <Species>(Species.Count); #region Reproduction foreach (Species species in Species) { //Calculate the number of organisms every species will have: int num_alloted_offspring = (int)(NumOrganisms * (species.AverageFitnessScore / total_speciesFitness)); //Prepare new species for placement: Species creation_species = new Species(); next_species.Add(creation_species); //Prepare ScoredDistribution for selecting organisms to mate: ScoredDistribution <Organism> internal_organisms = new ScoredDistribution <Organism>(species.Size, Pedigree.Random); foreach (Organism organism in species) { internal_organisms.Add(organism, organism.FitnessScore); } stored_distributionsSpecies.Add(species, new ReproduceAndReplace_Node(internal_organisms, creation_species)); //Actaully mate the organisms: for (int i = 0; i < num_alloted_offspring; ++i) { Organism random_organism_1 = internal_organisms.ChooseValue(); Organism random_organism_2 = internal_organisms.ChooseValue(random_organism_1); //We don't want any self-replication... if (random_organism_2 == null) { random_organism_2 = random_organism_1; //Unless that's the only option ;) Only happens when the organism is the only one in the species. } Organism baby = new Organism(random_organism_1.Genome.Crossover(random_organism_1.FitnessScore, random_organism_2.Genome, random_organism_2.FitnessScore, Pedigree.Random)); next_generation.Add(baby); creation_species.AddOrganism(baby); } } while (next_generation.Count < NumOrganisms) //We need more organisms, give it to some random species. Super rare that this doesn't happen. { ReproduceAndReplace_Node chosen_last_node = stored_distributionsSpecies[Species.RandomValue(Pedigree.Random)]; ScoredDistribution <Organism> last_round_distribution = chosen_last_node.scoredDistribution_organisms; Species last_round_species = chosen_last_node.new_species; Organism random_organism_1 = last_round_distribution.ChooseValue(); Organism random_organism_2 = last_round_distribution.ChooseValue(random_organism_1); //We don't want any self-replication... if (random_organism_2 == null) { random_organism_2 = random_organism_1; //Unless that's the only option ;) Only happens when the organism is the only one in the species. } Organism baby = new Organism(random_organism_1.Genome.Crossover(random_organism_1.FitnessScore, random_organism_2.Genome, random_organism_2.FitnessScore, Pedigree.Random)); next_generation.Add(baby); last_round_species.AddOrganism(baby); } #endregion Reproduction #region Replacement //Organisms: Organisms.Clear(); Organisms.AddRange(next_generation); //Species: Species.Clear(); foreach (Species species in next_species) { Species.Add(species); } #endregion Replacement RemoveExtinctions(); CompatibilityDistance += CD_function.Invoke(Species.Count); }
private double GetMilitaryScore() { return(Population == 0 ? 0 : Organisms.Average(org => (double)org.GetGeneValueByType(GeneEnum.Military))); }