Added first version of the project (Proof Of Concept)
This commit is contained in:
@@ -0,0 +1,258 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace PropagationRemasteredBeta
|
||||
{
|
||||
public class Terrain
|
||||
{
|
||||
const int DEFAULT_SIZE = 1000;
|
||||
const int DEFAULT_INFECTED_PROPORTION = 10;
|
||||
const int DEFAULT_IMMUNE_PROPORTION = 10;
|
||||
const int DEFAULT_DEATH_RATE = 5;
|
||||
const int DEFAULT_INFECTION_RATE = 20;
|
||||
const int DEFAULT_CURE_TIME = 25;
|
||||
|
||||
const int DEBUGGER_PLACEHOLDER = 86758;
|
||||
|
||||
private Human[,] _population;
|
||||
private Size _terrainSize;
|
||||
private int _infectedProportion;
|
||||
private int _immuneProportion;
|
||||
private int _deathRate;
|
||||
private int _infectionRate;
|
||||
private int _cureTime;
|
||||
private Bitmap _render;
|
||||
|
||||
private Human[,] oldTerrain;
|
||||
private Human[,] newTerrain;
|
||||
|
||||
private List<int> _sainCount;
|
||||
private List<int> _infectedCount;
|
||||
private List<int> _immuneCount;
|
||||
private List<int> _deadCount;
|
||||
|
||||
private int _simulationDuration;
|
||||
|
||||
/*Used for debugging*/
|
||||
public int DRAWED_ELEMENTS;
|
||||
|
||||
private Random rnd;
|
||||
public Human[,] Population { get => _population; set => _population = value; }
|
||||
public Size TerrainSize { get => _terrainSize; private set => _terrainSize = value; }
|
||||
public int InfectedProportion { get => _infectedProportion; private set => _infectedProportion = value; }
|
||||
public int ImmuneProportion { get => _immuneProportion; private set => _immuneProportion = value; }
|
||||
public int DeathRate { get => _deathRate; private set => _deathRate = value; }
|
||||
public int InfectionRate { get => _infectionRate; private set => _infectionRate = value; }
|
||||
public int CureTime { get => _cureTime; set => _cureTime = value; }
|
||||
public Bitmap Render { get => _render; set => _render = value; }
|
||||
|
||||
public List<int> SainCount { get => _sainCount; set => _sainCount = value; }
|
||||
public List<int> InfectedCount { get => _infectedCount; set => _infectedCount = value; }
|
||||
public List<int> ImmuneCount { get => _immuneCount; set => _immuneCount = value; }
|
||||
public List<int> DeadCount { get => _deadCount; set => _deadCount = value; }
|
||||
public int SimulationDuration { get => _simulationDuration; set => _simulationDuration = value; }
|
||||
|
||||
public Terrain(Size terrainSize, int infectedProportion, int resistantProportion, int deathRate, int infectionRate, int cureTime)
|
||||
{
|
||||
Population = new Human[terrainSize.Width, terrainSize.Height];
|
||||
TerrainSize = terrainSize;
|
||||
InfectedProportion = infectedProportion;
|
||||
ImmuneProportion = resistantProportion;
|
||||
DeathRate = deathRate;
|
||||
InfectionRate = infectionRate;
|
||||
CureTime = cureTime;
|
||||
rnd = new Random();
|
||||
|
||||
oldTerrain = null;
|
||||
newTerrain = null;
|
||||
|
||||
//all of this is for stats purposes
|
||||
|
||||
SainCount = new List<int>();
|
||||
InfectedCount = new List<int>();
|
||||
ImmuneCount = new List<int>();
|
||||
DeadCount = new List<int>();
|
||||
|
||||
SimulationDuration = -1;
|
||||
|
||||
}
|
||||
public Terrain() : this(new Size(DEFAULT_SIZE, DEFAULT_SIZE), DEFAULT_INFECTED_PROPORTION, DEFAULT_IMMUNE_PROPORTION, DEFAULT_DEATH_RATE, DEFAULT_INFECTION_RATE, DEFAULT_CURE_TIME)
|
||||
{
|
||||
//empty
|
||||
}
|
||||
public void Generate()
|
||||
{
|
||||
//That is the basic method to scan trough the entire field
|
||||
for (int width = 0; width < TerrainSize.Width; width += 1)
|
||||
{
|
||||
for (int height = 0; height < TerrainSize.Height; height += 1)
|
||||
{
|
||||
int state;
|
||||
|
||||
state = Human.SAIN;
|
||||
|
||||
if (rnd.Next(0, 100) < InfectedProportion)
|
||||
{
|
||||
state = Human.INFECTED;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rnd.Next(0, 100) < ImmuneProportion)
|
||||
{
|
||||
state = Human.IMMUNE;
|
||||
}
|
||||
}
|
||||
|
||||
Population[width, height] = new Human(new Point(width, height), state);
|
||||
}
|
||||
}
|
||||
}
|
||||
public void GenerateOneForAll()
|
||||
{
|
||||
for (int width = 0; width < TerrainSize.Width; width += 1)
|
||||
{
|
||||
for (int height = 0; height < TerrainSize.Height; height += 1)
|
||||
{
|
||||
int state;
|
||||
|
||||
state = Human.SAIN;
|
||||
|
||||
|
||||
if (rnd.Next(0, 100) < ImmuneProportion)
|
||||
{
|
||||
state = Human.IMMUNE;
|
||||
}
|
||||
|
||||
|
||||
Population[width, height] = new Human(new Point(width, height), state);
|
||||
}
|
||||
}
|
||||
//we generate a single infected in a random location
|
||||
int x = rnd.Next(0, TerrainSize.Width);
|
||||
int y = rnd.Next(0, TerrainSize.Height);
|
||||
|
||||
Population[x, y].State = Human.INFECTED;
|
||||
}
|
||||
public void Refresh()
|
||||
{
|
||||
SimulationDuration++;
|
||||
SainCount.Add(0);
|
||||
ImmuneCount.Add(0);
|
||||
InfectedCount.Add(0);
|
||||
DeadCount.Add(0);
|
||||
|
||||
oldTerrain = Population;
|
||||
newTerrain = oldTerrain;
|
||||
|
||||
for (int width = 0; width < TerrainSize.Width; width += 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
|
||||
if (Population[width, height].State != Human.SAIN && Population[width, height].State != Human.DEAD && Population[width, height].State != Human.IMMUNE)
|
||||
{
|
||||
Population[width, height].Propagate(oldTerrain, newTerrain, InfectionRate, DeathRate, CureTime, rnd);
|
||||
}
|
||||
else
|
||||
{
|
||||
newTerrain[width, height] = Population[width, height];
|
||||
}
|
||||
//only for stats purposes
|
||||
switch (Population[width, height].State)
|
||||
{
|
||||
case Human.SAIN:
|
||||
SainCount[SimulationDuration] += 1;
|
||||
break;
|
||||
case Human.IMMUNE:
|
||||
ImmuneCount[SimulationDuration] += 1;
|
||||
break;
|
||||
case Human.INFECTED:
|
||||
InfectedCount[SimulationDuration] += 1;
|
||||
break;
|
||||
case Human.DEAD:
|
||||
DeadCount[SimulationDuration] += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Population = newTerrain;
|
||||
}
|
||||
|
||||
public Bitmap Display()
|
||||
{
|
||||
DRAWED_ELEMENTS = 0;
|
||||
Render = new Bitmap(TerrainSize.Width, TerrainSize.Height);
|
||||
using (Graphics gr = Graphics.FromImage(Render))
|
||||
{
|
||||
//this is an attempt to save time, we display the dominant color in the all bitmap and only change the others.
|
||||
int dominantState = Human.SAIN;
|
||||
//we check that it is not the first frame and by default we expect the first frame to be dominantly sain people
|
||||
if (InfectedCount.Count() > 0)
|
||||
{
|
||||
int infecteds = InfectedCount[InfectedCount.Count() - 1];
|
||||
int sain = SainCount[SainCount.Count() - 1];
|
||||
int immune = ImmuneCount[ImmuneCount.Count() - 1];
|
||||
int deaths = DeadCount[DeadCount.Count() - 1];
|
||||
|
||||
if (infecteds > sain && infecteds > immune && infecteds > deaths)
|
||||
{
|
||||
//the dominant color is the infected one
|
||||
dominantState = Human.INFECTED;
|
||||
}
|
||||
if (immune > sain && immune > infecteds && immune > deaths)
|
||||
{
|
||||
//the dominant color is the infected one
|
||||
dominantState = Human.IMMUNE;
|
||||
}
|
||||
if (deaths > sain && deaths > infecteds && deaths > immune)
|
||||
{
|
||||
//the dominant color is the infected one
|
||||
dominantState = Human.DEAD;
|
||||
}
|
||||
}
|
||||
//as Color object cannot be a constant we cannot use Human.SAIN_COLOR we need to use a fully constructed human
|
||||
Human sample = new Human(new Point(-1, -1), Human.DEAD);
|
||||
switch (dominantState)
|
||||
{
|
||||
case Human.SAIN:
|
||||
gr.FillRectangle(new SolidBrush(sample.SAIN_COLOR), new Rectangle(new Point(0, 0), new Size(Render.Width, Render.Height)));
|
||||
break;
|
||||
case Human.IMMUNE:
|
||||
gr.FillRectangle(new SolidBrush(sample.IMMUNE_COLOR), new Rectangle(new Point(0, 0), new Size(Render.Width, Render.Height)));
|
||||
break;
|
||||
case Human.INFECTED:
|
||||
gr.FillRectangle(new SolidBrush(sample.INFECTED_COLOR), new Rectangle(new Point(0, 0), new Size(Render.Width, Render.Height)));
|
||||
break;
|
||||
case Human.DEAD:
|
||||
gr.FillRectangle(new SolidBrush(sample.DEATH_COLOR), new Rectangle(new Point(0, 0), new Size(Render.Width, Render.Height)));
|
||||
break;
|
||||
default:
|
||||
gr.FillRectangle(new SolidBrush(sample.SAIN_COLOR), new Rectangle(new Point(0, 0), new Size(Render.Width, Render.Height)));
|
||||
break;
|
||||
}
|
||||
|
||||
for (int width = 0; width < TerrainSize.Width; width += 1)
|
||||
{
|
||||
for (int height = 0; height < TerrainSize.Height; height += 1)
|
||||
{
|
||||
Human individual = Population[width, height];
|
||||
if (individual.State != dominantState)
|
||||
{
|
||||
Color c = individual.Sprite;
|
||||
gr.FillRectangle(new SolidBrush(c), new Rectangle(individual.Position, individual.HumanSize));
|
||||
DRAWED_ELEMENTS++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return Render;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user