mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-27 05:03:27 -08:00
78
41_Guess/csharp/Game.cs
Normal file
78
41_Guess/csharp/Game.cs
Normal file
@@ -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)
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -6,4 +6,12 @@
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Resources/*.txt" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\00_Common\dotnet\Games.Common\Games.Common.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
7
41_Guess/csharp/Program.cs
Normal file
7
41_Guess/csharp/Program.cs
Normal file
@@ -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();
|
||||
5
41_Guess/csharp/Resources/BlankLines.txt
Normal file
5
41_Guess/csharp/Resources/BlankLines.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
1
41_Guess/csharp/Resources/Good.txt
Normal file
1
41_Guess/csharp/Resources/Good.txt
Normal file
@@ -0,0 +1 @@
|
||||
Good.
|
||||
9
41_Guess/csharp/Resources/Introduction.txt
Normal file
9
41_Guess/csharp/Resources/Introduction.txt
Normal file
@@ -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.
|
||||
|
||||
1
41_Guess/csharp/Resources/Limit.txt
Normal file
1
41_Guess/csharp/Resources/Limit.txt
Normal file
@@ -0,0 +1 @@
|
||||
What limit do you want
|
||||
44
41_Guess/csharp/Resources/Resource.cs
Normal file
44
41_Guess/csharp/Resources/Resource.cs
Normal file
@@ -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}'.");
|
||||
}
|
||||
1
41_Guess/csharp/Resources/ShouldHave.txt
Normal file
1
41_Guess/csharp/Resources/ShouldHave.txt
Normal file
@@ -0,0 +1 @@
|
||||
You should have been able to get it in only {0}
|
||||
1
41_Guess/csharp/Resources/ThatsIt.txt
Normal file
1
41_Guess/csharp/Resources/ThatsIt.txt
Normal file
@@ -0,0 +1 @@
|
||||
That's it! You got it in {0} tries.
|
||||
2
41_Guess/csharp/Resources/Thinking.txt
Normal file
2
41_Guess/csharp/Resources/Thinking.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
I'm thinking of a number between 1 and {0}
|
||||
Now you try to guess what it is.
|
||||
1
41_Guess/csharp/Resources/TooHigh.txt
Normal file
1
41_Guess/csharp/Resources/TooHigh.txt
Normal file
@@ -0,0 +1 @@
|
||||
Too high. Try a smaller answer.
|
||||
1
41_Guess/csharp/Resources/TooLow.txt
Normal file
1
41_Guess/csharp/Resources/TooLow.txt
Normal file
@@ -0,0 +1 @@
|
||||
Too low. Try a bigger answer.
|
||||
1
41_Guess/csharp/Resources/VeryGood.txt
Normal file
1
41_Guess/csharp/Resources/VeryGood.txt
Normal file
@@ -0,0 +1 @@
|
||||
Very good.
|
||||
Reference in New Issue
Block a user