summaryrefslogtreecommitdiff
path: root/MorgSimulator/Morg.cs
diff options
context:
space:
mode:
Diffstat (limited to 'MorgSimulator/Morg.cs')
-rw-r--r--MorgSimulator/Morg.cs87
1 files changed, 87 insertions, 0 deletions
diff --git a/MorgSimulator/Morg.cs b/MorgSimulator/Morg.cs
new file mode 100644
index 0000000..62048bf
--- /dev/null
+++ b/MorgSimulator/Morg.cs
@@ -0,0 +1,87 @@
+using System.Collections.Generic;
+using System.Linq;
+
+namespace MorgSimulator
+{
+ public abstract class Morg(int id, (int x, int y) location, (int x, int y) direction)
+ {
+ public int Id { get; set; } = id;
+ public string Type { get; protected set; } = string.Empty;
+ public (int x, int y) Location { get; set; } = location;
+ public (int x, int y) Direction { get; set; } = direction;
+ public bool IsAlive { get; set; } = true;
+ public IMovementStrategy MovementStrategy { get; protected set; } = null!;
+ public IFeedingStrategy FeedingStrategy { get; protected set; } = null!;
+ public List<string> PreyTypes { get; protected set; } = new List<string>();
+#nullable enable
+ public Morg? Prey { get; set; }
+#nullable disable
+
+ private readonly List<Morg> _observers = [];
+
+ public void Attach(Morg observer)
+ {
+ if (!_observers.Contains(observer))
+ _observers.Add(observer);
+ }
+
+ public void Detach(Morg observer)
+ {
+ _observers.Remove(observer);
+ }
+
+ public void Notify()
+ {
+ foreach (var observer in _observers.ToList())
+ observer.Update(this);
+ }
+
+ public virtual void Update(Morg subject)
+ {
+ Direction = CalculateDirectionToTarget(subject.Location);
+ }
+
+ public virtual void Move()
+ {
+ if (!IsAlive) return;
+
+ var newLocation = (Location.x + Direction.x, Location.y + Direction.y);
+
+ MovementStrategy.Move(this, newLocation);
+ Notify();
+ }
+
+ public virtual void Feed()
+ {
+ if (!IsAlive || Prey == null || !Prey.IsAlive) return;
+
+ FeedingStrategy.Feed(this, Prey);
+
+ Prey = null;
+ }
+
+ public bool CanEat(string targetType)
+ {
+ return PreyTypes.Contains(targetType);
+ }
+
+ public (int x, int y) CalculateDirectionToTarget((int x, int y) target)
+ {
+ int deltaX = target.x - Location.x;
+ int deltaY = target.y - Location.y;
+ int directionX = deltaX > 0 ? 1 : (deltaX < 0 ? -1 : 0);
+ int directionY = deltaY > 0 ? 1 : (deltaY < 0 ? -1 : 0);
+
+ return (directionX, directionY);
+ }
+
+ public double DistanceTo((int x, int y) target)
+ {
+ int deltaX = target.x - Location.x;
+ int deltaY = target.y - Location.y;
+
+ return System.Math.Sqrt(deltaX * deltaX + deltaY * deltaY);
+ }
+
+ }
+} \ No newline at end of file