diff options
| author | Fuwn <[email protected]> | 2025-10-30 17:01:14 -0700 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2025-10-30 17:01:14 -0700 |
| commit | 5cdde428a7f966f17f0a94eca7b94fbf1e499838 (patch) | |
| tree | 5f94122032752e2561009ef1c5e5b6641c5fb73c | |
| parent | refactor(diagrams): Move present diagrams to assignment folder (diff) | |
| download | cst276-5cdde428a7f966f17f0a94eca7b94fbf1e499838.tar.xz cst276-5cdde428a7f966f17f0a94eca7b94fbf1e499838.zip | |
feat: Implement Assignment 2 functionality
| -rw-r--r-- | MorgSimulator/Dish.cs | 6 | ||||
| -rw-r--r-- | MorgSimulator/Factory/IMorgFactory.cs | 9 | ||||
| -rw-r--r-- | MorgSimulator/Factory/MorgFactory.cs | 62 | ||||
| -rw-r--r-- | MorgSimulator/Morg.cs | 18 | ||||
| -rw-r--r-- | MorgSimulator/Program.cs | 22 | ||||
| -rw-r--r-- | MorgSimulator/Reader/CSVReader.cs | 25 | ||||
| -rw-r--r-- | MorgSimulator/Reader/FileReader.cs | 23 | ||||
| -rw-r--r-- | MorgSimulator/Reader/MorgReader.cs | 32 | ||||
| -rw-r--r-- | MorgSimulator/Reader/Reader.cs | 11 | ||||
| -rw-r--r-- | MorgSimulator/Reader/ReaderDecorator.cs | 21 | ||||
| -rw-r--r-- | MorgSimulator/Type/TypeAMorg.cs | 16 | ||||
| -rw-r--r-- | MorgSimulator/Type/TypeBMorg.cs | 15 | ||||
| -rw-r--r-- | MorgSimulator/Type/TypeCMorg.cs | 16 | ||||
| -rw-r--r-- | morgs.txt | 4 |
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 |