diff --git a/VsProject/PropagationRemasteredBeta.sln b/VsProject/PropagationRemasteredBeta.sln new file mode 100644 index 0000000..e9915d1 --- /dev/null +++ b/VsProject/PropagationRemasteredBeta.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30621.155 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PropagationRemasteredBeta", "PropagationRemasteredBeta\PropagationRemasteredBeta.csproj", "{27825863-02A0-4112-BE3D-47E5B83177A5}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {27825863-02A0-4112-BE3D-47E5B83177A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {27825863-02A0-4112-BE3D-47E5B83177A5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {27825863-02A0-4112-BE3D-47E5B83177A5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {27825863-02A0-4112-BE3D-47E5B83177A5}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {ED9F4304-C8D9-42AE-8F7B-A01555E7146F} + EndGlobalSection +EndGlobal diff --git a/VsProject/PropagationRemasteredBeta/App.config b/VsProject/PropagationRemasteredBeta/App.config new file mode 100644 index 0000000..56efbc7 --- /dev/null +++ b/VsProject/PropagationRemasteredBeta/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/VsProject/PropagationRemasteredBeta/Form1.Designer.cs b/VsProject/PropagationRemasteredBeta/Form1.Designer.cs new file mode 100644 index 0000000..b829653 --- /dev/null +++ b/VsProject/PropagationRemasteredBeta/Form1.Designer.cs @@ -0,0 +1,289 @@ +namespace PropagationRemasteredBeta +{ + partial class Form1 + { + /// + /// Variable nécessaire au concepteur. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Nettoyage des ressources utilisées. + /// + /// true si les ressources managées doivent être supprimées ; sinon, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Code généré par le Concepteur Windows Form + + /// + /// Méthode requise pour la prise en charge du concepteur - ne modifiez pas + /// le contenu de cette méthode avec l'éditeur de code. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.btnStartNormal = new System.Windows.Forms.Button(); + this.pbxTerrain = new System.Windows.Forms.PictureBox(); + this.tmrTick = new System.Windows.Forms.Timer(this.components); + this.label1 = new System.Windows.Forms.Label(); + this.lblMemory = new System.Windows.Forms.Label(); + this.lblelementsCounter = new System.Windows.Forms.Label(); + this.label3 = new System.Windows.Forms.Label(); + this.lblFrameCount = new System.Windows.Forms.Label(); + this.label4 = new System.Windows.Forms.Label(); + this.lblTotalTime = new System.Windows.Forms.Label(); + this.label5 = new System.Windows.Forms.Label(); + this.lblDeaths = new System.Windows.Forms.Label(); + this.lbl6 = new System.Windows.Forms.Label(); + this.lblSain = new System.Windows.Forms.Label(); + this.lbl5 = new System.Windows.Forms.Label(); + this.lblImmunes = new System.Windows.Forms.Label(); + this.lbl4 = new System.Windows.Forms.Label(); + this.lblInfected = new System.Windows.Forms.Label(); + this.label12 = new System.Windows.Forms.Label(); + this.btnStartOneForAll = new System.Windows.Forms.Button(); + ((System.ComponentModel.ISupportInitialize)(this.pbxTerrain)).BeginInit(); + this.SuspendLayout(); + // + // btnStartNormal + // + this.btnStartNormal.Location = new System.Drawing.Point(818, 294); + this.btnStartNormal.Name = "btnStartNormal"; + this.btnStartNormal.Size = new System.Drawing.Size(105, 51); + this.btnStartNormal.TabIndex = 0; + this.btnStartNormal.Text = "Start classic"; + this.btnStartNormal.UseVisualStyleBackColor = true; + this.btnStartNormal.Click += new System.EventHandler(this.button1_Click); + // + // pbxTerrain + // + this.pbxTerrain.Location = new System.Drawing.Point(12, 12); + this.pbxTerrain.Name = "pbxTerrain"; + this.pbxTerrain.Size = new System.Drawing.Size(800, 800); + this.pbxTerrain.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; + this.pbxTerrain.TabIndex = 1; + this.pbxTerrain.TabStop = false; + // + // tmrTick + // + this.tmrTick.Tick += new System.EventHandler(this.tmrTick_Tick); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(818, 12); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(78, 13); + this.label1.TabIndex = 2; + this.label1.Text = "Memory Usage"; + // + // lblMemory + // + this.lblMemory.AutoSize = true; + this.lblMemory.Location = new System.Drawing.Point(818, 25); + this.lblMemory.Name = "lblMemory"; + this.lblMemory.Size = new System.Drawing.Size(29, 13); + this.lblMemory.TabIndex = 3; + this.lblMemory.Text = "NaN"; + // + // lblelementsCounter + // + this.lblelementsCounter.AutoSize = true; + this.lblelementsCounter.Location = new System.Drawing.Point(818, 61); + this.lblelementsCounter.Name = "lblelementsCounter"; + this.lblelementsCounter.Size = new System.Drawing.Size(29, 13); + this.lblelementsCounter.TabIndex = 5; + this.lblelementsCounter.Text = "NaN"; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(818, 48); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(84, 13); + this.label3.TabIndex = 4; + this.label3.Text = "Drawed Elemets"; + // + // lblFrameCount + // + this.lblFrameCount.AutoSize = true; + this.lblFrameCount.Location = new System.Drawing.Point(818, 101); + this.lblFrameCount.Name = "lblFrameCount"; + this.lblFrameCount.Size = new System.Drawing.Size(29, 13); + this.lblFrameCount.TabIndex = 7; + this.lblFrameCount.Text = "NaN"; + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(818, 88); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(41, 13); + this.label4.TabIndex = 6; + this.label4.Text = "Frames"; + // + // lblTotalTime + // + this.lblTotalTime.AutoSize = true; + this.lblTotalTime.Location = new System.Drawing.Point(818, 136); + this.lblTotalTime.Name = "lblTotalTime"; + this.lblTotalTime.Size = new System.Drawing.Size(29, 13); + this.lblTotalTime.TabIndex = 9; + this.lblTotalTime.Text = "NaN"; + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Location = new System.Drawing.Point(818, 123); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(85, 13); + this.label5.TabIndex = 8; + this.label5.Text = "Total Time (ms) :"; + // + // lblDeaths + // + this.lblDeaths.AutoSize = true; + this.lblDeaths.Location = new System.Drawing.Point(818, 278); + this.lblDeaths.Name = "lblDeaths"; + this.lblDeaths.Size = new System.Drawing.Size(29, 13); + this.lblDeaths.TabIndex = 11; + this.lblDeaths.Text = "NaN"; + // + // lbl6 + // + this.lbl6.AutoSize = true; + this.lbl6.Location = new System.Drawing.Point(818, 265); + this.lbl6.Name = "lbl6"; + this.lbl6.Size = new System.Drawing.Size(44, 13); + this.lbl6.TabIndex = 10; + this.lbl6.Text = "Deads :"; + // + // lblSain + // + this.lblSain.AutoSize = true; + this.lblSain.Location = new System.Drawing.Point(818, 242); + this.lblSain.Name = "lblSain"; + this.lblSain.Size = new System.Drawing.Size(29, 13); + this.lblSain.TabIndex = 13; + this.lblSain.Text = "NaN"; + // + // lbl5 + // + this.lbl5.AutoSize = true; + this.lbl5.Location = new System.Drawing.Point(818, 229); + this.lbl5.Name = "lbl5"; + this.lbl5.Size = new System.Drawing.Size(39, 13); + this.lbl5.TabIndex = 12; + this.lbl5.Text = "Sains :"; + // + // lblImmunes + // + this.lblImmunes.AutoSize = true; + this.lblImmunes.Location = new System.Drawing.Point(818, 207); + this.lblImmunes.Name = "lblImmunes"; + this.lblImmunes.Size = new System.Drawing.Size(29, 13); + this.lblImmunes.TabIndex = 15; + this.lblImmunes.Text = "NaN"; + // + // lbl4 + // + this.lbl4.AutoSize = true; + this.lbl4.Location = new System.Drawing.Point(818, 194); + this.lbl4.Name = "lbl4"; + this.lbl4.Size = new System.Drawing.Size(55, 13); + this.lbl4.TabIndex = 14; + this.lbl4.Text = "Immunes :"; + // + // lblInfected + // + this.lblInfected.AutoSize = true; + this.lblInfected.Location = new System.Drawing.Point(818, 172); + this.lblInfected.Name = "lblInfected"; + this.lblInfected.Size = new System.Drawing.Size(29, 13); + this.lblInfected.TabIndex = 17; + this.lblInfected.Text = "NaN"; + // + // label12 + // + this.label12.AutoSize = true; + this.label12.Location = new System.Drawing.Point(818, 159); + this.label12.Name = "label12"; + this.label12.Size = new System.Drawing.Size(57, 13); + this.label12.TabIndex = 16; + this.label12.Text = "Infecteds :"; + // + // btnStartOneForAll + // + this.btnStartOneForAll.Location = new System.Drawing.Point(818, 351); + this.btnStartOneForAll.Name = "btnStartOneForAll"; + this.btnStartOneForAll.Size = new System.Drawing.Size(105, 51); + this.btnStartOneForAll.TabIndex = 18; + this.btnStartOneForAll.Text = "Start oneForAll"; + this.btnStartOneForAll.UseVisualStyleBackColor = true; + this.btnStartOneForAll.Click += new System.EventHandler(this.btnStartOneForAll_Click); + // + // Form1 + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(929, 814); + this.Controls.Add(this.btnStartOneForAll); + this.Controls.Add(this.lblInfected); + this.Controls.Add(this.label12); + this.Controls.Add(this.lblImmunes); + this.Controls.Add(this.lbl4); + this.Controls.Add(this.lblSain); + this.Controls.Add(this.lbl5); + this.Controls.Add(this.lblDeaths); + this.Controls.Add(this.lbl6); + this.Controls.Add(this.lblTotalTime); + this.Controls.Add(this.label5); + this.Controls.Add(this.lblFrameCount); + this.Controls.Add(this.label4); + this.Controls.Add(this.lblelementsCounter); + this.Controls.Add(this.label3); + this.Controls.Add(this.lblMemory); + this.Controls.Add(this.label1); + this.Controls.Add(this.pbxTerrain); + this.Controls.Add(this.btnStartNormal); + this.Name = "Form1"; + this.Text = "Form1"; + this.Paint += new System.Windows.Forms.PaintEventHandler(this.Form1_Paint); + ((System.ComponentModel.ISupportInitialize)(this.pbxTerrain)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button btnStartNormal; + private System.Windows.Forms.PictureBox pbxTerrain; + private System.Windows.Forms.Timer tmrTick; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label lblMemory; + private System.Windows.Forms.Label lblelementsCounter; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Label lblFrameCount; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.Label lblTotalTime; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.Label lblDeaths; + private System.Windows.Forms.Label lbl6; + private System.Windows.Forms.Label lblSain; + private System.Windows.Forms.Label lbl5; + private System.Windows.Forms.Label lblImmunes; + private System.Windows.Forms.Label lbl4; + private System.Windows.Forms.Label lblInfected; + private System.Windows.Forms.Label label12; + private System.Windows.Forms.Button btnStartOneForAll; + } +} + diff --git a/VsProject/PropagationRemasteredBeta/Form1.cs b/VsProject/PropagationRemasteredBeta/Form1.cs new file mode 100644 index 0000000..2c3da83 --- /dev/null +++ b/VsProject/PropagationRemasteredBeta/Form1.cs @@ -0,0 +1,134 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Diagnostics; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace PropagationRemasteredBeta +{ + public partial class Form1 : Form + { + Terrain t; + Bitmap BufferImage; + int frameCount; + bool started = false; + Stopwatch stopwatch; + double totalTime; + public Form1() + { + InitializeComponent(); + t = new Terrain(); + frameCount = 0; + BufferImage = new Bitmap(t.TerrainSize.Width, t.TerrainSize.Height); + stopwatch = new Stopwatch(); + totalTime = 0; + } + + private void button1_Click(object sender, EventArgs e) + { + btnStartOneForAll.Enabled = false; + StartStop(1); + } + + private void StartStop(int mode) + { + if (started) + { + started = false; + btnStartNormal.Text = "Start classic"; + btnStartOneForAll.Text = "Start one for all"; + btnStartOneForAll.Enabled = true; + btnStartNormal.Enabled = true; + tmrTick.Stop(); + } + else + { + started = true; + btnStartNormal.Text = "Stop"; + btnStartOneForAll.Text = "Stop"; + tmrTick.Start(); + t = new Terrain(); + frameCount = 0; + + switch (mode) + { + case 1: + t.Generate(); + break; + case 2: + t.GenerateOneForAll(); + break; + } + + } + } + + private void Form1_Paint(object sender, PaintEventArgs e) + { + if (started) + { + BufferImage = t.Display(); + pbxTerrain.Image = BufferImage; + stopwatch.Stop(); + totalTime = stopwatch.ElapsedMilliseconds; + frameCount++; + lblFrameCount.Text = frameCount.ToString(); + lblTotalTime.Text = totalTime.ToString(); + } + } + + private void tmrTick_Tick(object sender, EventArgs e) + { + //t.Refresh(); + stopwatch.Start(); + int infecteds; + if (t.InfectedCount.Count > 0) + { + infecteds = t.InfectedCount[t.InfectedCount.Count() - 1]; + } + else + { + infecteds = 1; + } + if (infecteds > 0) + { + t.Refresh(); + } + else + { + StartStop(1); + } + this.Invalidate(); + //refresh all the stats + lblMemory.Text = GetMemoryUsage().ToString() + " Mb"; + lblelementsCounter.Text = t.DRAWED_ELEMENTS.ToString(); + lblInfected.Text = t.InfectedCount[t.InfectedCount.Count() - 1].ToString(); + lblImmunes.Text = t.ImmuneCount[t.ImmuneCount.Count() - 1].ToString(); + lblSain.Text = t.SainCount[t.SainCount.Count() - 1].ToString(); + lblDeaths.Text = t.DeadCount[t.DeadCount.Count() - 1].ToString(); + } + + private double GetMemoryUsage() + { + var memory = 0.0; + using (Process proc = Process.GetCurrentProcess()) + { + // The proc.PrivateMemorySize64 will returns the private memory usage in byte. + // Would like to Convert it to Megabyte? divide it by 2^20 + memory = proc.PrivateMemorySize64 / (1024 * 1024); + } + return memory; + } + + private void btnStartOneForAll_Click(object sender, EventArgs e) + { + btnStartNormal.Enabled = false; + StartStop(2); + } + } +} diff --git a/VsProject/PropagationRemasteredBeta/Form1.resx b/VsProject/PropagationRemasteredBeta/Form1.resx new file mode 100644 index 0000000..2bc86b0 --- /dev/null +++ b/VsProject/PropagationRemasteredBeta/Form1.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + \ No newline at end of file diff --git a/VsProject/PropagationRemasteredBeta/Human.cs b/VsProject/PropagationRemasteredBeta/Human.cs new file mode 100644 index 0000000..a5f2bb9 --- /dev/null +++ b/VsProject/PropagationRemasteredBeta/Human.cs @@ -0,0 +1,175 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PropagationRemasteredBeta +{ + public class Human:ICloneable + { + //State values + public Color SAIN_COLOR = Color.Green; + public Color INFECTED_COLOR = Color.Red; + public Color IMMUNE_COLOR = Color.Blue; + public Color DEATH_COLOR = Color.Black; + + public const int SAIN = 0; + public const int INFECTED = 1; + public const int IMMUNE = 2; + public const int DEAD = 3; + + const int DEFAULT_HUMAN_SIZE = 1; + + private Point _position; + private int _state; + private Size _humanSize; + private int _lifeTimeCounter; + private int _InfectedTimeCounter; + private Color _sprite; + + public Point Position { get => _position; set => _position = value; } + public int State + { + get { return _state; } + //We set the counter of infection whenever we set it to infected + set { + _state = value; + if (_state == INFECTED) { _InfectedTimeCounter = 1; } + switch (_state) + { + case INFECTED: + Sprite = INFECTED_COLOR; + break; + case SAIN: + Sprite = SAIN_COLOR; + break; + case DEAD: + Sprite = DEATH_COLOR; + break; + case IMMUNE: + Sprite = IMMUNE_COLOR; + break; + } + } + } + public Size HumanSize { get => _humanSize; set => _humanSize = value; } + public int LifeTimeCounter { get => _lifeTimeCounter; set => _lifeTimeCounter = value; } + public int InfectedTimeCounter { get => _InfectedTimeCounter; set => _InfectedTimeCounter = value; } + public Color Sprite { get => _sprite; set => _sprite = value; } + + public Human(Point position, int state, Size humanSize) + { + HumanSize = humanSize; + Position = position; + State = state; + LifeTimeCounter = 1; + InfectedTimeCounter = 0; + } + public Human(Point position, int state) : this(position, state, new Size(DEFAULT_HUMAN_SIZE, DEFAULT_HUMAN_SIZE)) + { + + } + //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) + { + SAIN_COLOR = sainColor; + IMMUNE_COLOR = immuneColor; + DEATH_COLOR = deadColor; + INFECTED_COLOR = infectedColor; + } + + public void Propagate(Human[,] previousTerrain, Human[,] nextTerrain, int infectiosity, int deathRate, int cureTime, Random rnd) + { + Human target; + Point location; + + //target = previousTerrain[Position.X, Position.Y]; + + LifeTimeCounter++; + + if (this.State == INFECTED) + { + InfectedTimeCounter++; + if (rnd.Next(0, 100) <= deathRate) + { + this.State = DEAD; + nextTerrain[this.Position.X, this.Position.Y] = this; + } + if (LifeTimeCounter >= cureTime) + { + this.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)) + { + //check top left + location = new Point(Position.X - 1, Position.Y + 1); + target = previousTerrain[location.X, location.Y]; + CheckInfection(nextTerrain, target, infectiosity, deathRate, rnd); + + //check top + location = new Point(Position.X, Position.Y + 1); + target = previousTerrain[location.X, location.Y]; + CheckInfection(nextTerrain, target, infectiosity, deathRate, rnd); + + //check top left + location = new Point(Position.X + 1, Position.Y + 1); + target = previousTerrain[location.X, location.Y]; + CheckInfection(nextTerrain, target, infectiosity, deathRate, rnd); + + //check left + location = new Point(Position.X - 1, Position.Y); + target = previousTerrain[location.X, location.Y]; + CheckInfection(nextTerrain, target, infectiosity, deathRate, rnd); + + //check right + location = new Point(Position.X + 1, Position.Y); + target = previousTerrain[location.X, location.Y]; + CheckInfection(nextTerrain, target, infectiosity, deathRate, rnd); + + //check bottom left + location = new Point(Position.X - 1, Position.Y - 1); + target = previousTerrain[location.X, location.Y]; + CheckInfection(nextTerrain, target, infectiosity, deathRate, rnd); + + //check bottom + location = new Point(Position.X, Position.Y - 1); + target = previousTerrain[location.X, location.Y]; + CheckInfection(nextTerrain, target, infectiosity, deathRate, rnd); + + //check bottom right + location = new Point(Position.X + 1, Position.Y - 1); + target = previousTerrain[location.X, location.Y]; + CheckInfection(nextTerrain, target, infectiosity, deathRate, rnd); + } + } + } + } + private void CheckInfection(Human[,] nextTerrain, Human target, int infectiosity, int deathRate, Random rnd) + { + if (target.State == SAIN) + { + if (rnd.Next(0, 100) <= infectiosity) + { + target.State = INFECTED; + } + } + + nextTerrain[target.Position.X, target.Position.Y] = target; + } + + public object Clone() + { + Human newHuman = new Human(Position,State); + newHuman.HumanSize = HumanSize; + newHuman.InfectedTimeCounter = InfectedTimeCounter; + newHuman.LifeTimeCounter = LifeTimeCounter; + return newHuman; + } + } +} diff --git a/VsProject/PropagationRemasteredBeta/Program.cs b/VsProject/PropagationRemasteredBeta/Program.cs new file mode 100644 index 0000000..cfd89d2 --- /dev/null +++ b/VsProject/PropagationRemasteredBeta/Program.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace PropagationRemasteredBeta +{ + static class Program + { + /// + /// Point d'entrée principal de l'application. + /// + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new Form1()); + } + } +} diff --git a/VsProject/PropagationRemasteredBeta/PropagationRemasteredBeta.csproj b/VsProject/PropagationRemasteredBeta/PropagationRemasteredBeta.csproj new file mode 100644 index 0000000..3ad4d8a --- /dev/null +++ b/VsProject/PropagationRemasteredBeta/PropagationRemasteredBeta.csproj @@ -0,0 +1,85 @@ + + + + + Debug + AnyCPU + {27825863-02A0-4112-BE3D-47E5B83177A5} + WinExe + PropagationRemasteredBeta + PropagationRemasteredBeta + v4.7.2 + 512 + true + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + Form + + + Form1.cs + + + + + + + Form1.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + \ No newline at end of file diff --git a/VsProject/PropagationRemasteredBeta/Properties/AssemblyInfo.cs b/VsProject/PropagationRemasteredBeta/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..c8d3325 --- /dev/null +++ b/VsProject/PropagationRemasteredBeta/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// Les informations générales relatives à un assembly dépendent de +// l'ensemble d'attributs suivant. Changez les valeurs de ces attributs pour modifier les informations +// associées à un assembly. +[assembly: AssemblyTitle("PropagationRemasteredBeta")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("PropagationRemasteredBeta")] +[assembly: AssemblyCopyright("Copyright © 2022")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// L'affectation de la valeur false à ComVisible rend les types invisibles dans cet assembly +// aux composants COM. Si vous devez accéder à un type dans cet assembly à partir de +// COM, affectez la valeur true à l'attribut ComVisible sur ce type. +[assembly: ComVisible(false)] + +// Le GUID suivant est pour l'ID de la typelib si ce projet est exposé à COM +[assembly: Guid("27825863-02a0-4112-be3d-47e5b83177a5")] + +// Les informations de version pour un assembly se composent des quatre valeurs suivantes : +// +// Version principale +// Version secondaire +// Numéro de build +// Révision +// +// Vous pouvez spécifier toutes les valeurs ou indiquer les numéros de build et de révision par défaut +// en utilisant '*', comme indiqué ci-dessous : +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/VsProject/PropagationRemasteredBeta/Properties/Resources.Designer.cs b/VsProject/PropagationRemasteredBeta/Properties/Resources.Designer.cs new file mode 100644 index 0000000..33596cf --- /dev/null +++ b/VsProject/PropagationRemasteredBeta/Properties/Resources.Designer.cs @@ -0,0 +1,71 @@ +//------------------------------------------------------------------------------ +// +// Ce code a été généré par un outil. +// Version du runtime :4.0.30319.42000 +// +// Les modifications apportées à ce fichier peuvent provoquer un comportement incorrect et seront perdues si +// le code est régénéré. +// +//------------------------------------------------------------------------------ + +namespace PropagationRemasteredBeta.Properties +{ + + + /// + /// Une classe de ressource fortement typée destinée, entre autres, à la consultation des chaînes localisées. + /// + // Cette classe a été générée automatiquement par la classe StronglyTypedResourceBuilder + // à l'aide d'un outil, tel que ResGen ou Visual Studio. + // Pour ajouter ou supprimer un membre, modifiez votre fichier .ResX, puis réexécutez ResGen + // avec l'option /str ou régénérez votre projet VS. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources + { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() + { + } + + /// + /// Retourne l'instance ResourceManager mise en cache utilisée par cette classe. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager + { + get + { + if ((resourceMan == null)) + { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PropagationRemasteredBeta.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Remplace la propriété CurrentUICulture du thread actuel pour toutes + /// les recherches de ressources à l'aide de cette classe de ressource fortement typée. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture + { + get + { + return resourceCulture; + } + set + { + resourceCulture = value; + } + } + } +} diff --git a/VsProject/PropagationRemasteredBeta/Properties/Resources.resx b/VsProject/PropagationRemasteredBeta/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/VsProject/PropagationRemasteredBeta/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/VsProject/PropagationRemasteredBeta/Properties/Settings.Designer.cs b/VsProject/PropagationRemasteredBeta/Properties/Settings.Designer.cs new file mode 100644 index 0000000..dcb5919 --- /dev/null +++ b/VsProject/PropagationRemasteredBeta/Properties/Settings.Designer.cs @@ -0,0 +1,30 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace PropagationRemasteredBeta.Properties +{ + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase + { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default + { + get + { + return defaultInstance; + } + } + } +} diff --git a/VsProject/PropagationRemasteredBeta/Properties/Settings.settings b/VsProject/PropagationRemasteredBeta/Properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/VsProject/PropagationRemasteredBeta/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/VsProject/PropagationRemasteredBeta/Terrain.cs b/VsProject/PropagationRemasteredBeta/Terrain.cs new file mode 100644 index 0000000..9837752 --- /dev/null +++ b/VsProject/PropagationRemasteredBeta/Terrain.cs @@ -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 _sainCount; + private List _infectedCount; + private List _immuneCount; + private List _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 SainCount { get => _sainCount; set => _sainCount = value; } + public List InfectedCount { get => _infectedCount; set => _infectedCount = value; } + 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 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(); + InfectedCount = new List(); + ImmuneCount = new List(); + DeadCount = new List(); + + 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; + } + } +}