Update 82_Stars with common library

This commit is contained in:
Andrew Cooper
2022-03-20 17:19:29 +11:00
parent d6ddc6bf9e
commit 4fb62ce30c
9 changed files with 147 additions and 134 deletions

View File

@@ -94,6 +94,13 @@ public interface IReadWrite
/// <param name="value">The <see cref="object" /> to be written.</param> /// <param name="value">The <see cref="object" /> to be written.</param>
void WriteLine(object value); void WriteLine(object value);
/// <summary>
/// Writes a formatted string to output.
/// </summary>
/// <param name="format">The format <see cref="string" /> to be written.</param>
/// <param name="value">The values to be inserted into the format.</param>
void WriteLine(string format, params object[] values);
/// <summary> /// <summary>
/// Writes the contents of a <see cref="Stream" /> to output. /// Writes the contents of a <see cref="Stream" /> to output.
/// </summary> /// </summary>

View File

@@ -99,6 +99,8 @@ public class TextIO : IReadWrite
public void WriteLine(object value) => _output.WriteLine(value.ToString()); public void WriteLine(object value) => _output.WriteLine(value.ToString());
public void WriteLine(string format, params object[] values) => _output.WriteLine(format, values);
public void Write(Stream stream, bool keepOpen = false) public void Write(Stream stream, bool keepOpen = false)
{ {
using var reader = new StreamReader(stream); using var reader = new StreamReader(stream);

View File

@@ -1,94 +1,105 @@
using System; using System;
using Games.Common.IO;
using Games.Common.Randomness;
using Stars.Resources;
namespace Stars namespace Stars;
internal class Game
{ {
internal class Game private readonly TextIO _io;
{ private readonly IRandom _random;
private readonly int _maxNumber; private readonly int _maxNumber;
private readonly int _maxGuessCount; private readonly int _maxGuessCount;
private readonly Random _random;
public Game(int maxNumber, int maxGuessCount) public Game(TextIO io, IRandom random, int maxNumber, int maxGuessCount)
{
_io = io;
_random = random;
_maxNumber = maxNumber;
_maxGuessCount = maxGuessCount;
}
internal void Play(Func<bool> playAgain)
{
DisplayIntroduction();
do
{ {
_maxNumber = maxNumber; Play();
_maxGuessCount = maxGuessCount; } while (playAgain.Invoke());
_random = new Random(); }
private void DisplayIntroduction()
{
_io.Write(Resource.Streams.Title);
if (_io.ReadString("Do you want instructions").Equals("N", StringComparison.InvariantCultureIgnoreCase))
{
return;
} }
internal void DisplayInstructions() _io.WriteLine(Resource.Formats.Instructions, _maxNumber, _maxGuessCount);
}
private void Play()
{
_io.WriteLine();
_io.WriteLine();
var target = _random.Next(_maxNumber) + 1;
_io.WriteLine("Ok, I am thinking of a number. Start guessing.");
AcceptGuesses(target);
}
private void AcceptGuesses(int target)
{
for (int guessCount = 1; guessCount <= _maxGuessCount; guessCount++)
{ {
if (Input.GetString("Do you want instructions? ").Equals("N", StringComparison.InvariantCultureIgnoreCase)) _io.WriteLine();
var guess = _io.ReadNumber("Your guess");
if (guess == target)
{ {
DisplayWin(guessCount);
return; return;
} }
Console.WriteLine($"I am thinking of a number between 1 and {_maxNumber}."); DisplayStars(target, guess);
Console.WriteLine("Try to guess my number. After you guess, I");
Console.WriteLine("will type one or more stars (*). The more");
Console.WriteLine("stars I type, the close you are to my number.");
Console.WriteLine("One star (*) means far away, seven stars (*******)");
Console.WriteLine($"means really close! You get {_maxGuessCount} guesses.");
} }
internal void Play() DisplayLoss(target);
}
private void DisplayStars(int target, float guess)
{
var stars = Math.Abs(guess - target) switch
{ {
Console.WriteLine(); >= 64 => "*",
Console.WriteLine(); >= 32 => "**",
>= 16 => "***",
>= 8 => "****",
>= 4 => "*****",
>= 2 => "******",
_ => "*******"
};
var target = _random.Next(_maxNumber) + 1; _io.WriteLine(stars);
}
Console.WriteLine("Ok, I am thinking of a number. Start guessing."); private void DisplayWin(int guessCount)
{
_io.WriteLine();
_io.WriteLine(new string('*', 79));
_io.WriteLine();
_io.WriteLine($"You got it in {guessCount} guesses!!! Let's play again...");
}
AcceptGuesses(target); private void DisplayLoss(int target)
} {
_io.WriteLine();
private void AcceptGuesses(int target) _io.WriteLine($"Sorry, that's {_maxGuessCount} guesses. The number was {target}.");
{
for (int guessCount = 1; guessCount <= _maxGuessCount; guessCount++)
{
Console.WriteLine();
var guess = Input.GetNumber("Your guess? ");
if (guess == target)
{
DisplayWin(guessCount);
return;
}
DisplayStars(target, guess);
}
DisplayLoss(target);
}
private static void DisplayStars(int target, float guess)
{
var stars = Math.Abs(guess - target) switch
{
>= 64 => "*",
>= 32 => "**",
>= 16 => "***",
>= 8 => "****",
>= 4 => "*****",
>= 2 => "******",
_ => "*******"
};
Console.WriteLine(stars);
}
private static void DisplayWin(int guessCount)
{
Console.WriteLine();
Console.WriteLine(new string('*', 79));
Console.WriteLine();
Console.WriteLine($"You got it in {guessCount} guesses!!! Let's play again...");
}
private void DisplayLoss(int target)
{
Console.WriteLine();
Console.WriteLine($"Sorry, that's {_maxGuessCount} guesses. The number was {target}.");
}
} }
} }

View File

@@ -1,31 +0,0 @@
using System;
namespace Stars
{
internal static class Input
{
// Float, because that's what the BASIC input operation returns
internal static float GetNumber(string prompt)
{
Console.Write(prompt);
while (true)
{
var response = Console.ReadLine();
if (float.TryParse(response, out var value))
{
return value;
}
Console.WriteLine("!Number expected - retry input line");
Console.Write("? ");
}
}
internal static string GetString(string prompt)
{
Console.Write(prompt);
return Console.ReadLine();
}
}
}

View File

@@ -1,30 +1,7 @@
using System; using Games.Common.IO;
using Games.Common.Randomness;
using Stars;
namespace Stars var game = new Game(new ConsoleIO(), new RandomNumberGenerator(), maxNumber: 100, maxGuessCount: 7);
{
class Program
{
static void Main(string[] args)
{
DisplayTitle();
var game = new Game(maxNumber: 100, maxGuessCount: 7); game.Play(() => true);
game.DisplayInstructions();
while (true)
{
game.Play();
}
}
private static void DisplayTitle()
{
Console.WriteLine(" Stars");
Console.WriteLine(" Creative Computing Morristown, New Jersey");
Console.WriteLine();
Console.WriteLine();
Console.WriteLine();
}
}
}

View File

@@ -0,0 +1,6 @@
I am thinking of a number between 1 and {0}.
Try to guess my number. After you guess, I
will type one or more stars (*). The more
stars I type, the closer you are to my number.
One star (*) means far away, seven stars (*******)
means really close! You get {1} guesses.

View File

@@ -0,0 +1,28 @@
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
namespace Stars.Resources;
internal static class Resource
{
internal static class Streams
{
public static Stream Title => GetStream();
}
internal static class Formats
{
public static string Instructions => 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($"Stars.Resources.{name}.txt");
}

View File

@@ -0,0 +1,5 @@
Stars
Creative Computing Morristown, New Jersey

View File

@@ -2,7 +2,15 @@
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<EmbeddedResource Include="Resources/*.txt" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\00_Common\dotnet\Games.Common\Games.Common.csproj" />
</ItemGroup>
</Project> </Project>