From 832371dc07f83ec64e194349cf20af18678b3053 Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Wed, 6 Jul 2022 07:46:16 +1000 Subject: [PATCH 01/11] Add string resources --- 16_Bug/csharp/Bug.csproj | 9 +++++++++ 16_Bug/csharp/Resources/Introduction.txt | 7 +++++++ 16_Bug/csharp/Resources/Intructions.txt | 18 ++++++++++++++++++ 16_Bug/csharp/Resources/Resource.cs | 24 ++++++++++++++++++++++++ 4 files changed, 58 insertions(+) create mode 100644 16_Bug/csharp/Resources/Introduction.txt create mode 100644 16_Bug/csharp/Resources/Intructions.txt create mode 100644 16_Bug/csharp/Resources/Resource.cs diff --git a/16_Bug/csharp/Bug.csproj b/16_Bug/csharp/Bug.csproj index d3fe4757..91e759c0 100644 --- a/16_Bug/csharp/Bug.csproj +++ b/16_Bug/csharp/Bug.csproj @@ -6,4 +6,13 @@ enable enable + + + + + + + + + diff --git a/16_Bug/csharp/Resources/Introduction.txt b/16_Bug/csharp/Resources/Introduction.txt new file mode 100644 index 00000000..b49238e6 --- /dev/null +++ b/16_Bug/csharp/Resources/Introduction.txt @@ -0,0 +1,7 @@ + Bug + Creative Computing Morristown, New Jersey + + + +The Game Bug +I hope you enjoy this game. diff --git a/16_Bug/csharp/Resources/Intructions.txt b/16_Bug/csharp/Resources/Intructions.txt new file mode 100644 index 00000000..bdbdadd3 --- /dev/null +++ b/16_Bug/csharp/Resources/Intructions.txt @@ -0,0 +1,18 @@ +The object of Bug is to finish your bug before I finish +mine. Each number stands for a part of the bug body. +I will roll the die for you, tell you what I rolled for you +what the number stands for, and if you can get the part. +If you can get the part I will give it to you. +The same will happen on my turn. +If there is a change in either bug I will give you the +option of seeing the pictures of the bugs. +The numbers stand for parts as follows: +Number Part Number of part needed + 1 Body 1 + 2 Neck 1 + 3 Head 1 + 4 Feelers 2 + 5 Tail 1 + 6 Legs 6 + + diff --git a/16_Bug/csharp/Resources/Resource.cs b/16_Bug/csharp/Resources/Resource.cs new file mode 100644 index 00000000..165b9c82 --- /dev/null +++ b/16_Bug/csharp/Resources/Resource.cs @@ -0,0 +1,24 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +namespace Bug.Resources; + +internal static class Resource +{ + internal static class Streams + { + public static Stream Introduction => GetStream(); + public static Stream Instructions => GetStream(); + } + + private static string GetString([CallerMemberName] string? name = null) + { + using var stream = GetStream(name); + using var reader = new StreamReader(stream); + return reader.ReadToEnd(); + } + + private static Stream GetStream([CallerMemberName] string? name = null) => + Assembly.GetExecutingAssembly().GetManifestResourceStream($"Basketball.Resources.{name}.txt") + ?? throw new Exception($"Could not find embedded resource stream '{name}'."); +} \ No newline at end of file From ffc0b99fa3c57d8279c1334832893b7ffd27bf4f Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Wed, 6 Jul 2022 07:48:01 +1000 Subject: [PATCH 02/11] Display title and instructions --- 16_Bug/csharp/Game.cs | 25 +++++++++++++++++++++++++ 16_Bug/csharp/Program.cs | 4 ++++ 2 files changed, 29 insertions(+) create mode 100644 16_Bug/csharp/Game.cs create mode 100644 16_Bug/csharp/Program.cs diff --git a/16_Bug/csharp/Game.cs b/16_Bug/csharp/Game.cs new file mode 100644 index 00000000..b82c270d --- /dev/null +++ b/16_Bug/csharp/Game.cs @@ -0,0 +1,25 @@ +using Bug.Resources; +using Games.Common.IO; +using Games.Common.Randomness; + +internal class Game +{ + private readonly IReadWrite _io; + private readonly IRandom _random; + + public Game(IReadWrite io, IRandom random) + { + _io = io; + _random = random; + } + + public void Play() + { + _io.WriteLine(Resource.Streams.Introduction); + var response = _io.ReadString("Do you want instructions"); + if (!response.Equals("no", StringComparison.InvariantCultureIgnoreCase)) + { + _io.WriteLine(Resource.Streams.Instructions); + } + } +} \ No newline at end of file diff --git a/16_Bug/csharp/Program.cs b/16_Bug/csharp/Program.cs new file mode 100644 index 00000000..bb3d85aa --- /dev/null +++ b/16_Bug/csharp/Program.cs @@ -0,0 +1,4 @@ +using Games.Common.IO; +using Games.Common.Randomness; + +new Game(new ConsoleIO(), new RandomNumberGenerator()).Play(); From f35bbb02243a82802888fc0d95e928a6b8cf0573 Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Wed, 6 Jul 2022 07:52:59 +1000 Subject: [PATCH 03/11] Fix some resource issues --- 16_Bug/csharp/Game.cs | 4 ++-- 16_Bug/csharp/Resources/{Intructions.txt => Instructions.txt} | 0 16_Bug/csharp/Resources/Introduction.txt | 1 + 16_Bug/csharp/Resources/Resource.cs | 3 ++- 4 files changed, 5 insertions(+), 3 deletions(-) rename 16_Bug/csharp/Resources/{Intructions.txt => Instructions.txt} (100%) diff --git a/16_Bug/csharp/Game.cs b/16_Bug/csharp/Game.cs index b82c270d..f1bc1291 100644 --- a/16_Bug/csharp/Game.cs +++ b/16_Bug/csharp/Game.cs @@ -15,11 +15,11 @@ internal class Game public void Play() { - _io.WriteLine(Resource.Streams.Introduction); + _io.Write(Resource.Streams.Introduction); var response = _io.ReadString("Do you want instructions"); if (!response.Equals("no", StringComparison.InvariantCultureIgnoreCase)) { - _io.WriteLine(Resource.Streams.Instructions); + _io.Write(Resource.Streams.Instructions); } } } \ No newline at end of file diff --git a/16_Bug/csharp/Resources/Intructions.txt b/16_Bug/csharp/Resources/Instructions.txt similarity index 100% rename from 16_Bug/csharp/Resources/Intructions.txt rename to 16_Bug/csharp/Resources/Instructions.txt diff --git a/16_Bug/csharp/Resources/Introduction.txt b/16_Bug/csharp/Resources/Introduction.txt index b49238e6..e74a833e 100644 --- a/16_Bug/csharp/Resources/Introduction.txt +++ b/16_Bug/csharp/Resources/Introduction.txt @@ -5,3 +5,4 @@ The Game Bug I hope you enjoy this game. + diff --git a/16_Bug/csharp/Resources/Resource.cs b/16_Bug/csharp/Resources/Resource.cs index 165b9c82..51b7bf39 100644 --- a/16_Bug/csharp/Resources/Resource.cs +++ b/16_Bug/csharp/Resources/Resource.cs @@ -19,6 +19,7 @@ internal static class Resource } private static Stream GetStream([CallerMemberName] string? name = null) => - Assembly.GetExecutingAssembly().GetManifestResourceStream($"Basketball.Resources.{name}.txt") + Assembly.GetExecutingAssembly() + .GetManifestResourceStream($"{typeof(Resource).Namespace}.{name}.txt") ?? throw new Exception($"Could not find embedded resource stream '{name}'."); } \ No newline at end of file From 6078da8c783a7e449b847b8d34adcef997861150 Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Mon, 11 Jul 2022 08:46:42 +1000 Subject: [PATCH 04/11] Add parts and messages --- 16_Bug/csharp/Game.cs | 4 ++- 16_Bug/csharp/Parts/Body.cs | 25 ++++++++++++++++ 16_Bug/csharp/Parts/Feeler.cs | 6 ++++ 16_Bug/csharp/Parts/Feelers.cs | 11 +++++++ 16_Bug/csharp/Parts/Head.cs | 20 +++++++++++++ 16_Bug/csharp/Parts/IPart.cs | 6 ++++ 16_Bug/csharp/Parts/Leg.cs | 6 ++++ 16_Bug/csharp/Parts/Legs.cs | 11 +++++++ 16_Bug/csharp/Parts/Neck.cs | 21 ++++++++++++++ 16_Bug/csharp/Parts/ParentPart.cs | 22 ++++++++++++++ 16_Bug/csharp/Parts/Part.cs | 32 ++++++++++++++++++++ 16_Bug/csharp/Parts/PartCollection.cs | 31 ++++++++++++++++++++ 16_Bug/csharp/Parts/Tail.cs | 11 +++++++ 16_Bug/csharp/Program.cs | 1 + 16_Bug/csharp/Resources/Message.cs | 42 +++++++++++++++++++++++++++ 16_Bug/csharp/Resources/Resource.cs | 2 +- 16 files changed, 249 insertions(+), 2 deletions(-) create mode 100644 16_Bug/csharp/Parts/Body.cs create mode 100644 16_Bug/csharp/Parts/Feeler.cs create mode 100644 16_Bug/csharp/Parts/Feelers.cs create mode 100644 16_Bug/csharp/Parts/Head.cs create mode 100644 16_Bug/csharp/Parts/IPart.cs create mode 100644 16_Bug/csharp/Parts/Leg.cs create mode 100644 16_Bug/csharp/Parts/Legs.cs create mode 100644 16_Bug/csharp/Parts/Neck.cs create mode 100644 16_Bug/csharp/Parts/ParentPart.cs create mode 100644 16_Bug/csharp/Parts/Part.cs create mode 100644 16_Bug/csharp/Parts/PartCollection.cs create mode 100644 16_Bug/csharp/Parts/Tail.cs create mode 100644 16_Bug/csharp/Resources/Message.cs 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 { From be9f0a92f8ee48567d492dbf5a7a5ea76f51f6f8 Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Tue, 12 Jul 2022 07:41:45 +1000 Subject: [PATCH 05/11] Add Bug and conecpt of completeness --- 16_Bug/csharp/Bug.cs | 13 +++++++++++++ 16_Bug/csharp/Parts/Body.cs | 2 ++ 16_Bug/csharp/Parts/Head.cs | 2 ++ 16_Bug/csharp/Parts/IPart.cs | 1 + 16_Bug/csharp/Parts/Neck.cs | 2 ++ 16_Bug/csharp/Parts/Part.cs | 2 ++ 16_Bug/csharp/Parts/PartCollection.cs | 2 ++ 16_Bug/csharp/Resources/Message.cs | 2 ++ 8 files changed, 26 insertions(+) create mode 100644 16_Bug/csharp/Bug.cs diff --git a/16_Bug/csharp/Bug.cs b/16_Bug/csharp/Bug.cs new file mode 100644 index 00000000..e013d1b6 --- /dev/null +++ b/16_Bug/csharp/Bug.cs @@ -0,0 +1,13 @@ +using BugGame.Parts; +using BugGame.Resources; + +namespace BugGame; + +internal class Bug +{ + private readonly Body _body = new(); + + public bool IsComplete => _body.IsComplete; + + public bool TryAdd(IPart part, out Message message) => _body.TryAdd(part, out message); +} \ No newline at end of file diff --git a/16_Bug/csharp/Parts/Body.cs b/16_Bug/csharp/Parts/Body.cs index 61aad080..65fde374 100644 --- a/16_Bug/csharp/Parts/Body.cs +++ b/16_Bug/csharp/Parts/Body.cs @@ -13,6 +13,8 @@ internal class Body : ParentPart { } + public override bool IsComplete => _neck.IsComplete && _tail.IsComplete && _legs.IsComplete; + protected override bool TryAddCore(IPart part, out Message message) => part switch { diff --git a/16_Bug/csharp/Parts/Head.cs b/16_Bug/csharp/Parts/Head.cs index 2d5e705d..bafa172f 100644 --- a/16_Bug/csharp/Parts/Head.cs +++ b/16_Bug/csharp/Parts/Head.cs @@ -11,6 +11,8 @@ internal class Head : ParentPart { } + public override bool IsComplete => _feelers.IsComplete; + protected override bool TryAddCore(IPart part, out Message message) => part switch { diff --git a/16_Bug/csharp/Parts/IPart.cs b/16_Bug/csharp/Parts/IPart.cs index e325a7c1..3d1a45c5 100644 --- a/16_Bug/csharp/Parts/IPart.cs +++ b/16_Bug/csharp/Parts/IPart.cs @@ -3,4 +3,5 @@ namespace BugGame.Parts; internal interface IPart { string Name { get; } + bool IsComplete { get; } } diff --git a/16_Bug/csharp/Parts/Neck.cs b/16_Bug/csharp/Parts/Neck.cs index 035d0c18..ee5853e2 100644 --- a/16_Bug/csharp/Parts/Neck.cs +++ b/16_Bug/csharp/Parts/Neck.cs @@ -11,6 +11,8 @@ internal class Neck : ParentPart { } + public override bool IsComplete => _head.IsComplete; + protected override bool TryAddCore(IPart part, out Message message) => part switch { diff --git a/16_Bug/csharp/Parts/Part.cs b/16_Bug/csharp/Parts/Part.cs index a1a5d64d..ada12b8c 100644 --- a/16_Bug/csharp/Parts/Part.cs +++ b/16_Bug/csharp/Parts/Part.cs @@ -13,6 +13,8 @@ internal class Part _duplicateMessage = duplicateMessage; } + public virtual bool IsComplete => IsPresent; + protected bool IsPresent { get; private set; } public string Name => GetType().Name; diff --git a/16_Bug/csharp/Parts/PartCollection.cs b/16_Bug/csharp/Parts/PartCollection.cs index 43a684b5..aac0bbd2 100644 --- a/16_Bug/csharp/Parts/PartCollection.cs +++ b/16_Bug/csharp/Parts/PartCollection.cs @@ -16,6 +16,8 @@ internal class PartCollection _fullMessage = fullMessage; } + public bool IsComplete => _count == _maxCount; + public bool TryAddOne(out Message message) { if (_count < _maxCount) diff --git a/16_Bug/csharp/Resources/Message.cs b/16_Bug/csharp/Resources/Message.cs index 5cd9f998..be85faf8 100644 --- a/16_Bug/csharp/Resources/Message.cs +++ b/16_Bug/csharp/Resources/Message.cs @@ -1,3 +1,5 @@ +using BugGame.Parts; + namespace BugGame.Resources; internal class Message From 04ec0f8f47a0278ed0c7f208210e6b6d87ddee0a Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Wed, 13 Jul 2022 08:04:35 +1000 Subject: [PATCH 06/11] Add printing of bugs --- 16_Bug/csharp/Bug.cs | 8 ++++++++ 16_Bug/csharp/Parts/Body.cs | 14 ++++++++++++++ 16_Bug/csharp/Parts/Feelers.cs | 5 ++++- 16_Bug/csharp/Parts/Head.cs | 13 +++++++++++++ 16_Bug/csharp/Parts/IPart.cs | 1 - 16_Bug/csharp/Parts/Legs.cs | 5 ++++- 16_Bug/csharp/Parts/Neck.cs | 7 +++++++ 16_Bug/csharp/Parts/Part.cs | 2 +- 16_Bug/csharp/Parts/PartCollection.cs | 19 ++++++++++++++++++- 16_Bug/csharp/Parts/Tail.cs | 3 +++ 10 files changed, 72 insertions(+), 5 deletions(-) diff --git a/16_Bug/csharp/Bug.cs b/16_Bug/csharp/Bug.cs index e013d1b6..42e686d4 100644 --- a/16_Bug/csharp/Bug.cs +++ b/16_Bug/csharp/Bug.cs @@ -1,3 +1,4 @@ +using System.Text; using BugGame.Parts; using BugGame.Resources; @@ -10,4 +11,11 @@ internal class Bug public bool IsComplete => _body.IsComplete; public bool TryAdd(IPart part, out Message message) => _body.TryAdd(part, out message); + + public string ToString(string pronoun, char feelerCharacter) + { + var builder = new StringBuilder($"*****{pronoun} Bug*****").AppendLine().AppendLine().AppendLine(); + _body.AppendTo(builder, feelerCharacter); + return builder.ToString(); + } } \ No newline at end of file diff --git a/16_Bug/csharp/Parts/Body.cs b/16_Bug/csharp/Parts/Body.cs index 65fde374..2b7586dc 100644 --- a/16_Bug/csharp/Parts/Body.cs +++ b/16_Bug/csharp/Parts/Body.cs @@ -1,3 +1,4 @@ +using System.Text; using BugGame.Resources; namespace BugGame.Parts; @@ -24,4 +25,17 @@ internal class Body : ParentPart Leg => _legs.TryAddOne(out message), _ => throw new NotSupportedException($"Can't add a {part.Name} to a {Name}.") }; + + public void AppendTo(StringBuilder builder, char feelerCharacter) + { + _neck.AppendTo(builder, feelerCharacter); + builder + .AppendLine(" BBBBBBBBBBBB") + .AppendLine(" B B") + .AppendLine(" B B"); + _tail.AppendTo(builder); + builder + .AppendLine(" BBBBBBBBBBBB"); + _legs.AppendTo(builder); + } } diff --git a/16_Bug/csharp/Parts/Feelers.cs b/16_Bug/csharp/Parts/Feelers.cs index fca80c33..165a073d 100644 --- a/16_Bug/csharp/Parts/Feelers.cs +++ b/16_Bug/csharp/Parts/Feelers.cs @@ -1,3 +1,4 @@ +using System.Text; using BugGame.Resources; namespace BugGame.Parts; @@ -5,7 +6,9 @@ namespace BugGame.Parts; internal class Feelers : PartCollection { public Feelers() - : base(6, Message.FeelerAdded, Message.FeelersFull) + : base(2, Message.FeelerAdded, Message.FeelersFull) { } + + public void AppendTo(StringBuilder builder, char character) => AppendTo(builder, 10, 4, character); } diff --git a/16_Bug/csharp/Parts/Head.cs b/16_Bug/csharp/Parts/Head.cs index bafa172f..3bab7caa 100644 --- a/16_Bug/csharp/Parts/Head.cs +++ b/16_Bug/csharp/Parts/Head.cs @@ -1,3 +1,4 @@ +using System.Text; using BugGame.Resources; namespace BugGame.Parts; @@ -19,4 +20,16 @@ internal class Head : ParentPart Feeler => _feelers.TryAddOne(out message), _ => throw new NotSupportedException($"Can't add a {part.Name} to a {Name}.") }; + + public void AppendTo(StringBuilder builder, char feelerCharacter) + { + _feelers.AppendTo(builder, feelerCharacter); + builder + .AppendLine(" HHHHHHH") + .AppendLine(" H H") + .AppendLine(" H O O H") + .AppendLine(" H H") + .AppendLine(" H V H") + .AppendLine(" HHHHHHH"); + } } diff --git a/16_Bug/csharp/Parts/IPart.cs b/16_Bug/csharp/Parts/IPart.cs index 3d1a45c5..e325a7c1 100644 --- a/16_Bug/csharp/Parts/IPart.cs +++ b/16_Bug/csharp/Parts/IPart.cs @@ -3,5 +3,4 @@ namespace BugGame.Parts; internal interface IPart { string Name { get; } - bool IsComplete { get; } } diff --git a/16_Bug/csharp/Parts/Legs.cs b/16_Bug/csharp/Parts/Legs.cs index b108e2ea..0ed8d8fc 100644 --- a/16_Bug/csharp/Parts/Legs.cs +++ b/16_Bug/csharp/Parts/Legs.cs @@ -1,3 +1,4 @@ +using System.Text; using BugGame.Resources; namespace BugGame.Parts; @@ -5,7 +6,9 @@ namespace BugGame.Parts; internal class Legs : PartCollection { public Legs() - : base(2, Message.LegAdded, Message.LegsFull) + : base(6, Message.LegAdded, Message.LegsFull) { } + + public void AppendTo(StringBuilder builder) => AppendTo(builder, 6, 2, 'L'); } diff --git a/16_Bug/csharp/Parts/Neck.cs b/16_Bug/csharp/Parts/Neck.cs index ee5853e2..e8976c1c 100644 --- a/16_Bug/csharp/Parts/Neck.cs +++ b/16_Bug/csharp/Parts/Neck.cs @@ -1,3 +1,4 @@ +using System.Text; using BugGame.Resources; namespace BugGame.Parts; @@ -20,4 +21,10 @@ internal class Neck : ParentPart Feeler => _head.TryAdd(part, out message), _ => throw new NotSupportedException($"Can't add a {part.Name} to a {Name}.") }; + + public void AppendTo(StringBuilder builder, char feelerCharacter) + { + _head.AppendTo(builder, feelerCharacter); + builder.AppendLine(" N N").AppendLine(" N N"); + } } diff --git a/16_Bug/csharp/Parts/Part.cs b/16_Bug/csharp/Parts/Part.cs index ada12b8c..f29fbd81 100644 --- a/16_Bug/csharp/Parts/Part.cs +++ b/16_Bug/csharp/Parts/Part.cs @@ -2,7 +2,7 @@ using BugGame.Resources; namespace BugGame.Parts; -internal class Part +internal class Part : IPart { private readonly Message _addedMessage; private readonly Message _duplicateMessage; diff --git a/16_Bug/csharp/Parts/PartCollection.cs b/16_Bug/csharp/Parts/PartCollection.cs index aac0bbd2..6e6034de 100644 --- a/16_Bug/csharp/Parts/PartCollection.cs +++ b/16_Bug/csharp/Parts/PartCollection.cs @@ -1,3 +1,4 @@ +using System.Text; using BugGame.Resources; namespace BugGame.Parts; @@ -23,11 +24,27 @@ internal class PartCollection if (_count < _maxCount) { _count++; - message = _addedMessage.ForQuantity(_count); + message = _addedMessage.ForValue(_count); return true; } message = _fullMessage; return false; } + + protected void AppendTo(StringBuilder builder, int offset, int length, char character) + { + if (_count == 0) { return; } + + builder.Append(' ', offset); + + for (var i = 0; i < length; i++) + { + for (var j = 0; j < _count; j++) + { + builder.Append(character).Append(' '); + } + builder.AppendLine(); + } + } } diff --git a/16_Bug/csharp/Parts/Tail.cs b/16_Bug/csharp/Parts/Tail.cs index ad610d81..8c450f1d 100644 --- a/16_Bug/csharp/Parts/Tail.cs +++ b/16_Bug/csharp/Parts/Tail.cs @@ -1,3 +1,4 @@ +using System.Text; using BugGame.Resources; namespace BugGame.Parts; @@ -8,4 +9,6 @@ internal class Tail : Part : base(Message.TailAdded, Message.TailNotNeeded) { } + + public void AppendTo(StringBuilder builder) => builder.AppendLine("TTTTTB B"); } \ No newline at end of file From 013baf71a2058c9403ae26041cf8dced651a7971 Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Wed, 13 Jul 2022 08:04:47 +1000 Subject: [PATCH 07/11] Add game loop --- 16_Bug/csharp/Game.cs | 56 +++++++++++++++++++++++++-- 16_Bug/csharp/Resources/Message.cs | 4 +- 16_Bug/csharp/Resources/PlayAgain.txt | 1 + 16_Bug/csharp/Resources/Resource.cs | 10 +---- 4 files changed, 59 insertions(+), 12 deletions(-) create mode 100644 16_Bug/csharp/Resources/PlayAgain.txt diff --git a/16_Bug/csharp/Game.cs b/16_Bug/csharp/Game.cs index c98c44f5..2b5c0711 100644 --- a/16_Bug/csharp/Game.cs +++ b/16_Bug/csharp/Game.cs @@ -1,7 +1,8 @@ +using BugGame.Parts; using BugGame.Resources; using Games.Common.IO; using Games.Common.Randomness; - +using static System.StringComparison; namespace BugGame; internal class Game @@ -18,10 +19,59 @@ internal class Game public void Play() { _io.Write(Resource.Streams.Introduction); - var response = _io.ReadString("Do you want instructions"); - if (!response.Equals("no", StringComparison.InvariantCultureIgnoreCase)) + if (!_io.ReadString("Do you want instructions").Equals("no", InvariantCultureIgnoreCase)) { _io.Write(Resource.Streams.Instructions); } + + BuildBugs(); + + _io.Write(Resource.Streams.PlayAgain); + } + + private void BuildBugs() + { + var yourBug = new Bug(); + var myBug = new Bug(); + + while (true) + { + if (TryBuild(yourBug, m => m.You) || TryBuild(myBug, m => m.I)) + { + if (yourBug.IsComplete) { _io.WriteLine(Message.Complete.You); } + if (myBug.IsComplete) { _io.WriteLine(Message.Complete.I); } + + if (!_io.ReadString("Do you want the picture").Equals("no", InvariantCultureIgnoreCase)) + { + _io.WriteLine(yourBug.ToString("Your", 'A')); + _io.WriteLine(myBug.ToString("My", 'F')); + } + } + + if (yourBug.IsComplete || myBug.IsComplete) { break; } + } + } + + private bool TryBuild(Bug bug, Func messageTransform) + { + var roll = _random.Next(6) + 1; + _io.WriteLine(messageTransform(Message.Rolled.ForValue(roll))); + + IPart part = roll switch + { + 1 => new Body(), + 2 => new Neck(), + 3 => new Head(), + 4 => new Feeler(), + 5 => new Tail(), + 6 => new Leg(), + _ => throw new Exception("Unexpected roll value") + }; + _io.WriteLine($"{roll}={part.GetType().Name}"); + + var partAdded = bug.TryAdd(part, out var message); + _io.WriteLine(messageTransform.Invoke(message)); + + return partAdded; } } \ No newline at end of file diff --git a/16_Bug/csharp/Resources/Message.cs b/16_Bug/csharp/Resources/Message.cs index be85faf8..4c719475 100644 --- a/16_Bug/csharp/Resources/Message.cs +++ b/16_Bug/csharp/Resources/Message.cs @@ -24,6 +24,8 @@ internal class Message public static Message LegAdded = new("now have {0} legs"); public static Message LegsFull = new("I have 6 feet.", "You have 6 feet already"); + public static Message Complete = new("bug is finished."); + private Message(string common) : this("I " + common, "You" + common) { @@ -40,5 +42,5 @@ internal class Message 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)); + public Message ForValue(int quantity) => new(string.Format(I, quantity), string.Format(You, quantity)); } \ No newline at end of file diff --git a/16_Bug/csharp/Resources/PlayAgain.txt b/16_Bug/csharp/Resources/PlayAgain.txt new file mode 100644 index 00000000..2380e130 --- /dev/null +++ b/16_Bug/csharp/Resources/PlayAgain.txt @@ -0,0 +1 @@ +I hope you enjoyed the game, play it again soon!! diff --git a/16_Bug/csharp/Resources/Resource.cs b/16_Bug/csharp/Resources/Resource.cs index 57f05438..2b34a4e6 100644 --- a/16_Bug/csharp/Resources/Resource.cs +++ b/16_Bug/csharp/Resources/Resource.cs @@ -9,17 +9,11 @@ internal static class Resource { public static Stream Introduction => GetStream(); public static Stream Instructions => GetStream(); - } - - private static string GetString([CallerMemberName] string? name = null) - { - using var stream = GetStream(name); - using var reader = new StreamReader(stream); - return reader.ReadToEnd(); + public static Stream PlayAgain => GetStream(); } private static Stream GetStream([CallerMemberName] string? name = null) => Assembly.GetExecutingAssembly() - .GetManifestResourceStream($"{typeof(Resource).Namespace}.{name}.txt") + .GetManifestResourceStream($"Bug.Resources.{name}.txt") ?? throw new Exception($"Could not find embedded resource stream '{name}'."); } \ No newline at end of file From a648ebf0441fd7aab1b6f8c03386ed6a4a7a3f75 Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Wed, 13 Jul 2022 08:15:46 +1000 Subject: [PATCH 08/11] Fix adding parts --- 16_Bug/csharp/Parts/ParentPart.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/16_Bug/csharp/Parts/ParentPart.cs b/16_Bug/csharp/Parts/ParentPart.cs index 78a21d6e..1ca6682f 100644 --- a/16_Bug/csharp/Parts/ParentPart.cs +++ b/16_Bug/csharp/Parts/ParentPart.cs @@ -10,7 +10,12 @@ internal abstract class ParentPart : Part } public bool TryAdd(IPart part, out Message message) - => IsPresent ? TryAddCore(part, out message) : ReportDoNotHave(out message); + => (part.GetType() == GetType(), IsPresent) switch + { + (true, _) => TryAdd(out message), + (false, false) => ReportDoNotHave(out message), + _ => TryAddCore(part, out message) + }; protected abstract bool TryAddCore(IPart part, out Message message); From 98344717f7514ea094936889ea9c70539da4e3b3 Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Thu, 14 Jul 2022 00:24:10 +1000 Subject: [PATCH 09/11] CSHARP-16 Fix printing bug --- 16_Bug/csharp/Parts/Body.cs | 21 ++++++++++++--------- 16_Bug/csharp/Parts/Head.cs | 19 +++++++++++-------- 16_Bug/csharp/Parts/Neck.cs | 7 +++++-- 16_Bug/csharp/Parts/Tail.cs | 8 +++++++- 4 files changed, 35 insertions(+), 20 deletions(-) diff --git a/16_Bug/csharp/Parts/Body.cs b/16_Bug/csharp/Parts/Body.cs index 2b7586dc..58f80405 100644 --- a/16_Bug/csharp/Parts/Body.cs +++ b/16_Bug/csharp/Parts/Body.cs @@ -28,14 +28,17 @@ internal class Body : ParentPart public void AppendTo(StringBuilder builder, char feelerCharacter) { - _neck.AppendTo(builder, feelerCharacter); - builder - .AppendLine(" BBBBBBBBBBBB") - .AppendLine(" B B") - .AppendLine(" B B"); - _tail.AppendTo(builder); - builder - .AppendLine(" BBBBBBBBBBBB"); - _legs.AppendTo(builder); + if (IsPresent) + { + _neck.AppendTo(builder, feelerCharacter); + builder + .AppendLine(" BBBBBBBBBBBB") + .AppendLine(" B B") + .AppendLine(" B B"); + _tail.AppendTo(builder); + builder + .AppendLine(" BBBBBBBBBBBB"); + _legs.AppendTo(builder); + } } } diff --git a/16_Bug/csharp/Parts/Head.cs b/16_Bug/csharp/Parts/Head.cs index 3bab7caa..d7135575 100644 --- a/16_Bug/csharp/Parts/Head.cs +++ b/16_Bug/csharp/Parts/Head.cs @@ -23,13 +23,16 @@ internal class Head : ParentPart public void AppendTo(StringBuilder builder, char feelerCharacter) { - _feelers.AppendTo(builder, feelerCharacter); - builder - .AppendLine(" HHHHHHH") - .AppendLine(" H H") - .AppendLine(" H O O H") - .AppendLine(" H H") - .AppendLine(" H V H") - .AppendLine(" HHHHHHH"); + if (IsPresent) + { + _feelers.AppendTo(builder, feelerCharacter); + builder + .AppendLine(" HHHHHHH") + .AppendLine(" H H") + .AppendLine(" H O O H") + .AppendLine(" H H") + .AppendLine(" H V H") + .AppendLine(" HHHHHHH"); + } } } diff --git a/16_Bug/csharp/Parts/Neck.cs b/16_Bug/csharp/Parts/Neck.cs index e8976c1c..23dacfb7 100644 --- a/16_Bug/csharp/Parts/Neck.cs +++ b/16_Bug/csharp/Parts/Neck.cs @@ -24,7 +24,10 @@ internal class Neck : ParentPart public void AppendTo(StringBuilder builder, char feelerCharacter) { - _head.AppendTo(builder, feelerCharacter); - builder.AppendLine(" N N").AppendLine(" N N"); + if (IsPresent) + { + _head.AppendTo(builder, feelerCharacter); + builder.AppendLine(" N N").AppendLine(" N N"); + } } } diff --git a/16_Bug/csharp/Parts/Tail.cs b/16_Bug/csharp/Parts/Tail.cs index 8c450f1d..ebf4b28f 100644 --- a/16_Bug/csharp/Parts/Tail.cs +++ b/16_Bug/csharp/Parts/Tail.cs @@ -10,5 +10,11 @@ internal class Tail : Part { } - public void AppendTo(StringBuilder builder) => builder.AppendLine("TTTTTB B"); + public void AppendTo(StringBuilder builder) + { + if (IsPresent) + { + builder.AppendLine("TTTTTB B"); + } + } } \ No newline at end of file From 6e47d7fbfd8a9a9a8e755fa7533c38744d906b10 Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Thu, 14 Jul 2022 00:39:17 +1000 Subject: [PATCH 10/11] Fix game loop and finished message --- 16_Bug/csharp/Game.cs | 11 ++++++++--- 16_Bug/csharp/Parts/PartCollection.cs | 4 ++-- 16_Bug/csharp/Resources/Message.cs | 4 ++-- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/16_Bug/csharp/Game.cs b/16_Bug/csharp/Game.cs index 2b5c0711..8ea1cecf 100644 --- a/16_Bug/csharp/Game.cs +++ b/16_Bug/csharp/Game.cs @@ -36,10 +36,15 @@ internal class Game while (true) { - if (TryBuild(yourBug, m => m.You) || TryBuild(myBug, m => m.I)) + var partAdded = TryBuild(yourBug, m => m.You); + Thread.Sleep(500); + _io.WriteLine(); + partAdded |= TryBuild(myBug, m => m.I); + + if (partAdded) { - if (yourBug.IsComplete) { _io.WriteLine(Message.Complete.You); } - if (myBug.IsComplete) { _io.WriteLine(Message.Complete.I); } + if (yourBug.IsComplete) { _io.WriteLine("Your bug is finished."); } + if (myBug.IsComplete) { _io.WriteLine("My bug is finished."); } if (!_io.ReadString("Do you want the picture").Equals("no", InvariantCultureIgnoreCase)) { diff --git a/16_Bug/csharp/Parts/PartCollection.cs b/16_Bug/csharp/Parts/PartCollection.cs index 6e6034de..9a0fd2ee 100644 --- a/16_Bug/csharp/Parts/PartCollection.cs +++ b/16_Bug/csharp/Parts/PartCollection.cs @@ -36,10 +36,10 @@ internal class PartCollection { if (_count == 0) { return; } - builder.Append(' ', offset); - for (var i = 0; i < length; i++) { + builder.Append(' ', offset); + for (var j = 0; j < _count; j++) { builder.Append(character).Append(' '); diff --git a/16_Bug/csharp/Resources/Message.cs b/16_Bug/csharp/Resources/Message.cs index 4c719475..20a59d9a 100644 --- a/16_Bug/csharp/Resources/Message.cs +++ b/16_Bug/csharp/Resources/Message.cs @@ -27,7 +27,7 @@ internal class Message public static Message Complete = new("bug is finished."); private Message(string common) - : this("I " + common, "You" + common) + : this("I " + common, "You " + common) { } @@ -40,7 +40,7 @@ internal class Message public string I { get; } public string You { get; } - public static Message DoNotHaveA(Part part) => new($"do no have a {part.Name}"); + public static Message DoNotHaveA(Part part) => new($"do not have a {part.Name}"); public Message ForValue(int quantity) => new(string.Format(I, quantity), string.Format(You, quantity)); } \ No newline at end of file From 8f09273ab72f5a9296547fac0092f061f35b5500 Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Thu, 14 Jul 2022 00:41:36 +1000 Subject: [PATCH 11/11] Add print gap --- 16_Bug/csharp/Game.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/16_Bug/csharp/Game.cs b/16_Bug/csharp/Game.cs index 8ea1cecf..a8989a4c 100644 --- a/16_Bug/csharp/Game.cs +++ b/16_Bug/csharp/Game.cs @@ -48,8 +48,12 @@ internal class Game if (!_io.ReadString("Do you want the picture").Equals("no", InvariantCultureIgnoreCase)) { - _io.WriteLine(yourBug.ToString("Your", 'A')); - _io.WriteLine(myBug.ToString("My", 'F')); + _io.Write(yourBug.ToString("Your", 'A')); + _io.WriteLine(); + _io.WriteLine(); + _io.WriteLine(); + _io.WriteLine(); + _io.Write(myBug.ToString("My", 'F')); } }