From 7ab0e91c1f117338c06149d75e4b9bc2764aad4d Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Fri, 12 Aug 2022 17:28:49 +1000 Subject: [PATCH 1/4] Add resource strings --- 67_One_Check/csharp/OneCheck.csproj | 8 ++++ 67_One_Check/csharp/Resources/Bye.txt | 2 + 67_One_Check/csharp/Resources/From.txt | 1 + 67_One_Check/csharp/Resources/IllegalMove.txt | 1 + .../csharp/Resources/Introduction.txt | 29 ++++++++++++ 67_One_Check/csharp/Resources/Resource.cs | 45 +++++++++++++++++++ 67_One_Check/csharp/Resources/Results.txt | 4 ++ 67_One_Check/csharp/Resources/To.txt | 1 + 67_One_Check/csharp/Resources/TryAgain.txt | 1 + 67_One_Check/csharp/Resources/YesOrNo.txt | 1 + 10 files changed, 93 insertions(+) create mode 100644 67_One_Check/csharp/Resources/Bye.txt create mode 100644 67_One_Check/csharp/Resources/From.txt create mode 100644 67_One_Check/csharp/Resources/IllegalMove.txt create mode 100644 67_One_Check/csharp/Resources/Introduction.txt create mode 100644 67_One_Check/csharp/Resources/Resource.cs create mode 100644 67_One_Check/csharp/Resources/Results.txt create mode 100644 67_One_Check/csharp/Resources/To.txt create mode 100644 67_One_Check/csharp/Resources/TryAgain.txt create mode 100644 67_One_Check/csharp/Resources/YesOrNo.txt diff --git a/67_One_Check/csharp/OneCheck.csproj b/67_One_Check/csharp/OneCheck.csproj index d3fe4757..3870320c 100644 --- a/67_One_Check/csharp/OneCheck.csproj +++ b/67_One_Check/csharp/OneCheck.csproj @@ -6,4 +6,12 @@ enable enable + + + + + + + + diff --git a/67_One_Check/csharp/Resources/Bye.txt b/67_One_Check/csharp/Resources/Bye.txt new file mode 100644 index 00000000..ee4ddab1 --- /dev/null +++ b/67_One_Check/csharp/Resources/Bye.txt @@ -0,0 +1,2 @@ + +O.K. Hope you had fun!! \ No newline at end of file diff --git a/67_One_Check/csharp/Resources/From.txt b/67_One_Check/csharp/Resources/From.txt new file mode 100644 index 00000000..bb4c7a2d --- /dev/null +++ b/67_One_Check/csharp/Resources/From.txt @@ -0,0 +1 @@ +Jump from \ No newline at end of file diff --git a/67_One_Check/csharp/Resources/IllegalMove.txt b/67_One_Check/csharp/Resources/IllegalMove.txt new file mode 100644 index 00000000..a96b6e81 --- /dev/null +++ b/67_One_Check/csharp/Resources/IllegalMove.txt @@ -0,0 +1 @@ +Illegal move. Try again... \ No newline at end of file diff --git a/67_One_Check/csharp/Resources/Introduction.txt b/67_One_Check/csharp/Resources/Introduction.txt new file mode 100644 index 00000000..bc891a6e --- /dev/null +++ b/67_One_Check/csharp/Resources/Introduction.txt @@ -0,0 +1,29 @@ + 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. diff --git a/67_One_Check/csharp/Resources/Resource.cs b/67_One_Check/csharp/Resources/Resource.cs new file mode 100644 index 00000000..7095d7ec --- /dev/null +++ b/67_One_Check/csharp/Resources/Resource.cs @@ -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}'."); +} \ No newline at end of file diff --git a/67_One_Check/csharp/Resources/Results.txt b/67_One_Check/csharp/Resources/Results.txt new file mode 100644 index 00000000..8d4bd13f --- /dev/null +++ b/67_One_Check/csharp/Resources/Results.txt @@ -0,0 +1,4 @@ + +You made {0} jumps and had {1} pieces +remaining on the board. + diff --git a/67_One_Check/csharp/Resources/To.txt b/67_One_Check/csharp/Resources/To.txt new file mode 100644 index 00000000..788636ff --- /dev/null +++ b/67_One_Check/csharp/Resources/To.txt @@ -0,0 +1 @@ +to \ No newline at end of file diff --git a/67_One_Check/csharp/Resources/TryAgain.txt b/67_One_Check/csharp/Resources/TryAgain.txt new file mode 100644 index 00000000..c65e51fc --- /dev/null +++ b/67_One_Check/csharp/Resources/TryAgain.txt @@ -0,0 +1 @@ +Try again \ No newline at end of file diff --git a/67_One_Check/csharp/Resources/YesOrNo.txt b/67_One_Check/csharp/Resources/YesOrNo.txt new file mode 100644 index 00000000..703d4ad6 --- /dev/null +++ b/67_One_Check/csharp/Resources/YesOrNo.txt @@ -0,0 +1 @@ +Please answer 'Yes' or 'No'. \ No newline at end of file From 35f8248b1fb9b4d4d1093820fe804dbb8aaa1e6b Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Fri, 12 Aug 2022 17:49:05 +1000 Subject: [PATCH 2/4] Add game intro --- 67_One_Check/csharp/Board.cs | 18 +++++++++++++++++ 67_One_Check/csharp/Game.cs | 20 +++++++++++++++++++ 67_One_Check/csharp/Program.cs | 5 +++++ .../csharp/Resources/Introduction.txt | 17 ++++++++-------- 4 files changed, 52 insertions(+), 8 deletions(-) create mode 100644 67_One_Check/csharp/Board.cs create mode 100644 67_One_Check/csharp/Game.cs create mode 100644 67_One_Check/csharp/Program.cs diff --git a/67_One_Check/csharp/Board.cs b/67_One_Check/csharp/Board.cs new file mode 100644 index 00000000..213a54d7 --- /dev/null +++ b/67_One_Check/csharp/Board.cs @@ -0,0 +1,18 @@ +namespace OneCheck; + +internal class Board +{ + private readonly int[][] _checkers; + + public Board() + { + _checkers = + Enumerable.Range(0, 8) + .Select(r => Enumerable.Range(0, 8) + .Select(c => r > 1 && r < 6 && c > 1 && c < 6 ? 0 : 1).ToArray()) + .ToArray(); + } + + public override string ToString() => + string.Join(Environment.NewLine, _checkers.Select(r => string.Join(" ", r.Select(c => $" {c}")))); +} \ No newline at end of file diff --git a/67_One_Check/csharp/Game.cs b/67_One_Check/csharp/Game.cs new file mode 100644 index 00000000..924fc04c --- /dev/null +++ b/67_One_Check/csharp/Game.cs @@ -0,0 +1,20 @@ +namespace OneCheck; + +internal class Game +{ + private readonly IReadWrite _io; + private readonly Board _board; + + public Game(IReadWrite io) + { + _io = io; + _board = new Board(); + } + + public void Play() + { + _io.Write(Streams.Introduction); + + _io.WriteLine(_board); + } +} diff --git a/67_One_Check/csharp/Program.cs b/67_One_Check/csharp/Program.cs new file mode 100644 index 00000000..4a3ab83b --- /dev/null +++ b/67_One_Check/csharp/Program.cs @@ -0,0 +1,5 @@ +global using Games.Common.IO; +global using static OneCheck.Resources.Resource; +using OneCheck; + +new Game(new ConsoleIO()).Play(); diff --git a/67_One_Check/csharp/Resources/Introduction.txt b/67_One_Check/csharp/Resources/Introduction.txt index bc891a6e..409f6b37 100644 --- a/67_One_Check/csharp/Resources/Introduction.txt +++ b/67_One_Check/csharp/Resources/Introduction.txt @@ -17,13 +17,14 @@ 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 + 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. + From 876c71d89b5888059129af6e0469b436637a398f Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Tue, 16 Aug 2022 09:01:14 +1000 Subject: [PATCH 3/4] Add move logic --- 67_One_Check/csharp/Board.cs | 34 ++++++++++++++++++++++++++++++---- 67_One_Check/csharp/Game.cs | 28 +++++++++++++++++++++++++++- 67_One_Check/csharp/Move.cs | 13 +++++++++++++ 3 files changed, 70 insertions(+), 5 deletions(-) create mode 100644 67_One_Check/csharp/Move.cs diff --git a/67_One_Check/csharp/Board.cs b/67_One_Check/csharp/Board.cs index 213a54d7..7ae917be 100644 --- a/67_One_Check/csharp/Board.cs +++ b/67_One_Check/csharp/Board.cs @@ -2,17 +2,43 @@ namespace OneCheck; internal class Board { - private readonly int[][] _checkers; + private readonly bool[][] _checkers; + private int _count; public Board() { _checkers = Enumerable.Range(0, 8) .Select(r => Enumerable.Range(0, 8) - .Select(c => r > 1 && r < 6 && c > 1 && c < 6 ? 0 : 1).ToArray()) + .Select(c => r <= 1 || r >= 6 || c <= 1 || c >= 6).ToArray()) .ToArray(); + _count = 48; } + private bool this[int index] + { + get => _checkers[(index - 1) / 8][(index-1) % 8]; + set => _checkers[(index - 1) / 8][(index-1) % 8] = value; + } + + public int Count => _count; + + public bool TryMove(Move move) + { + if (move.IsInRange && move.IsTwoSpacesDiagonally && IsPieceJumpingPieceToEmptySpace(move)) + { + this[move.From] = false; + this[move.Jumped] = false; + this[move.To] = true; + _count--; + return true; + } + + return false; + } + + private bool IsPieceJumpingPieceToEmptySpace(Move move) => this[move.From] && this[move.Jumped] && !this[move.To]; + public override string ToString() => - string.Join(Environment.NewLine, _checkers.Select(r => string.Join(" ", r.Select(c => $" {c}")))); -} \ No newline at end of file + string.Join(Environment.NewLine, _checkers.Select(r => string.Join(" ", r.Select(c => c ? " 1" : " 0")))); +} diff --git a/67_One_Check/csharp/Game.cs b/67_One_Check/csharp/Game.cs index 924fc04c..49da9851 100644 --- a/67_One_Check/csharp/Game.cs +++ b/67_One_Check/csharp/Game.cs @@ -4,6 +4,7 @@ internal class Game { private readonly IReadWrite _io; private readonly Board _board; + private int _moveCount; public Game(IReadWrite io) { @@ -15,6 +16,31 @@ internal class Game { _io.Write(Streams.Introduction); - _io.WriteLine(_board); + do + { + _io.WriteLine(_board); + _io.WriteLine(); + } while (PlayMove()); + + _io.WriteLine(Formats.Results, _moveCount, _board.Count); + } + + private bool PlayMove() + { + while (true) + { + var from = (int)_io.ReadNumber(Prompts.From); + if (from == 0) { return false; } + + var move = new Move { From = from, To = (int)_io.ReadNumber(Prompts.To) }; + + if (_board.TryMove(move)) + { + _moveCount++; + return true; + } + + _io.Write(Streams.IllegalMove); + } } } diff --git a/67_One_Check/csharp/Move.cs b/67_One_Check/csharp/Move.cs new file mode 100644 index 00000000..b90f7c0b --- /dev/null +++ b/67_One_Check/csharp/Move.cs @@ -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 >= 1 && From <= 64 && To >= 1 && To <= 64; + 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); +} \ No newline at end of file From c603549db34a25cb445298d44fd6e333d31d4efd Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Fri, 19 Aug 2022 08:41:11 +1000 Subject: [PATCH 4/4] Finish game --- 67_One_Check/csharp/Board.cs | 32 +++++++++++++++++---- 67_One_Check/csharp/Game.cs | 35 +++++++++++------------ 67_One_Check/csharp/Move.cs | 2 +- 67_One_Check/csharp/Resources/Results.txt | 1 - 4 files changed, 44 insertions(+), 26 deletions(-) diff --git a/67_One_Check/csharp/Board.cs b/67_One_Check/csharp/Board.cs index 7ae917be..2e68072d 100644 --- a/67_One_Check/csharp/Board.cs +++ b/67_One_Check/csharp/Board.cs @@ -3,7 +3,8 @@ namespace OneCheck; internal class Board { private readonly bool[][] _checkers; - private int _count; + private int _pieceCount; + private int _moveCount; public Board() { @@ -12,16 +13,33 @@ internal class Board .Select(r => Enumerable.Range(0, 8) .Select(c => r <= 1 || r >= 6 || c <= 1 || c >= 6).ToArray()) .ToArray(); - _count = 48; + _pieceCount = 48; } private bool this[int index] { - get => _checkers[(index - 1) / 8][(index-1) % 8]; - set => _checkers[(index - 1) / 8][(index-1) % 8] = value; + get => _checkers[index / 8][index % 8]; + set => _checkers[index / 8][index % 8] = value; } - public int Count => _count; + 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) { @@ -30,7 +48,7 @@ internal class Board this[move.From] = false; this[move.Jumped] = false; this[move.To] = true; - _count--; + _pieceCount--; return true; } @@ -39,6 +57,8 @@ internal class Board 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")))); } diff --git a/67_One_Check/csharp/Game.cs b/67_One_Check/csharp/Game.cs index 49da9851..d9e64e26 100644 --- a/67_One_Check/csharp/Game.cs +++ b/67_One_Check/csharp/Game.cs @@ -3,13 +3,10 @@ namespace OneCheck; internal class Game { private readonly IReadWrite _io; - private readonly Board _board; - private int _moveCount; public Game(IReadWrite io) { _io = io; - _board = new Board(); } public void Play() @@ -18,29 +15,31 @@ internal class Game do { - _io.WriteLine(_board); - _io.WriteLine(); - } while (PlayMove()); + var board = new Board(); + do + { + _io.WriteLine(board); + _io.WriteLine(); + } while (board.PlayMove(_io)); - _io.WriteLine(Formats.Results, _moveCount, _board.Count); + _io.WriteLine(board.GetReport()); + } while (_io.ReadYesNo(Prompts.TryAgain) == "yes"); + + _io.Write(Streams.Bye); } +} - private bool PlayMove() +internal static class IOExtensions +{ + internal static string ReadYesNo(this IReadWrite io, string prompt) { while (true) { - var from = (int)_io.ReadNumber(Prompts.From); - if (from == 0) { return false; } + var response = io.ReadString(prompt).ToLower(); - var move = new Move { From = from, To = (int)_io.ReadNumber(Prompts.To) }; + if (response == "yes" || response == "no") { return response; } - if (_board.TryMove(move)) - { - _moveCount++; - return true; - } - - _io.Write(Streams.IllegalMove); + io.Write(Streams.YesOrNo); } } } diff --git a/67_One_Check/csharp/Move.cs b/67_One_Check/csharp/Move.cs index b90f7c0b..0b48659e 100644 --- a/67_One_Check/csharp/Move.cs +++ b/67_One_Check/csharp/Move.cs @@ -6,7 +6,7 @@ internal class Move public int To { get; init; } public int Jumped => (From + To) / 2; - public bool IsInRange => From >= 1 && From <= 64 && To >= 1 && To <= 64; + 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); diff --git a/67_One_Check/csharp/Resources/Results.txt b/67_One_Check/csharp/Resources/Results.txt index 8d4bd13f..a8771b6b 100644 --- a/67_One_Check/csharp/Resources/Results.txt +++ b/67_One_Check/csharp/Resources/Results.txt @@ -1,4 +1,3 @@ You made {0} jumps and had {1} pieces remaining on the board. -