Update 62_Mugwump

This commit is contained in:
Andrew Cooper
2022-03-13 19:16:41 +11:00
parent 84c4741dd1
commit 455fea9609
12 changed files with 146 additions and 190 deletions

View File

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

View File

@@ -0,0 +1,13 @@
namespace Mugwump;
internal struct Distance
{
private readonly float _value;
public Distance(float deltaX, float deltaY)
{
_value = (float)Math.Sqrt(deltaX * deltaX + deltaY * deltaY);
}
public override string ToString() => _value.ToString("0.0");
}

View File

@@ -1,36 +1,55 @@
using System;
using System.Linq;
using System.Reflection;
namespace Mugwump
namespace Mugwump;
internal class Game
{
internal class Game
private readonly TextIO _io;
private readonly IRandom _random;
internal Game(TextIO io, IRandom random)
{
private readonly Grid _grid;
_io = io;
_random = random;
}
private Game(Random random)
internal void Play(Func<bool> playAgain = null)
{
DisplayIntro();
while (playAgain?.Invoke() ?? true)
{
_grid = new Grid(Enumerable.Range(1, 4).Select(id => new Mugwump(id, random.Next(10), random.Next(10))));
}
Play(new Grid(_io, _random));
public static void Play(Random random) => new Game(random).Play();
private void Play()
{
for (int turn = 1; turn <= 10; turn++)
{
var guess = Input.ReadGuess($"Turn no. {turn} -- what is your guess");
if (_grid.Check(guess))
{
Console.WriteLine();
Console.WriteLine($"You got them all in {turn} turns!");
return;
}
}
Console.WriteLine();
Console.WriteLine("Sorry, that's 10 tries. Here is where they're hiding:");
_grid.Reveal();
_io.WriteLine();
_io.WriteLine("That was fun! Let's play again.......");
_io.WriteLine("Four more mugwumps are now in hiding.");
}
}
private void DisplayIntro()
{
using var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Mugwump.Strings.Intro.txt");
_io.Write(stream);
}
private void Play(Grid grid)
{
for (int turn = 1; turn <= 10; turn++)
{
var guess = _io.ReadGuess($"Turn no. {turn} -- what is your guess");
if (grid.Check(guess))
{
_io.WriteLine();
_io.WriteLine($"You got them all in {turn} turns!");
return;
}
}
_io.WriteLine();
_io.WriteLine("Sorry, that's 10 tries. Here is where they're hiding:");
grid.Reveal();
}
}

View File

@@ -1,40 +1,40 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Mugwump
namespace Mugwump;
internal class Grid
{
internal class Grid
private readonly TextIO _io;
private readonly List<Mugwump> _mugwumps;
public Grid(TextIO io, IRandom random)
{
private readonly List<Mugwump> _mugwumps;
_io = io;
_mugwumps = Enumerable.Range(1, 4).Select(id => new Mugwump(id, random.NextPosition(10, 10))).ToList();
}
public Grid(IEnumerable<Mugwump> mugwumps)
public bool Check(Position guess)
{
foreach (var mugwump in _mugwumps.ToList())
{
_mugwumps = mugwumps.ToList();
var (found, distance) = mugwump.FindFrom(guess);
_io.WriteLine(found ? $"You have found {mugwump}" : $"You are {distance} units from {mugwump}");
if (found)
{
_mugwumps.Remove(mugwump);
}
}
public bool Check(Position guess)
return _mugwumps.Count == 0;
}
public void Reveal()
{
foreach (var mugwump in _mugwumps)
{
foreach (var mugwump in _mugwumps.ToList())
{
var (found, distance) = mugwump.FindFrom(guess);
Console.WriteLine(found ? $"You have found {mugwump}" : $"You are {distance} units from {mugwump}");
if (found)
{
_mugwumps.Remove(mugwump);
}
}
return _mugwumps.Count == 0;
}
public void Reveal()
{
foreach (var mugwump in _mugwumps.ToList())
{
Console.WriteLine(mugwump.Reveal());
}
_io.WriteLine(mugwump.Reveal());
}
}
}

View File

@@ -0,0 +1,7 @@
namespace Mugwump;
internal static class IRandomExtensions
{
internal static Position NextPosition(this IRandom random, int maxX, int maxY) =>
new(random.Next(maxX), random.Next(maxY));
}

View File

@@ -1,66 +0,0 @@
using System;
using System.Collections.Generic;
namespace Mugwump
{
// Provides input methods which emulate the BASIC interpreter's keyboard input routines
internal static class Input
{
internal static Position ReadGuess(string prompt)
{
Console.WriteLine();
Console.WriteLine();
var input = ReadNumbers(prompt, 2);
return new Position(input[0], input[1]);
}
private static void Prompt(string text = "") => Console.Write($"{text}? ");
private static List<float> ReadNumbers(string prompt, int requiredCount)
{
var numbers = new List<float>();
while (!TryReadNumbers(prompt, requiredCount, numbers))
{
prompt = "";
}
return numbers;
}
private static bool TryReadNumbers(string prompt, int requiredCount, List<float> numbers)
{
Prompt(prompt);
var inputValues = ReadStrings();
foreach (var value in inputValues)
{
if (numbers.Count == requiredCount)
{
Console.WriteLine("!Extra input ingored");
return true;
}
if (!TryParseNumber(value, out var number))
{
return false;
}
numbers.Add(number);
}
return numbers.Count == requiredCount || TryReadNumbers("?", requiredCount, numbers);
}
private static string[] ReadStrings() => Console.ReadLine().Split(',', StringSplitOptions.TrimEntries);
private static bool TryParseNumber(string text, out float number)
{
if (float.TryParse(text, out number)) { return true; }
Console.WriteLine("!Number expected - retry input line");
number = default;
return false;
}
}
}

View File

@@ -1,20 +1,19 @@
namespace Mugwump
namespace Mugwump;
internal class Mugwump
{
internal class Mugwump
private readonly int _id;
private readonly Position _position;
public Mugwump(int id, Position position)
{
private readonly int _id;
private readonly Position _position;
public Mugwump(int id, int x, int y)
{
_id = id;
_position = new Position(x, y);
}
public (bool, Distance) FindFrom(Position guess) => (guess == _position, guess - _position);
public string Reveal() => $"{this} is at {_position}";
public override string ToString() => $"Mugwump {_id}";
_id = id;
_position = position;
}
public (bool, Distance) FindFrom(Position guess) => (guess == _position, guess - _position);
public string Reveal() => $"{this} is at {_position}";
public override string ToString() => $"Mugwump {_id}";
}

View File

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

View File

@@ -1,16 +0,0 @@
using System;
namespace Mugwump
{
internal class Distance
{
private readonly float _value;
public Distance(float deltaX, float deltaY)
{
_value = (float)Math.Sqrt(deltaX * deltaX + deltaY * deltaY);
}
public override string ToString() => $"{_value:0.0}";
}
}

View File

@@ -1,9 +1,8 @@
namespace Mugwump
{
internal record Position(float X, float Y)
{
public override string ToString() => $"( {X} , {Y} )";
namespace Mugwump;
public static Distance operator -(Position p1, Position p2) => new(p1.X - p2.X, p1.Y - p2.Y);
}
internal record struct Position(float X, float Y)
{
public override string ToString() => $"( {X} , {Y} )";
public static Distance operator -(Position p1, Position p2) => new(p1.X - p2.X, p1.Y - p2.Y);
}

View File

@@ -1,33 +1,12 @@
using System;
using System.Reflection;
global using System;
global using Games.Common.IO;
global using Games.Common.Randomness;
namespace Mugwump
{
class Program
{
static void Main(string[] args)
{
DisplayIntro();
using Mugwump;
var random = new Random();
var random = new RandomNumberGenerator();
var io = new ConsoleIO();
while (true)
{
Game.Play(random);
var game = new Game(io, random);
Console.WriteLine();
Console.WriteLine("That was fun! Let's play again.......");
Console.WriteLine("Four more mugwumps are now in hiding.");
}
}
private static void DisplayIntro()
{
using var stream = Assembly.GetExecutingAssembly()
.GetManifestResourceStream("Mugwump.Strings.Intro.txt");
using var stdout = Console.OpenStandardOutput();
stream.CopyTo(stdout);
}
}
}
game.Play();

View File

@@ -0,0 +1,13 @@
namespace Mugwump;
// Provides input methods which emulate the BASIC interpreter's keyboard input routines
internal static class TextIOExtensions
{
internal static Position ReadGuess(this TextIO io, string prompt)
{
io.WriteLine();
io.WriteLine();
var (x, y) = io.Read2Numbers(prompt);
return new Position(x, y);
}
}