diff --git a/VsProject/PropagationRemasteredBeta/Human.cs b/VsProject/PropagationRemasteredBeta/Human.cs index a5f2bb9..026f1ae 100644 --- a/VsProject/PropagationRemasteredBeta/Human.cs +++ b/VsProject/PropagationRemasteredBeta/Human.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace PropagationRemasteredBeta { - public class Human:ICloneable + public class Human : ICloneable { //State values public Color SAIN_COLOR = Color.Green; @@ -34,8 +34,9 @@ namespace PropagationRemasteredBeta { get { return _state; } //We set the counter of infection whenever we set it to infected - set { - _state = value; + set + { + _state = value; if (_state == INFECTED) { _InfectedTimeCounter = 1; } switch (_state) { @@ -73,7 +74,7 @@ namespace PropagationRemasteredBeta } //we dont have any constructor with only default values because the human needs his position in the field to process the infection - public void ChangeBaseColors(Color sainColor,Color infectedColor,Color immuneColor,Color deadColor) + public void ChangeBaseColors(Color sainColor, Color infectedColor, Color immuneColor, Color deadColor) { SAIN_COLOR = sainColor; IMMUNE_COLOR = immuneColor; @@ -81,91 +82,118 @@ namespace PropagationRemasteredBeta INFECTED_COLOR = infectedColor; } - public void Propagate(Human[,] previousTerrain, Human[,] nextTerrain, int infectiosity, int deathRate, int cureTime, Random rnd) + public Human Propagate(Terrain T) { Human target; Point location; - //target = previousTerrain[Position.X, Position.Y]; - LifeTimeCounter++; if (this.State == INFECTED) { InfectedTimeCounter++; - if (rnd.Next(0, 100) <= deathRate) + if (T.Rnd.Next(0, 100) <= T.DeathRate) { - this.State = DEAD; - nextTerrain[this.Position.X, this.Position.Y] = this; + State = DEAD; } - if (LifeTimeCounter >= cureTime) + if (LifeTimeCounter >= T.CureTime) { - this.State = IMMUNE; + State = IMMUNE; } else { //we need to check if we are not in a corner - if (Position.X > 0 && Position.Y > 0 && Position.X < (previousTerrain.GetLength(0) - 1) && Position.Y < (previousTerrain.GetLength(1) - 1)) + if (Position.X > 0 && Position.Y > 0 && Position.X < (T.TerrainSize.Width - 1) && Position.Y < (T.TerrainSize.Height - 1)) { //check top left location = new Point(Position.X - 1, Position.Y + 1); - target = previousTerrain[location.X, location.Y]; - CheckInfection(nextTerrain, target, infectiosity, deathRate, rnd); + target = T.Population[location.X, location.Y]; + if (target.State == Human.SAIN) + { + T.PeopleToCheck.Add(target); + } + + //check top location = new Point(Position.X, Position.Y + 1); - target = previousTerrain[location.X, location.Y]; - CheckInfection(nextTerrain, target, infectiosity, deathRate, rnd); + target = T.Population[location.X, location.Y]; + + if (target.State == Human.SAIN) + { + T.PeopleToCheck.Add(target); + } //check top left location = new Point(Position.X + 1, Position.Y + 1); - target = previousTerrain[location.X, location.Y]; - CheckInfection(nextTerrain, target, infectiosity, deathRate, rnd); + target = T.Population[location.X, location.Y]; + + if (target.State == Human.SAIN) + { + T.PeopleToCheck.Add(target); + } //check left location = new Point(Position.X - 1, Position.Y); - target = previousTerrain[location.X, location.Y]; - CheckInfection(nextTerrain, target, infectiosity, deathRate, rnd); + target = T.Population[location.X, location.Y]; + + if (target.State == Human.SAIN) + { + T.PeopleToCheck.Add(target); + } //check right location = new Point(Position.X + 1, Position.Y); - target = previousTerrain[location.X, location.Y]; - CheckInfection(nextTerrain, target, infectiosity, deathRate, rnd); + target = T.Population[location.X, location.Y]; + + if (target.State == Human.SAIN) + { + T.PeopleToCheck.Add(target); + } //check bottom left location = new Point(Position.X - 1, Position.Y - 1); - target = previousTerrain[location.X, location.Y]; - CheckInfection(nextTerrain, target, infectiosity, deathRate, rnd); + target = T.Population[location.X, location.Y]; + + if (target.State == Human.SAIN) + { + T.PeopleToCheck.Add(target); + } //check bottom location = new Point(Position.X, Position.Y - 1); - target = previousTerrain[location.X, location.Y]; - CheckInfection(nextTerrain, target, infectiosity, deathRate, rnd); + target = T.Population[location.X, location.Y]; + + if (target.State == Human.SAIN) + { + T.PeopleToCheck.Add(target); + } //check bottom right location = new Point(Position.X + 1, Position.Y - 1); - target = previousTerrain[location.X, location.Y]; - CheckInfection(nextTerrain, target, infectiosity, deathRate, rnd); + target = T.Population[location.X, location.Y]; + + if (target.State == Human.SAIN) + { + T.PeopleToCheck.Add(target); + } } } } + return this; } - private void CheckInfection(Human[,] nextTerrain, Human target, int infectiosity, int deathRate, Random rnd) + public Human CheckInfection(int infectiosity, Random rnd) { - if (target.State == SAIN) + if (rnd.Next(0, 100) <= infectiosity) { - if (rnd.Next(0, 100) <= infectiosity) - { - target.State = INFECTED; - } + State = INFECTED; } - - nextTerrain[target.Position.X, target.Position.Y] = target; + return this; } public object Clone() { - Human newHuman = new Human(Position,State); + Human newHuman = new Human(Position, State); newHuman.HumanSize = HumanSize; newHuman.InfectedTimeCounter = InfectedTimeCounter; newHuman.LifeTimeCounter = LifeTimeCounter; diff --git a/VsProject/PropagationRemasteredBeta/Terrain.cs b/VsProject/PropagationRemasteredBeta/Terrain.cs index 9837752..8d8c534 100644 --- a/VsProject/PropagationRemasteredBeta/Terrain.cs +++ b/VsProject/PropagationRemasteredBeta/Terrain.cs @@ -17,10 +17,10 @@ namespace PropagationRemasteredBeta const int DEFAULT_INFECTION_RATE = 20; const int DEFAULT_CURE_TIME = 25; - const int DEBUGGER_PLACEHOLDER = 86758; - private Human[,] _population; + private List _peopleToCheck; private Size _terrainSize; + private int _infectedProportion; private int _immuneProportion; private int _deathRate; @@ -28,9 +28,6 @@ namespace PropagationRemasteredBeta private int _cureTime; private Bitmap _render; - private Human[,] oldTerrain; - private Human[,] newTerrain; - private List _sainCount; private List _infectedCount; private List _immuneCount; @@ -56,6 +53,8 @@ namespace PropagationRemasteredBeta public List ImmuneCount { get => _immuneCount; set => _immuneCount = value; } public List DeadCount { get => _deadCount; set => _deadCount = value; } public int SimulationDuration { get => _simulationDuration; set => _simulationDuration = value; } + public List PeopleToCheck { get => _peopleToCheck; set => _peopleToCheck = value; } + public Random Rnd { get => rnd; set => rnd = value; } public Terrain(Size terrainSize, int infectedProportion, int resistantProportion, int deathRate, int infectionRate, int cureTime) { @@ -66,10 +65,7 @@ namespace PropagationRemasteredBeta DeathRate = deathRate; InfectionRate = infectionRate; CureTime = cureTime; - rnd = new Random(); - - oldTerrain = null; - newTerrain = null; + Rnd = new Random(); //all of this is for stats purposes @@ -96,13 +92,13 @@ namespace PropagationRemasteredBeta state = Human.SAIN; - if (rnd.Next(0, 100) < InfectedProportion) + if (Rnd.Next(0, 100) < InfectedProportion) { state = Human.INFECTED; } else { - if (rnd.Next(0, 100) < ImmuneProportion) + if (Rnd.Next(0, 100) < ImmuneProportion) { state = Human.IMMUNE; } @@ -123,7 +119,7 @@ namespace PropagationRemasteredBeta state = Human.SAIN; - if (rnd.Next(0, 100) < ImmuneProportion) + if (Rnd.Next(0, 100) < ImmuneProportion) { state = Human.IMMUNE; } @@ -133,8 +129,8 @@ namespace PropagationRemasteredBeta } } //we generate a single infected in a random location - int x = rnd.Next(0, TerrainSize.Width); - int y = rnd.Next(0, TerrainSize.Height); + int x = Rnd.Next(0, TerrainSize.Width); + int y = Rnd.Next(0, TerrainSize.Height); Population[x, y].State = Human.INFECTED; } @@ -146,22 +142,24 @@ namespace PropagationRemasteredBeta InfectedCount.Add(0); DeadCount.Add(0); - oldTerrain = Population; - newTerrain = oldTerrain; + PeopleToCheck = new List(); for (int width = 0; width < TerrainSize.Width; width += 1) { + //Parallel.For(0, TerrainSize.Height, height => for (int height = 0; height < TerrainSize.Height; height += 1) { //we also send the random so if one day we want to add a seed feature it will also affect the transmission - if (Population[width, height].State != Human.SAIN && Population[width, height].State != Human.DEAD && Population[width, height].State != Human.IMMUNE) + switch (Population[width, height].State) { - Population[width, height].Propagate(oldTerrain, newTerrain, InfectionRate, DeathRate, CureTime, rnd); - } - else - { - newTerrain[width, height] = Population[width, height]; + case Human.INFECTED: + Population[width, height] = Population[width, height].Propagate(this); + break; + default: + //nothing to do + break; } + //only for stats purposes switch (Population[width, height].State) { @@ -178,10 +176,14 @@ namespace PropagationRemasteredBeta DeadCount[SimulationDuration] += 1; break; } - } + }//); + } + + foreach (Human target in PeopleToCheck) + { + Population[target.Position.X,target.Position.Y] = target.CheckInfection(InfectionRate,Rnd); } - Population = newTerrain; } public Bitmap Display()