private void killOrganisms(IDictionary organismsToKill, int organismKillCount, int totalPopulation,
bool killingAnimals)
{
const int diseaseBoundary = 10;
int killedCount = 0;
ArrayList largePopulationSpecies = new ArrayList();
Random rand = new Random(DateTime.Now.Millisecond);
if (organismsToKill == null || organismKillCount <= 0) return;
// Find the species that have large populations on the system
ICollection allSpeciesCollection = organismsToKill.Values;
foreach (SortedList list in allSpeciesCollection)
{
// For large population species, we try to maintain their population percentages with respect to the other
// large population species
if (list.Count <= diseaseBoundary) continue;
// Kill a proportional amount of this species
int speciesKillTarget = (int) ((list.Count/(double) totalPopulation)*organismKillCount);
while (list.Count > diseaseBoundary && speciesKillTarget > 0)
{
killedCount++;
speciesKillTarget--;
// Get the oldest animal of this species
OrganismState state = (OrganismState) list.GetByIndex(0);
list.RemoveAt(0);
if (killingAnimals)
{
Debug.Assert(state is AnimalState);
state.Kill(PopulationChangeReason.Sick);
}
else
{
removeOrganism(new KilledOrganism(state.ID, PopulationChangeReason.Sick));
}
}
if (list.Count > diseaseBoundary)
{
largePopulationSpecies.Add(list);
}
}
organismKillCount -= killedCount;
killedCount = 0;
// If we still need to kill more organisms, we take it off the large populations first
if (organismKillCount > 0)
{
int index = rand.Next(0, largePopulationSpecies.Count);
while (organismKillCount > 0 && largePopulationSpecies.Count > 0)
{
SortedList list = (SortedList) largePopulationSpecies[index];
OrganismState state = (OrganismState) list.GetByIndex(0);
list.RemoveAt(0);
if (killingAnimals)
{
Debug.Assert(state is AnimalState);
state.Kill(PopulationChangeReason.Sick);
}
else
{
removeOrganism(new KilledOrganism(state.ID, PopulationChangeReason.Sick));
}
organismKillCount--;
killedCount++;
if (list.Count <= diseaseBoundary)
{
largePopulationSpecies.RemoveAt(index);
}
else
{
index++;
}
if (index > largePopulationSpecies.Count - 1)
{
index = 0;
}
}
}
killedCount = 0;
// If we still need to kill more organisms, we take it off of anyone, one by one, randomly
if (organismKillCount > 0)
{
SortedList[] allSpecies = new SortedList[organismsToKill.Count];
allSpeciesCollection.CopyTo(allSpecies, 0);
while (organismKillCount > 0)
{
int index = rand.Next(0, allSpecies.Length);
SortedList list = allSpecies[index];
if (list.Count > 0)
{
OrganismState state = (OrganismState) list.GetByIndex(0);
list.RemoveAt(0);
if (killingAnimals)
{
Debug.Assert(state is AnimalState);
state.Kill(PopulationChangeReason.Sick);
}
else
{
removeOrganism(new KilledOrganism(state.ID, PopulationChangeReason.Sick));
}
organismKillCount--;
killedCount++;
}
}
}
}