diff --git a/16_Bug/csharp/Game.cs b/16_Bug/csharp/Game.cs index f1bc1291..c98c44f5 100644 --- a/16_Bug/csharp/Game.cs +++ b/16_Bug/csharp/Game.cs @@ -1,7 +1,9 @@ -using Bug.Resources; +using BugGame.Resources; using Games.Common.IO; using Games.Common.Randomness; +namespace BugGame; + internal class Game { private readonly IReadWrite _io; diff --git a/16_Bug/csharp/Parts/Body.cs b/16_Bug/csharp/Parts/Body.cs new file mode 100644 index 00000000..61aad080 --- /dev/null +++ b/16_Bug/csharp/Parts/Body.cs @@ -0,0 +1,25 @@ +using BugGame.Resources; + +namespace BugGame.Parts; + +internal class Body : ParentPart +{ + private readonly Neck _neck = new(); + private readonly Tail _tail = new(); + private readonly Legs _legs = new(); + + public Body() + : base(Message.BodyAdded, Message.BodyNotNeeded) + { + } + + protected override bool TryAddCore(IPart part, out Message message) + => part switch + { + Neck => _neck.TryAdd(out message), + Head or Feeler => _neck.TryAdd(part, out message), + Tail => _tail.TryAdd(out message), + Leg => _legs.TryAddOne(out message), + _ => throw new NotSupportedException($"Can't add a {part.Name} to a {Name}.") + }; +} diff --git a/16_Bug/csharp/Parts/Feeler.cs b/16_Bug/csharp/Parts/Feeler.cs new file mode 100644 index 00000000..9508d541 --- /dev/null +++ b/16_Bug/csharp/Parts/Feeler.cs @@ -0,0 +1,6 @@ +namespace BugGame.Parts; + +internal class Feeler : IPart +{ + public string Name => nameof(Feeler); +} diff --git a/16_Bug/csharp/Parts/Feelers.cs b/16_Bug/csharp/Parts/Feelers.cs new file mode 100644 index 00000000..fca80c33 --- /dev/null +++ b/16_Bug/csharp/Parts/Feelers.cs @@ -0,0 +1,11 @@ +using BugGame.Resources; + +namespace BugGame.Parts; + +internal class Feelers : PartCollection +{ + public Feelers() + : base(6, Message.FeelerAdded, Message.FeelersFull) + { + } +} diff --git a/16_Bug/csharp/Parts/Head.cs b/16_Bug/csharp/Parts/Head.cs new file mode 100644 index 00000000..2d5e705d --- /dev/null +++ b/16_Bug/csharp/Parts/Head.cs @@ -0,0 +1,20 @@ +using BugGame.Resources; + +namespace BugGame.Parts; + +internal class Head : ParentPart +{ + private Feelers _feelers = new(); + + public Head() + : base(Message.HeadAdded, Message.HeadNotNeeded) + { + } + + protected override bool TryAddCore(IPart part, out Message message) + => part switch + { + Feeler => _feelers.TryAddOne(out message), + _ => throw new NotSupportedException($"Can't add a {part.Name} to a {Name}.") + }; +} diff --git a/16_Bug/csharp/Parts/IPart.cs b/16_Bug/csharp/Parts/IPart.cs new file mode 100644 index 00000000..e325a7c1 --- /dev/null +++ b/16_Bug/csharp/Parts/IPart.cs @@ -0,0 +1,6 @@ +namespace BugGame.Parts; + +internal interface IPart +{ + string Name { get; } +} diff --git a/16_Bug/csharp/Parts/Leg.cs b/16_Bug/csharp/Parts/Leg.cs new file mode 100644 index 00000000..c2d4aaaf --- /dev/null +++ b/16_Bug/csharp/Parts/Leg.cs @@ -0,0 +1,6 @@ +namespace BugGame.Parts; + +internal class Leg : IPart +{ + public string Name => nameof(Leg); +} diff --git a/16_Bug/csharp/Parts/Legs.cs b/16_Bug/csharp/Parts/Legs.cs new file mode 100644 index 00000000..b108e2ea --- /dev/null +++ b/16_Bug/csharp/Parts/Legs.cs @@ -0,0 +1,11 @@ +using BugGame.Resources; + +namespace BugGame.Parts; + +internal class Legs : PartCollection +{ + public Legs() + : base(2, Message.LegAdded, Message.LegsFull) + { + } +} diff --git a/16_Bug/csharp/Parts/Neck.cs b/16_Bug/csharp/Parts/Neck.cs new file mode 100644 index 00000000..035d0c18 --- /dev/null +++ b/16_Bug/csharp/Parts/Neck.cs @@ -0,0 +1,21 @@ +using BugGame.Resources; + +namespace BugGame.Parts; + +internal class Neck : ParentPart +{ + private Head _head = new(); + + public Neck() + : base(Message.NeckAdded, Message.NeckNotNeeded) + { + } + + protected override bool TryAddCore(IPart part, out Message message) + => part switch + { + Head => _head.TryAdd(out message), + Feeler => _head.TryAdd(part, out message), + _ => throw new NotSupportedException($"Can't add a {part.Name} to a {Name}.") + }; +} diff --git a/16_Bug/csharp/Parts/ParentPart.cs b/16_Bug/csharp/Parts/ParentPart.cs new file mode 100644 index 00000000..78a21d6e --- /dev/null +++ b/16_Bug/csharp/Parts/ParentPart.cs @@ -0,0 +1,22 @@ +using BugGame.Resources; + +namespace BugGame.Parts; + +internal abstract class ParentPart : Part +{ + public ParentPart(Message addedMessage, Message duplicateMessage) + : base(addedMessage, duplicateMessage) + { + } + + public bool TryAdd(IPart part, out Message message) + => IsPresent ? TryAddCore(part, out message) : ReportDoNotHave(out message); + + protected abstract bool TryAddCore(IPart part, out Message message); + + private bool ReportDoNotHave(out Message message) + { + message = Message.DoNotHaveA(this); + return false; + } +} diff --git a/16_Bug/csharp/Parts/Part.cs b/16_Bug/csharp/Parts/Part.cs new file mode 100644 index 00000000..a1a5d64d --- /dev/null +++ b/16_Bug/csharp/Parts/Part.cs @@ -0,0 +1,32 @@ +using BugGame.Resources; + +namespace BugGame.Parts; + +internal class Part +{ + private readonly Message _addedMessage; + private readonly Message _duplicateMessage; + + public Part(Message addedMessage, Message duplicateMessage) + { + _addedMessage = addedMessage; + _duplicateMessage = duplicateMessage; + } + + protected bool IsPresent { get; private set; } + + public string Name => GetType().Name; + + public bool TryAdd(out Message message) + { + if (IsPresent) + { + message = _duplicateMessage; + return false; + } + + message = _addedMessage; + IsPresent = true; + return true; + } +} diff --git a/16_Bug/csharp/Parts/PartCollection.cs b/16_Bug/csharp/Parts/PartCollection.cs new file mode 100644 index 00000000..43a684b5 --- /dev/null +++ b/16_Bug/csharp/Parts/PartCollection.cs @@ -0,0 +1,31 @@ +using BugGame.Resources; + +namespace BugGame.Parts; + +internal class PartCollection +{ + private readonly int _maxCount; + private readonly Message _addedMessage; + private readonly Message _fullMessage; + private int _count; + + public PartCollection(int maxCount, Message addedMessage, Message fullMessage) + { + _maxCount = maxCount; + _addedMessage = addedMessage; + _fullMessage = fullMessage; + } + + public bool TryAddOne(out Message message) + { + if (_count < _maxCount) + { + _count++; + message = _addedMessage.ForQuantity(_count); + return true; + } + + message = _fullMessage; + return false; + } +} diff --git a/16_Bug/csharp/Parts/Tail.cs b/16_Bug/csharp/Parts/Tail.cs new file mode 100644 index 00000000..ad610d81 --- /dev/null +++ b/16_Bug/csharp/Parts/Tail.cs @@ -0,0 +1,11 @@ +using BugGame.Resources; + +namespace BugGame.Parts; + +internal class Tail : Part +{ + public Tail() + : base(Message.TailAdded, Message.TailNotNeeded) + { + } +} \ No newline at end of file diff --git a/16_Bug/csharp/Program.cs b/16_Bug/csharp/Program.cs index bb3d85aa..883e62d1 100644 --- a/16_Bug/csharp/Program.cs +++ b/16_Bug/csharp/Program.cs @@ -1,3 +1,4 @@ +using BugGame; using Games.Common.IO; using Games.Common.Randomness; diff --git a/16_Bug/csharp/Resources/Message.cs b/16_Bug/csharp/Resources/Message.cs new file mode 100644 index 00000000..5cd9f998 --- /dev/null +++ b/16_Bug/csharp/Resources/Message.cs @@ -0,0 +1,42 @@ +namespace BugGame.Resources; + +internal class Message +{ + public static Message Rolled = new("rolled a {0}"); + + public static Message BodyAdded = new("now have a body."); + public static Message BodyNotNeeded = new("do not need a body."); + + public static Message NeckAdded = new("now have a neck."); + public static Message NeckNotNeeded = new("do not need a neck."); + + public static Message HeadAdded = new("needed a head."); + public static Message HeadNotNeeded = new("I do not need a head.", "You have a head."); + + public static Message TailAdded = new("I now have a tail.", "I now give you a tail."); + public static Message TailNotNeeded = new("I do not need a tail.", "You already have a tail."); + + public static Message FeelerAdded = new("I get a feeler.", "I now give you a feeler"); + public static Message FeelersFull = new("I have 2 feelers already.", "You have two feelers already"); + + public static Message LegAdded = new("now have {0} legs"); + public static Message LegsFull = new("I have 6 feet.", "You have 6 feet already"); + + private Message(string common) + : this("I " + common, "You" + common) + { + } + + private Message(string i, string you) + { + I = i; + You = you; + } + + public string I { get; } + public string You { get; } + + public static Message DoNotHaveA(Part part) => new($"do no have a {part.Name}"); + + public Message ForQuantity(int quantity) => new(string.Format(I, quantity), string.Format(You, quantity)); +} \ No newline at end of file diff --git a/16_Bug/csharp/Resources/Resource.cs b/16_Bug/csharp/Resources/Resource.cs index 51b7bf39..57f05438 100644 --- a/16_Bug/csharp/Resources/Resource.cs +++ b/16_Bug/csharp/Resources/Resource.cs @@ -1,7 +1,7 @@ using System.Reflection; using System.Runtime.CompilerServices; -namespace Bug.Resources; +namespace BugGame.Resources; internal static class Resource {