diff --git a/41_Guess/csharp/Game.cs b/41_Guess/csharp/Game.cs new file mode 100644 index 00000000..57ae071a --- /dev/null +++ b/41_Guess/csharp/Game.cs @@ -0,0 +1,78 @@ +namespace Guess; + +internal class Game +{ + private readonly IReadWrite _io; + private readonly IRandom _random; + + public Game(IReadWrite io, IRandom random) + { + _io = io; + _random = random; + } + + public void Play() + { + while (true) + { + _io.Write(Streams.Introduction); + + var limit = _io.ReadNumber(Prompts.Limit); + _io.WriteLine(); + + // There's a bug here that exists in the original code. + // If the limit entered is <= 0 then the program will crash. + var targetGuessCount = checked((int)Math.Log2(limit) + 1); + + PlayGuessingRounds(limit, targetGuessCount); + + _io.Write(Streams.BlankLines); + } + } + + private void PlayGuessingRounds(float limit, int targetGuessCount) + { + while (true) + { + _io.WriteLine(Formats.Thinking, limit); + + // There's a bug here that exists in the original code. If a non-integer is entered as the limit + // then it's possible for the secret number to be the next integer greater than the limit. + var secretNumber = (int)_random.NextFloat(limit) + 1; + + var guessCount = 0; + + while (true) + { + var guess = _io.ReadNumber(""); + if (guess <= 0) { return; } + guessCount++; + if (IsGuessCorrect(guess, secretNumber)) { break; } + } + + ReportResult(guessCount, targetGuessCount); + + _io.Write(Streams.BlankLines); + } + } + + private bool IsGuessCorrect(float guess, int secretNumber) + { + if (guess < secretNumber) { _io.Write(Streams.TooLow); } + if (guess > secretNumber) { _io.Write(Streams.TooHigh); } + + return guess == secretNumber; + } + + private void ReportResult(int guessCount, int targetGuessCount) + { + _io.WriteLine(Formats.ThatsIt, guessCount); + _io.WriteLine( + (guessCount - targetGuessCount) switch + { + < 0 => Strings.VeryGood, + 0 => Strings.Good, + > 0 => string.Format(Formats.ShouldHave, targetGuessCount) + }); + } +} \ No newline at end of file diff --git a/41_Guess/csharp/Guess.csproj b/41_Guess/csharp/Guess.csproj index d3fe4757..3870320c 100644 --- a/41_Guess/csharp/Guess.csproj +++ b/41_Guess/csharp/Guess.csproj @@ -6,4 +6,12 @@ enable enable + + + + + + + + diff --git a/41_Guess/csharp/Program.cs b/41_Guess/csharp/Program.cs new file mode 100644 index 00000000..73ab09dd --- /dev/null +++ b/41_Guess/csharp/Program.cs @@ -0,0 +1,7 @@ +global using Games.Common.IO; +global using Games.Common.Randomness; +global using static Guess.Resources.Resource; + +using Guess; + +new Game(new ConsoleIO(), new RandomNumberGenerator()).Play(); diff --git a/41_Guess/csharp/Resources/BlankLines.txt b/41_Guess/csharp/Resources/BlankLines.txt new file mode 100644 index 00000000..3f2ff2d6 --- /dev/null +++ b/41_Guess/csharp/Resources/BlankLines.txt @@ -0,0 +1,5 @@ + + + + + diff --git a/41_Guess/csharp/Resources/Good.txt b/41_Guess/csharp/Resources/Good.txt new file mode 100644 index 00000000..989dfa38 --- /dev/null +++ b/41_Guess/csharp/Resources/Good.txt @@ -0,0 +1 @@ +Good. \ No newline at end of file diff --git a/41_Guess/csharp/Resources/Introduction.txt b/41_Guess/csharp/Resources/Introduction.txt new file mode 100644 index 00000000..ed679492 --- /dev/null +++ b/41_Guess/csharp/Resources/Introduction.txt @@ -0,0 +1,9 @@ + Guess + Creative Computing Morristown, New Jersey + + + +This is a number guessing game. I'll think +of a number between 1 and any limit you want. +The you have to guess what it is. + diff --git a/41_Guess/csharp/Resources/Limit.txt b/41_Guess/csharp/Resources/Limit.txt new file mode 100644 index 00000000..62e698a6 --- /dev/null +++ b/41_Guess/csharp/Resources/Limit.txt @@ -0,0 +1 @@ +What limit do you want \ No newline at end of file diff --git a/41_Guess/csharp/Resources/Resource.cs b/41_Guess/csharp/Resources/Resource.cs new file mode 100644 index 00000000..d42477e2 --- /dev/null +++ b/41_Guess/csharp/Resources/Resource.cs @@ -0,0 +1,44 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +namespace Guess.Resources; + +internal static class Resource +{ + internal static class Streams + { + public static Stream Introduction => GetStream(); + public static Stream TooLow => GetStream(); + public static Stream TooHigh => GetStream(); + public static Stream BlankLines => GetStream(); + } + + internal static class Formats + { + public static string Thinking => GetString(); + public static string ThatsIt => GetString(); + public static string ShouldHave => GetString(); + } + + internal static class Prompts + { + public static string Limit => GetString(); + } + + internal static class Strings + { + public static string Good => GetString(); + public static string VeryGood => GetString(); + } + + 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($"{typeof(Resource).Namespace}.{name}.txt") + ?? throw new Exception($"Could not find embedded resource stream '{name}'."); +} \ No newline at end of file diff --git a/41_Guess/csharp/Resources/ShouldHave.txt b/41_Guess/csharp/Resources/ShouldHave.txt new file mode 100644 index 00000000..84803588 --- /dev/null +++ b/41_Guess/csharp/Resources/ShouldHave.txt @@ -0,0 +1 @@ +You should have been able to get it in only {0} \ No newline at end of file diff --git a/41_Guess/csharp/Resources/ThatsIt.txt b/41_Guess/csharp/Resources/ThatsIt.txt new file mode 100644 index 00000000..61f78c43 --- /dev/null +++ b/41_Guess/csharp/Resources/ThatsIt.txt @@ -0,0 +1 @@ +That's it! You got it in {0} tries. \ No newline at end of file diff --git a/41_Guess/csharp/Resources/Thinking.txt b/41_Guess/csharp/Resources/Thinking.txt new file mode 100644 index 00000000..8f1bbac7 --- /dev/null +++ b/41_Guess/csharp/Resources/Thinking.txt @@ -0,0 +1,2 @@ +I'm thinking of a number between 1 and {0} +Now you try to guess what it is. \ No newline at end of file diff --git a/41_Guess/csharp/Resources/TooHigh.txt b/41_Guess/csharp/Resources/TooHigh.txt new file mode 100644 index 00000000..bb4ee4ed --- /dev/null +++ b/41_Guess/csharp/Resources/TooHigh.txt @@ -0,0 +1 @@ +Too high. Try a smaller answer. \ No newline at end of file diff --git a/41_Guess/csharp/Resources/TooLow.txt b/41_Guess/csharp/Resources/TooLow.txt new file mode 100644 index 00000000..4bc1776f --- /dev/null +++ b/41_Guess/csharp/Resources/TooLow.txt @@ -0,0 +1 @@ +Too low. Try a bigger answer. \ No newline at end of file diff --git a/41_Guess/csharp/Resources/VeryGood.txt b/41_Guess/csharp/Resources/VeryGood.txt new file mode 100644 index 00000000..606150c7 --- /dev/null +++ b/41_Guess/csharp/Resources/VeryGood.txt @@ -0,0 +1 @@ +Very good. \ No newline at end of file