classDiagram class Entity { <> +int Id +string Type +(int x, int y) Location +(int x, int y) Direction +bool IsAlive +IMovementStrategy MovementStrategy +IFeedingStrategy FeedingStrategy +List~string~ PreyTypes +Entity Prey -List~Entity~ _observers +Attach(observer: Entity) +Detach(observer: Entity) +Notify() +Update(subject: Entity) +Move() +Feed() +CanEat(targetType: string) bool +CalculateDirectionToTarget(target: (int, int)) (int, int) +DistanceTo(target: (int, int)) double } class Morg { +Morg(id, location, direction) } class Simulator~T~ { <> #List~T~ _entities #const double FEEDING_DISTANCE +AddEntity(entity: T) +GetAllEntities() IEnumerable~T~ +CreateIterator() IEntityIterator~T~ +Run(runTime: int) #ProcessTimeStep() #FindPreyIfNeeded(entity: T) #CheckAndFeed(entity: T) #FindNearestPrey(predator: T) Entity* } class Dish { +AddMorg(morg: Morg) +GetAllMorgs() List~Morg~ #FindNearestPrey(predator: Morg) Entity* } class IMovementStrategy { <> +Move(entity: Entity, newLocation: (int, int)) } class MovementStrategyPaddles { +Move(entity: Entity, newLocation: (int, int)) } class MovementStrategyOozes { +Move(entity: Entity, newLocation: (int, int)) } class IFeedingStrategy { <> +Feed(predator: Entity, prey: Entity) } class FeedingStrategyAbsorbs { +Feed(predator: Entity, prey: Entity) } class FeedingStrategyEnvelops { +Feed(predator: Entity, prey: Entity) } class Reader { <> +ReadLine() string* +EndOfStream bool +Close() } class FileReader { -StreamReader _streamReader +ReadLine() string* } class ReaderDecorator { <> #Reader _reader +ReadLine() string* } class CSVReader { +ReadLine() string* +ReadCSVLine() string[]* } class EntityReader~T~ { <> #IEntityFactory~T~ _factory +ReadEntity(id: int) T* } class MorgReader { +ReadEntity(id: int) Morg* } class IEntityFactory~T~ { <> +CreateEntity(id, type, x, y, movement, feeding) T +CreateMovementStrategy(movementType) IMovementStrategy +CreateFeedingStrategy(behavior) IFeedingStrategy } class MorgFactory { +CreateEntity(...) Morg +CreateMovementStrategy(...) IMovementStrategy +CreateFeedingStrategy(...) IFeedingStrategy -ParsePreyTypes(feedingParts) List~string~ } class IEntityIterator~T~ { <> +HasNext() bool +Next() T* +Reset() } class EntityIterator~T~ { -List~T~ _entities -int _currentIndex +HasNext() bool +Next() T* +Reset() } class Program { +Main() } Entity <|-- Morg Simulator~T~ <|-- Dish Entity --> IMovementStrategy : uses Entity --> IFeedingStrategy : uses Entity --> Entity : Observer Pattern IMovementStrategy <|.. MovementStrategyPaddles IMovementStrategy <|.. MovementStrategyOozes IFeedingStrategy <|.. FeedingStrategyAbsorbs IFeedingStrategy <|.. FeedingStrategyEnvelops Reader <|-- FileReader Reader <|-- ReaderDecorator ReaderDecorator <|-- CSVReader ReaderDecorator <|-- EntityReader~T~ EntityReader~T~ <|-- MorgReader EntityReader~T~ --> IEntityFactory~T~ : uses IEntityFactory~T~ <|.. MorgFactory MorgFactory --> Morg : creates MorgFactory --> IMovementStrategy : creates MorgFactory --> IFeedingStrategy : creates Simulator~T~ --> IEntityIterator~T~ IEntityIterator~T~ <|.. EntityIterator~T~ Dish --> Morg Program --> Dish Program --> FileReader Program --> CSVReader Program --> MorgReader Program --> MorgFactory