Added first version of the project (Proof Of Concept)

This commit is contained in:
M.Rohmer
2022-03-03 17:07:29 +01:00
parent d5a7454936
commit 3a561f2d0a
14 changed files with 1378 additions and 0 deletions
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
</configuration>
+289
View File
@@ -0,0 +1,289 @@
namespace PropagationRemasteredBeta
{
partial class Form1
{
/// <summary>
/// Variable nécessaire au concepteur.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Nettoyage des ressources utilisées.
/// </summary>
/// <param name="disposing">true si les ressources managées doivent être supprimées ; sinon, false.</param>
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
/// <summary>
/// Méthode requise pour la prise en charge du concepteur - ne modifiez pas
/// le contenu de cette méthode avec l'éditeur de code.
/// </summary>
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;
}
}
@@ -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);
}
}
}
@@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="tmrTick.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>
@@ -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;
}
}
}
@@ -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
{
/// <summary>
/// Point d'entrée principal de l'application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
@@ -0,0 +1,85 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{27825863-02A0-4112-BE3D-47E5B83177A5}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>PropagationRemasteredBeta</RootNamespace>
<AssemblyName>PropagationRemasteredBeta</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Form1.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Form1.Designer.cs">
<DependentUpon>Form1.cs</DependentUpon>
</Compile>
<Compile Include="Human.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Terrain.cs" />
<EmbeddedResource Include="Form1.resx">
<DependentUpon>Form1.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
@@ -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")]
@@ -0,0 +1,71 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 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é.
// </auto-generated>
//------------------------------------------------------------------------------
namespace PropagationRemasteredBeta.Properties
{
/// <summary>
/// Une classe de ressource fortement typée destinée, entre autres, à la consultation des chaînes localisées.
/// </summary>
// 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()
{
}
/// <summary>
/// Retourne l'instance ResourceManager mise en cache utilisée par cette classe.
/// </summary>
[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;
}
}
/// <summary>
/// Remplace la propriété CurrentUICulture du thread actuel pour toutes
/// les recherches de ressources à l'aide de cette classe de ressource fortement typée.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture
{
get
{
return resourceCulture;
}
set
{
resourceCulture = value;
}
}
}
}
@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
@@ -0,0 +1,30 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 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.
// </auto-generated>
//------------------------------------------------------------------------------
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;
}
}
}
}
@@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>
@@ -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;
}
}
}