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 { public SolidBrush SAIN_COLOR; public SolidBrush INFECTED_COLOR; public SolidBrush IMMUNE_COLOR; public SolidBrush DEATH_COLOR; //those are constants to use with the state attribute and not get confused public const int SAIN = 0; public const int INFECTED = 1; public const int IMMUNE = 2; public const int DEAD = 3; private Point _position; private int _state; private Size _humanSize; private int _lifeTimeCounter; private int _InfectedTimeCounter; private SolidBrush _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 int LifeTimeCounter { get => _lifeTimeCounter; set => _lifeTimeCounter = value; } public int InfectedTimeCounter { get => _InfectedTimeCounter; set => _InfectedTimeCounter = value; } //public Color Sprite { get => Sprite; set => Sprite = value; } public SolidBrush Sprite { get => _sprite; set => _sprite = value; } public Human(Point position, int state, SolidBrush sainColor, SolidBrush infectedColor, SolidBrush immuneColor, SolidBrush deadColor) { Position = position; LifeTimeCounter = 1; InfectedTimeCounter = 0; SAIN_COLOR = sainColor; INFECTED_COLOR = infectedColor; IMMUNE_COLOR = immuneColor; DEATH_COLOR = deadColor; //IMPORTANT only set state AFTER colors or some people will have sprites set to null State = state; } public Human(Point position, int state) : this(position, state, new SolidBrush(Color.Green), new SolidBrush(Color.Red), new SolidBrush(Color.Blue), new SolidBrush(Color.Black)) { } public void ChangeBaseColors(SolidBrush sainColor, SolidBrush infectedColor, SolidBrush immuneColor, SolidBrush deadColor) { SAIN_COLOR = sainColor; IMMUNE_COLOR = immuneColor; DEATH_COLOR = deadColor; INFECTED_COLOR = infectedColor; } public Human Propagate(Terrain T) { Human target; Point location; LifeTimeCounter++; InfectedTimeCounter++; List peopleToCheckLocations = new List(); //we need to check if we are not in a corner if (Position.X > 0 && Position.Y > 0 && Position.X < (T.TerrainSize.Width - 1) && Position.Y < (T.TerrainSize.Height - 1)) { //check top left peopleToCheckLocations.Add(new Point(Position.X - 1, Position.Y + 1)); //check top peopleToCheckLocations.Add(new Point(Position.X, Position.Y + 1)); //check top left peopleToCheckLocations.Add(new Point(Position.X, Position.Y + 1)); //check left peopleToCheckLocations.Add(new Point(Position.X - 1, Position.Y)); //check right peopleToCheckLocations.Add(new Point(Position.X + 1, Position.Y)); //check bottom left peopleToCheckLocations.Add(new Point(Position.X - 1, Position.Y - 1)); //check bottom peopleToCheckLocations.Add(new Point(Position.X, Position.Y - 1)); //check bottom right peopleToCheckLocations.Add(new Point(Position.X + 1, Position.Y - 1)); } else { //now we have te peoples that are in sides or corners if (Position.Y == 0) { if (Position.X == 0) { //top left corner // @# // ## peopleToCheckLocations.Add(new Point(Position.X + 1,Position.Y)); peopleToCheckLocations.Add(new Point(Position.X, Position.Y + 1)); peopleToCheckLocations.Add(new Point(Position.X + 1, Position.Y + 1)); } else if (Position.X >= T.TerrainSize.Width -1) { //top right corner // #@ // ## peopleToCheckLocations.Add(new Point(Position.X - 1, Position.Y + 1)); peopleToCheckLocations.Add(new Point(Position.X - 1, Position.Y)); peopleToCheckLocations.Add(new Point(Position.X, Position.Y + 1)); } else { //on the top side // #@# // ### peopleToCheckLocations.Add(new Point(Position.X - 1, Position.Y + 1)); peopleToCheckLocations.Add(new Point(Position.X - 1, Position.Y)); peopleToCheckLocations.Add(new Point(Position.X + 1, Position.Y)); peopleToCheckLocations.Add(new Point(Position.X, Position.Y + 1)); peopleToCheckLocations.Add(new Point(Position.X + 1, Position.Y + 1)); } } else { if (Position.Y >= T.TerrainSize.Height - 1) { if (Position.X == 0) { //bottom left corner // ## // @# peopleToCheckLocations.Add(new Point(Position.X + 1, Position.Y)); peopleToCheckLocations.Add(new Point(Position.X, Position.Y - 1)); peopleToCheckLocations.Add(new Point(Position.X + 1, Position.Y - 1)); } else if (Position.X >= T.TerrainSize.Width - 1) { //Bottom right corner // ## // #@ peopleToCheckLocations.Add(new Point(Position.X - 1, Position.Y - 1)); peopleToCheckLocations.Add(new Point(Position.X - 1, Position.Y)); peopleToCheckLocations.Add(new Point(Position.X, Position.Y - 1)); } else { //on the bottom side // ### // #@# peopleToCheckLocations.Add(new Point(Position.X - 1, Position.Y - 1)); peopleToCheckLocations.Add(new Point(Position.X - 1, Position.Y)); peopleToCheckLocations.Add(new Point(Position.X + 1, Position.Y)); peopleToCheckLocations.Add(new Point(Position.X, Position.Y - 1)); peopleToCheckLocations.Add(new Point(Position.X + 1, Position.Y - 1)); } } else { //on the left side if (Position.X >= T.TerrainSize.Width -1) { // ## // #@ // ## peopleToCheckLocations.Add(new Point(Position.X,Position.Y)); peopleToCheckLocations.Add(new Point(Position.X -1, Position.Y -1)); peopleToCheckLocations.Add(new Point(Position.X, Position.Y -1)); peopleToCheckLocations.Add(new Point(Position.X -1, Position.Y)); peopleToCheckLocations.Add(new Point(Position.X - 1, Position.Y +1)); peopleToCheckLocations.Add(new Point(Position.X, Position.Y +1)); } else { //on the right side // ## // @# // ## peopleToCheckLocations.Add(new Point(Position.X, Position.Y)); peopleToCheckLocations.Add(new Point(Position.X, Position.Y -1)); peopleToCheckLocations.Add(new Point(Position.X + 1, Position.Y -1)); peopleToCheckLocations.Add(new Point(Position.X + 1, Position.Y)); peopleToCheckLocations.Add(new Point(Position.X, Position.Y + 1)); peopleToCheckLocations.Add(new Point(Position.X + 1, Position.Y + 1)); } } } } foreach (Point p in peopleToCheckLocations) { target = T.Population[p.X, p.Y]; if (target.State == Human.SAIN) { T.PeopleToCheck.Add(target); } } T.InfectedsToCheck.Add(this); return this; } public Human CheckInfection(int infectiosity, Random rnd) { if (rnd.Next(0, 100) <= infectiosity) { State = INFECTED; } return this; } public Human CheckDeath(int deathRate, int cureTime, Random rnd) { if (rnd.Next(0, 100) <= deathRate) { State = DEAD; } if (InfectedTimeCounter >= cureTime) { State = IMMUNE; } return this; } public object Clone() { Human newHuman = new Human(Position, State); newHuman.InfectedTimeCounter = InfectedTimeCounter; newHuman.LifeTimeCounter = LifeTimeCounter; return newHuman; } } }