Merge pull request #787 from drewjcooper/csharp-67-one-check

C# 67 one check
This commit is contained in:
Jeff Atwood
2022-08-25 14:41:01 -07:00
committed by GitHub
14 changed files with 220 additions and 0 deletions
+64
View File
@@ -0,0 +1,64 @@
namespace OneCheck;
internal class Board
{
private readonly bool[][] _checkers;
private int _pieceCount;
private int _moveCount;
public Board()
{
_checkers =
Enumerable.Range(0, 8)
.Select(r => Enumerable.Range(0, 8)
.Select(c => r <= 1 || r >= 6 || c <= 1 || c >= 6).ToArray())
.ToArray();
_pieceCount = 48;
}
private bool this[int index]
{
get => _checkers[index / 8][index % 8];
set => _checkers[index / 8][index % 8] = value;
}
public bool PlayMove(IReadWrite io)
{
while (true)
{
var from = (int)io.ReadNumber(Prompts.From);
if (from == 0) { return false; }
var move = new Move { From = from - 1, To = (int)io.ReadNumber(Prompts.To) - 1 };
if (TryMove(move))
{
_moveCount++;
return true;
}
io.Write(Streams.IllegalMove);
}
}
public bool TryMove(Move move)
{
if (move.IsInRange && move.IsTwoSpacesDiagonally && IsPieceJumpingPieceToEmptySpace(move))
{
this[move.From] = false;
this[move.Jumped] = false;
this[move.To] = true;
_pieceCount--;
return true;
}
return false;
}
private bool IsPieceJumpingPieceToEmptySpace(Move move) => this[move.From] && this[move.Jumped] && !this[move.To];
public string GetReport() => string.Format(Formats.Results, _moveCount, _pieceCount);
public override string ToString() =>
string.Join(Environment.NewLine, _checkers.Select(r => string.Join(" ", r.Select(c => c ? " 1" : " 0"))));
}
+45
View File
@@ -0,0 +1,45 @@
namespace OneCheck;
internal class Game
{
private readonly IReadWrite _io;
public Game(IReadWrite io)
{
_io = io;
}
public void Play()
{
_io.Write(Streams.Introduction);
do
{
var board = new Board();
do
{
_io.WriteLine(board);
_io.WriteLine();
} while (board.PlayMove(_io));
_io.WriteLine(board.GetReport());
} while (_io.ReadYesNo(Prompts.TryAgain) == "yes");
_io.Write(Streams.Bye);
}
}
internal static class IOExtensions
{
internal static string ReadYesNo(this IReadWrite io, string prompt)
{
while (true)
{
var response = io.ReadString(prompt).ToLower();
if (response == "yes" || response == "no") { return response; }
io.Write(Streams.YesOrNo);
}
}
}
+13
View File
@@ -0,0 +1,13 @@
namespace OneCheck;
internal class Move
{
public int From { get; init; }
public int To { get; init; }
public int Jumped => (From + To) / 2;
public bool IsInRange => From >= 0 && From <= 63 && To >= 0 && To <= 63;
public bool IsTwoSpacesDiagonally => RowDelta == 2 && ColumnDelta == 2;
private int RowDelta => Math.Abs(From / 8 - To / 8);
private int ColumnDelta => Math.Abs(From % 8 - To % 8);
}
+8
View File
@@ -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>
+5
View File
@@ -0,0 +1,5 @@
global using Games.Common.IO;
global using static OneCheck.Resources.Resource;
using OneCheck;
new Game(new ConsoleIO()).Play();
+2
View File
@@ -0,0 +1,2 @@
O.K. Hope you had fun!!
+1
View File
@@ -0,0 +1 @@
Jump from
@@ -0,0 +1 @@
Illegal move. Try again...
@@ -0,0 +1,30 @@
One Check
Creative Computing Morristown, New Jersey
Solitaire checker puzzle by David Ahl
48 checkers and placed on the 2 outside spaces of a
standard 64-square checkerboard. The object is to
remove as many checkers as possible by diagonal jumps
(as in standard checkers). Use the numbered board to
indicate the square you wish to jump from and to. On
the board printed out on each turn '1' indicates a
checker and '0' an empty square. When you have no
possible jumps remaining, input a '0' in response to
question 'Jump from ?'
Here is the numerical board:
1 2 3 4 5 6 7 8
9 10 11 12 13 14 15 16
17 18 19 20 21 22 23 24
25 26 27 28 29 30 31 32
33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48
49 50 51 52 53 54 55 56
57 58 59 60 61 62 63 64
And here is the opening position of the checkers.
+45
View File
@@ -0,0 +1,45 @@
using System.Reflection;
using System.Runtime.CompilerServices;
namespace OneCheck.Resources;
internal static class Resource
{
internal static class Streams
{
public static Stream Introduction => GetStream();
public static Stream IllegalMove => GetStream();
public static Stream YesOrNo => GetStream();
public static Stream Bye => GetStream();
}
internal static class Formats
{
public static string Results => GetString();
}
internal static class Prompts
{
public static string From => GetString();
public static string To => GetString();
public static string TryAgain => GetString();
}
internal static class Strings
{
public static string TooManyColumns => GetString();
public static string TooManyRows => 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}'.");
}
@@ -0,0 +1,3 @@
You made {0} jumps and had {1} pieces
remaining on the board.
+1
View File
@@ -0,0 +1 @@
to
@@ -0,0 +1 @@
Try again
@@ -0,0 +1 @@
Please answer 'Yes' or 'No'.