summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFuwn <[email protected]>2025-10-30 17:01:14 -0700
committerFuwn <[email protected]>2025-10-30 17:01:14 -0700
commit5cdde428a7f966f17f0a94eca7b94fbf1e499838 (patch)
tree5f94122032752e2561009ef1c5e5b6641c5fb73c
parentrefactor(diagrams): Move present diagrams to assignment folder (diff)
downloadcst276-5cdde428a7f966f17f0a94eca7b94fbf1e499838.tar.xz
cst276-5cdde428a7f966f17f0a94eca7b94fbf1e499838.zip
feat: Implement Assignment 2 functionality
-rw-r--r--MorgSimulator/Dish.cs6
-rw-r--r--MorgSimulator/Factory/IMorgFactory.cs9
-rw-r--r--MorgSimulator/Factory/MorgFactory.cs62
-rw-r--r--MorgSimulator/Morg.cs18
-rw-r--r--MorgSimulator/Program.cs22
-rw-r--r--MorgSimulator/Reader/CSVReader.cs25
-rw-r--r--MorgSimulator/Reader/FileReader.cs23
-rw-r--r--MorgSimulator/Reader/MorgReader.cs32
-rw-r--r--MorgSimulator/Reader/Reader.cs11
-rw-r--r--MorgSimulator/Reader/ReaderDecorator.cs21
-rw-r--r--MorgSimulator/Type/TypeAMorg.cs16
-rw-r--r--MorgSimulator/Type/TypeBMorg.cs15
-rw-r--r--MorgSimulator/Type/TypeCMorg.cs16
-rw-r--r--morgs.txt4
14 files changed, 216 insertions, 64 deletions
diff --git a/MorgSimulator/Dish.cs b/MorgSimulator/Dish.cs
index d81fc8a..1813d5a 100644
--- a/MorgSimulator/Dish.cs
+++ b/MorgSimulator/Dish.cs
@@ -23,8 +23,10 @@ namespace MorgSimulator
Morg? nearestPrey = null;
double nearestDistance = double.MaxValue;
- foreach (var potentialPrey in _morgs.Where(m => m.IsAlive && m != predator))
- if (predator.CanEat(potentialPrey.Type))
+ foreach (var potentialPrey in _morgs)
+ if (potentialPrey.IsAlive &&
+ potentialPrey != predator &&
+ predator.CanEat(potentialPrey.Type))
{
double distance = predator.DistanceTo(potentialPrey.Location);
diff --git a/MorgSimulator/Factory/IMorgFactory.cs b/MorgSimulator/Factory/IMorgFactory.cs
new file mode 100644
index 0000000..60537de
--- /dev/null
+++ b/MorgSimulator/Factory/IMorgFactory.cs
@@ -0,0 +1,9 @@
+namespace MorgSimulator.Factory
+{
+ public interface IMorgFactory
+ {
+ Morg CreateMorg(int id, string type, int x, int y, string movement, string feeding);
+ IMovementStrategy CreateMovementStrategy(string movementType);
+ IFeedingStrategy CreateFeedingStrategy(string behavior);
+ }
+}
diff --git a/MorgSimulator/Factory/MorgFactory.cs b/MorgSimulator/Factory/MorgFactory.cs
new file mode 100644
index 0000000..95ecbee
--- /dev/null
+++ b/MorgSimulator/Factory/MorgFactory.cs
@@ -0,0 +1,62 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace MorgSimulator.Factory
+{
+ public class MorgFactory : IMorgFactory
+ {
+ public Morg CreateMorg(int id, string type, int x, int y, string movement, string feeding)
+ {
+ var trimmedFeeding = feeding.Trim();
+ var feedingParts = trimmedFeeding.Split(' ');
+ var movementStrategy = CreateMovementStrategy(movement);
+ var feedingStrategy = CreateFeedingStrategy(feedingParts[0]);
+ var preyTypes = ParsePreyTypes(feedingParts);
+ var morg = new Morg(id, (x, y), (0, 0))
+ {
+ Type = type,
+ MovementStrategy = movementStrategy,
+ FeedingStrategy = feedingStrategy,
+ PreyTypes = preyTypes
+ };
+
+ return morg;
+ }
+
+ public IMovementStrategy CreateMovementStrategy(string movementType)
+ {
+ return movementType.Trim() switch
+ {
+ "Paddles" => new MovementStrategyPaddles(),
+ "Oozes" => new MovementStrategyOozes(),
+ _ => throw new ArgumentException($"Unknown movement type: {movementType}")
+ };
+ }
+
+ public IFeedingStrategy CreateFeedingStrategy(string behavior)
+ {
+ return behavior switch
+ {
+ "Absorbs" => new FeedingStrategyAbsorbs(),
+ "Envelops" => new FeedingStrategyEnvelops(),
+ _ => throw new ArgumentException($"Unknown feeding type: {behavior}")
+ };
+ }
+
+ private static List<string> ParsePreyTypes(string[] feedingParts)
+ {
+ var preyTypes = new List<string>();
+
+ for (int i = 1; i < feedingParts.Length; i++)
+ {
+ var prey = feedingParts[i].Trim();
+
+ if (!string.IsNullOrEmpty(prey))
+ preyTypes.Add(prey);
+ }
+
+ return preyTypes;
+ }
+ }
+}
diff --git a/MorgSimulator/Morg.cs b/MorgSimulator/Morg.cs
index 62048bf..cfac9dd 100644
--- a/MorgSimulator/Morg.cs
+++ b/MorgSimulator/Morg.cs
@@ -3,16 +3,16 @@ using System.Linq;
namespace MorgSimulator
{
- public abstract class Morg(int id, (int x, int y) location, (int x, int y) direction)
+ public 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 string Type { get; 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>();
+ public IMovementStrategy MovementStrategy { get; set; } = null!;
+ public IFeedingStrategy FeedingStrategy { get; set; } = null!;
+ public List<string> PreyTypes { get; set; } = [];
#nullable enable
public Morg? Prey { get; set; }
#nullable disable
@@ -32,16 +32,16 @@ namespace MorgSimulator
public void Notify()
{
- foreach (var observer in _observers.ToList())
+ foreach (var observer in _observers)
observer.Update(this);
}
- public virtual void Update(Morg subject)
+ public void Update(Morg subject)
{
Direction = CalculateDirectionToTarget(subject.Location);
}
- public virtual void Move()
+ public void Move()
{
if (!IsAlive) return;
@@ -51,7 +51,7 @@ namespace MorgSimulator
Notify();
}
- public virtual void Feed()
+ public void Feed()
{
if (!IsAlive || Prey == null || !Prey.IsAlive) return;
diff --git a/MorgSimulator/Program.cs b/MorgSimulator/Program.cs
index bf15776..29fd971 100644
--- a/MorgSimulator/Program.cs
+++ b/MorgSimulator/Program.cs
@@ -1,13 +1,23 @@
using MorgSimulator;
+using MorgSimulator.Reader;
+using MorgSimulator.Factory;
var dish = new Dish();
+var factory = new MorgFactory();
+var fileReader = new FileReader("morgs.txt");
+var csvReader = new CSVReader(fileReader);
+var morgReader = new MorgReader(csvReader, factory);
+int id = 1;
-dish.AddMorg(new TypeAMorg(1, (0, 0), (1, 0)));
-dish.AddMorg(new TypeAMorg(2, (10, 10), (-1, -1)));
-dish.AddMorg(new TypeBMorg(3, (5, 5), (0, 1)));
-dish.AddMorg(new TypeBMorg(4, (15, 0), (-1, 0)));
-dish.AddMorg(new TypeCMorg(5, (8, 8), (0, -1)));
-dish.AddMorg(new TypeCMorg(6, (20, 5), (-1, 1)));
+while (!morgReader.EndOfStream)
+{
+ var morg = morgReader.ReadMorg(id++);
+
+ if (morg != null)
+ dish.AddMorg(morg);
+}
+
+morgReader.Close();
const int RUN_TIME = 15;
diff --git a/MorgSimulator/Reader/CSVReader.cs b/MorgSimulator/Reader/CSVReader.cs
new file mode 100644
index 0000000..b678eed
--- /dev/null
+++ b/MorgSimulator/Reader/CSVReader.cs
@@ -0,0 +1,25 @@
+#nullable enable
+namespace MorgSimulator.Reader
+{
+ public class CSVReader(Reader reader) : ReaderDecorator(reader)
+ {
+ public override string? ReadLine()
+ {
+ var line = base.ReadLine();
+
+ if (line == null) return null;
+
+ return line.Trim();
+ }
+
+ public string[]? ReadCSVLine()
+ {
+ var line = ReadLine();
+
+ if (line == null) return null;
+
+ return line.Split(',');
+ }
+ }
+}
+#nullable disable
diff --git a/MorgSimulator/Reader/FileReader.cs b/MorgSimulator/Reader/FileReader.cs
new file mode 100644
index 0000000..8c7e3eb
--- /dev/null
+++ b/MorgSimulator/Reader/FileReader.cs
@@ -0,0 +1,23 @@
+#nullable enable
+using System.IO;
+
+namespace MorgSimulator.Reader
+{
+ public class FileReader(string filePath) : Reader
+ {
+ private readonly StreamReader _streamReader = new(filePath);
+
+ public override string? ReadLine()
+ {
+ return _streamReader.ReadLine();
+ }
+
+ public override bool EndOfStream => _streamReader.EndOfStream;
+
+ public override void Close()
+ {
+ _streamReader.Close();
+ }
+ }
+}
+#nullable disable
diff --git a/MorgSimulator/Reader/MorgReader.cs b/MorgSimulator/Reader/MorgReader.cs
new file mode 100644
index 0000000..2bf9a30
--- /dev/null
+++ b/MorgSimulator/Reader/MorgReader.cs
@@ -0,0 +1,32 @@
+#nullable enable
+using MorgSimulator.Factory;
+
+namespace MorgSimulator.Reader
+{
+ public class MorgReader(Reader reader, IMorgFactory factory) : ReaderDecorator(reader)
+ {
+ private readonly IMorgFactory _factory = factory;
+
+ public Morg? ReadMorg(int id)
+ {
+ if (_reader is not CSVReader csvReader) return null;
+
+ var fields = csvReader.ReadCSVLine();
+
+ if (fields == null || fields.Length < 5) return null;
+
+ var type = fields[0].Trim();
+ var xString = fields[1].Trim();
+ var yString = fields[2].Trim();
+ var movement = fields[3].Trim();
+ var feeding = fields[4].Trim();
+
+ if (!int.TryParse(xString, out int x) ||
+ !int.TryParse(yString, out int y))
+ return null;
+
+ return _factory.CreateMorg(id, type, x, y, movement, feeding);
+ }
+ }
+}
+#nullable disable
diff --git a/MorgSimulator/Reader/Reader.cs b/MorgSimulator/Reader/Reader.cs
new file mode 100644
index 0000000..13563b0
--- /dev/null
+++ b/MorgSimulator/Reader/Reader.cs
@@ -0,0 +1,11 @@
+#nullable enable
+namespace MorgSimulator.Reader
+{
+ public abstract class Reader
+ {
+ public abstract string? ReadLine();
+ public abstract bool EndOfStream { get; }
+ public abstract void Close();
+ }
+}
+#nullable disable
diff --git a/MorgSimulator/Reader/ReaderDecorator.cs b/MorgSimulator/Reader/ReaderDecorator.cs
new file mode 100644
index 0000000..38dc1e6
--- /dev/null
+++ b/MorgSimulator/Reader/ReaderDecorator.cs
@@ -0,0 +1,21 @@
+#nullable enable
+namespace MorgSimulator.Reader
+{
+ public abstract class ReaderDecorator(Reader reader) : Reader
+ {
+ protected Reader _reader = reader;
+
+ public override string? ReadLine()
+ {
+ return _reader.ReadLine();
+ }
+
+ public override bool EndOfStream => _reader.EndOfStream;
+
+ public override void Close()
+ {
+ _reader.Close();
+ }
+ }
+}
+#nullable disable
diff --git a/MorgSimulator/Type/TypeAMorg.cs b/MorgSimulator/Type/TypeAMorg.cs
deleted file mode 100644
index 376f054..0000000
--- a/MorgSimulator/Type/TypeAMorg.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-namespace MorgSimulator
-{
- public class TypeAMorg : Morg
- {
- public TypeAMorg(int id, (int x, int y) location, (int x, int y) direction)
- : base(id, location, direction)
- {
- Type = "A";
- MovementStrategy = new MovementStrategyPaddles();
- FeedingStrategy = new FeedingStrategyAbsorbs();
-
- PreyTypes.Add("B");
- PreyTypes.Add("C");
- }
- }
-}
diff --git a/MorgSimulator/Type/TypeBMorg.cs b/MorgSimulator/Type/TypeBMorg.cs
deleted file mode 100644
index 5b235ed..0000000
--- a/MorgSimulator/Type/TypeBMorg.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-namespace MorgSimulator
-{
- public class TypeBMorg : Morg
- {
- public TypeBMorg(int id, (int x, int y) location, (int x, int y) direction)
- : base(id, location, direction)
- {
- Type = "B";
- MovementStrategy = new MovementStrategyOozes();
- FeedingStrategy = new FeedingStrategyEnvelops();
-
- PreyTypes.Add("A");
- }
- }
-}
diff --git a/MorgSimulator/Type/TypeCMorg.cs b/MorgSimulator/Type/TypeCMorg.cs
deleted file mode 100644
index 35577a1..0000000
--- a/MorgSimulator/Type/TypeCMorg.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-namespace MorgSimulator
-{
- public class TypeCMorg : Morg
- {
- public TypeCMorg(int id, (int x, int y) location, (int x, int y) direction)
- : base(id, location, direction)
- {
- Type = "C";
- MovementStrategy = new MovementStrategyPaddles();
- FeedingStrategy = new FeedingStrategyEnvelops();
-
- PreyTypes.Add("A");
- PreyTypes.Add("B");
- }
- }
-}
diff --git a/morgs.txt b/morgs.txt
new file mode 100644
index 0000000..19e3a73
--- /dev/null
+++ b/morgs.txt
@@ -0,0 +1,4 @@
+A,24,33,Paddles,Absorbs B C
+B,13,42,Oozes,Envelops A
+C,6,7,Paddles,Envelops A B
+D,21,6,Oozes,Absorbs C