Changed a bit the core mechanics with a slight improvement in performance

This commit is contained in:
M.Rohmer
2022-03-05 17:14:35 +01:00
parent 3a561f2d0a
commit 8316c5204a
2 changed files with 92 additions and 62 deletions
+64 -36
View File
@@ -34,7 +34,8 @@ namespace PropagationRemasteredBeta
{ {
get { return _state; } get { return _state; }
//We set the counter of infection whenever we set it to infected //We set the counter of infection whenever we set it to infected
set { set
{
_state = value; _state = value;
if (_state == INFECTED) { _InfectedTimeCounter = 1; } if (_state == INFECTED) { _InfectedTimeCounter = 1; }
switch (_state) switch (_state)
@@ -81,86 +82,113 @@ namespace PropagationRemasteredBeta
INFECTED_COLOR = infectedColor; 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; Human target;
Point location; Point location;
//target = previousTerrain[Position.X, Position.Y];
LifeTimeCounter++; LifeTimeCounter++;
if (this.State == INFECTED) if (this.State == INFECTED)
{ {
InfectedTimeCounter++; InfectedTimeCounter++;
if (rnd.Next(0, 100) <= deathRate) if (T.Rnd.Next(0, 100) <= T.DeathRate)
{ {
this.State = DEAD; State = DEAD;
nextTerrain[this.Position.X, this.Position.Y] = this;
} }
if (LifeTimeCounter >= cureTime) if (LifeTimeCounter >= T.CureTime)
{ {
this.State = IMMUNE; State = IMMUNE;
} }
else else
{ {
//we need to check if we are not in a corner //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 //check top left
location = new Point(Position.X - 1, Position.Y + 1); location = new Point(Position.X - 1, Position.Y + 1);
target = previousTerrain[location.X, location.Y]; target = T.Population[location.X, location.Y];
CheckInfection(nextTerrain, target, infectiosity, deathRate, rnd); if (target.State == Human.SAIN)
{
T.PeopleToCheck.Add(target);
}
//check top //check top
location = new Point(Position.X, Position.Y + 1); location = new Point(Position.X, Position.Y + 1);
target = previousTerrain[location.X, location.Y]; target = T.Population[location.X, location.Y];
CheckInfection(nextTerrain, target, infectiosity, deathRate, rnd);
if (target.State == Human.SAIN)
{
T.PeopleToCheck.Add(target);
}
//check top left //check top left
location = new Point(Position.X + 1, Position.Y + 1); location = new Point(Position.X + 1, Position.Y + 1);
target = previousTerrain[location.X, location.Y]; target = T.Population[location.X, location.Y];
CheckInfection(nextTerrain, target, infectiosity, deathRate, rnd);
if (target.State == Human.SAIN)
{
T.PeopleToCheck.Add(target);
}
//check left //check left
location = new Point(Position.X - 1, Position.Y); location = new Point(Position.X - 1, Position.Y);
target = previousTerrain[location.X, location.Y]; target = T.Population[location.X, location.Y];
CheckInfection(nextTerrain, target, infectiosity, deathRate, rnd);
if (target.State == Human.SAIN)
{
T.PeopleToCheck.Add(target);
}
//check right //check right
location = new Point(Position.X + 1, Position.Y); location = new Point(Position.X + 1, Position.Y);
target = previousTerrain[location.X, location.Y]; target = T.Population[location.X, location.Y];
CheckInfection(nextTerrain, target, infectiosity, deathRate, rnd);
if (target.State == Human.SAIN)
{
T.PeopleToCheck.Add(target);
}
//check bottom left //check bottom left
location = new Point(Position.X - 1, Position.Y - 1); location = new Point(Position.X - 1, Position.Y - 1);
target = previousTerrain[location.X, location.Y]; target = T.Population[location.X, location.Y];
CheckInfection(nextTerrain, target, infectiosity, deathRate, rnd);
if (target.State == Human.SAIN)
{
T.PeopleToCheck.Add(target);
}
//check bottom //check bottom
location = new Point(Position.X, Position.Y - 1); location = new Point(Position.X, Position.Y - 1);
target = previousTerrain[location.X, location.Y]; target = T.Population[location.X, location.Y];
CheckInfection(nextTerrain, target, infectiosity, deathRate, rnd);
if (target.State == Human.SAIN)
{
T.PeopleToCheck.Add(target);
}
//check bottom right //check bottom right
location = new Point(Position.X + 1, Position.Y - 1); location = new Point(Position.X + 1, Position.Y - 1);
target = previousTerrain[location.X, location.Y]; target = T.Population[location.X, location.Y];
CheckInfection(nextTerrain, target, infectiosity, deathRate, rnd);
} if (target.State == Human.SAIN)
}
}
}
private void CheckInfection(Human[,] nextTerrain, Human target, int infectiosity, int deathRate, Random rnd)
{ {
if (target.State == SAIN) T.PeopleToCheck.Add(target);
}
}
}
}
return this;
}
public Human CheckInfection(int infectiosity, Random rnd)
{ {
if (rnd.Next(0, 100) <= infectiosity) if (rnd.Next(0, 100) <= infectiosity)
{ {
target.State = INFECTED; State = INFECTED;
} }
} return this;
nextTerrain[target.Position.X, target.Position.Y] = target;
} }
public object Clone() public object Clone()
+26 -24
View File
@@ -17,10 +17,10 @@ namespace PropagationRemasteredBeta
const int DEFAULT_INFECTION_RATE = 20; const int DEFAULT_INFECTION_RATE = 20;
const int DEFAULT_CURE_TIME = 25; const int DEFAULT_CURE_TIME = 25;
const int DEBUGGER_PLACEHOLDER = 86758;
private Human[,] _population; private Human[,] _population;
private List<Human> _peopleToCheck;
private Size _terrainSize; private Size _terrainSize;
private int _infectedProportion; private int _infectedProportion;
private int _immuneProportion; private int _immuneProportion;
private int _deathRate; private int _deathRate;
@@ -28,9 +28,6 @@ namespace PropagationRemasteredBeta
private int _cureTime; private int _cureTime;
private Bitmap _render; private Bitmap _render;
private Human[,] oldTerrain;
private Human[,] newTerrain;
private List<int> _sainCount; private List<int> _sainCount;
private List<int> _infectedCount; private List<int> _infectedCount;
private List<int> _immuneCount; private List<int> _immuneCount;
@@ -56,6 +53,8 @@ namespace PropagationRemasteredBeta
public List<int> ImmuneCount { get => _immuneCount; set => _immuneCount = value; } public List<int> ImmuneCount { get => _immuneCount; set => _immuneCount = value; }
public List<int> DeadCount { get => _deadCount; set => _deadCount = value; } public List<int> DeadCount { get => _deadCount; set => _deadCount = value; }
public int SimulationDuration { get => _simulationDuration; set => _simulationDuration = value; } public int SimulationDuration { get => _simulationDuration; set => _simulationDuration = value; }
public List<Human> 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) public Terrain(Size terrainSize, int infectedProportion, int resistantProportion, int deathRate, int infectionRate, int cureTime)
{ {
@@ -66,10 +65,7 @@ namespace PropagationRemasteredBeta
DeathRate = deathRate; DeathRate = deathRate;
InfectionRate = infectionRate; InfectionRate = infectionRate;
CureTime = cureTime; CureTime = cureTime;
rnd = new Random(); Rnd = new Random();
oldTerrain = null;
newTerrain = null;
//all of this is for stats purposes //all of this is for stats purposes
@@ -96,13 +92,13 @@ namespace PropagationRemasteredBeta
state = Human.SAIN; state = Human.SAIN;
if (rnd.Next(0, 100) < InfectedProportion) if (Rnd.Next(0, 100) < InfectedProportion)
{ {
state = Human.INFECTED; state = Human.INFECTED;
} }
else else
{ {
if (rnd.Next(0, 100) < ImmuneProportion) if (Rnd.Next(0, 100) < ImmuneProportion)
{ {
state = Human.IMMUNE; state = Human.IMMUNE;
} }
@@ -123,7 +119,7 @@ namespace PropagationRemasteredBeta
state = Human.SAIN; state = Human.SAIN;
if (rnd.Next(0, 100) < ImmuneProportion) if (Rnd.Next(0, 100) < ImmuneProportion)
{ {
state = Human.IMMUNE; state = Human.IMMUNE;
} }
@@ -133,8 +129,8 @@ namespace PropagationRemasteredBeta
} }
} }
//we generate a single infected in a random location //we generate a single infected in a random location
int x = rnd.Next(0, TerrainSize.Width); int x = Rnd.Next(0, TerrainSize.Width);
int y = rnd.Next(0, TerrainSize.Height); int y = Rnd.Next(0, TerrainSize.Height);
Population[x, y].State = Human.INFECTED; Population[x, y].State = Human.INFECTED;
} }
@@ -146,22 +142,24 @@ namespace PropagationRemasteredBeta
InfectedCount.Add(0); InfectedCount.Add(0);
DeadCount.Add(0); DeadCount.Add(0);
oldTerrain = Population; PeopleToCheck = new List<Human>();
newTerrain = oldTerrain;
for (int width = 0; width < TerrainSize.Width; width += 1) for (int width = 0; width < TerrainSize.Width; width += 1)
{ {
//Parallel.For(0, TerrainSize.Height, height =>
for (int height = 0; height < TerrainSize.Height; height += 1) 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 //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); case Human.INFECTED:
} Population[width, height] = Population[width, height].Propagate(this);
else break;
{ default:
newTerrain[width, height] = Population[width, height]; //nothing to do
break;
} }
//only for stats purposes //only for stats purposes
switch (Population[width, height].State) switch (Population[width, height].State)
{ {
@@ -178,10 +176,14 @@ namespace PropagationRemasteredBeta
DeadCount[SimulationDuration] += 1; DeadCount[SimulationDuration] += 1;
break; break;
} }
} }//);
}
foreach (Human target in PeopleToCheck)
{
Population[target.Position.X,target.Position.Y] = target.CheckInfection(InfectionRate,Rnd);
} }
Population = newTerrain;
} }
public Bitmap Display() public Bitmap Display()