From 64e009d401eda11959694abec336c3349587b2b5 Mon Sep 17 00:00:00 2001 From: Christian Kauer Date: Fri, 22 Dec 2023 13:55:45 +0100 Subject: [PATCH] dev --- GameHandler.UnitTests/GameServiceTests.cs | 19 ++ GameHandler/DeathGame/DeathGameHandler.cs | 3 - GameHandler/GameService.cs | 54 ++++++ GameHandler/MainHandler.cs | 13 -- .../GameModel.UnitTests.csproj | 30 +++ GameModel.UnitTests/GlobalUsings.cs | 1 + .../Helper/IEnumerableExtension.cs | 20 ++ .../PinPictureTests.cs | 4 +- .../PinThrowTests.cs | 2 +- .../Exceptions/InvalidGameStateExcpetion.cs | 15 ++ GameModel/PinPicture.cs | 22 +++ GameModel/PinThrow.cs | 15 +- KoogleCli/KoogleCli.csproj | 20 ++ KoogleCli/Model/Option.cs | 16 ++ KoogleCli/Model/ThrowData.cs | 13 ++ KoogleCli/Parser/ThrowDataParser.cs | 25 +++ KoogleCli/Program.cs | 176 ++++++++++++++++++ KoogleV4.sln | 20 +- 18 files changed, 443 insertions(+), 25 deletions(-) create mode 100644 GameHandler.UnitTests/GameServiceTests.cs create mode 100644 GameHandler/GameService.cs delete mode 100644 GameHandler/MainHandler.cs create mode 100644 GameModel.UnitTests/GameModel.UnitTests.csproj create mode 100644 GameModel.UnitTests/GlobalUsings.cs create mode 100644 GameModel.UnitTests/Helper/IEnumerableExtension.cs rename {GameHandler.UnitTests => GameModel.UnitTests}/PinPictureTests.cs (99%) rename {GameHandler.UnitTests => GameModel.UnitTests}/PinThrowTests.cs (98%) create mode 100644 GameModel/Exceptions/InvalidGameStateExcpetion.cs create mode 100644 KoogleCli/KoogleCli.csproj create mode 100644 KoogleCli/Model/Option.cs create mode 100644 KoogleCli/Model/ThrowData.cs create mode 100644 KoogleCli/Parser/ThrowDataParser.cs create mode 100644 KoogleCli/Program.cs diff --git a/GameHandler.UnitTests/GameServiceTests.cs b/GameHandler.UnitTests/GameServiceTests.cs new file mode 100644 index 0000000..cececd7 --- /dev/null +++ b/GameHandler.UnitTests/GameServiceTests.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace GameHandler.UnitTests +{ + [TestFixture] + internal class GameServiceTests + { + [Test] + public void Start_StartsANewGame() + { + GameService service = new GameService(); + service.Start(); + } + } +} diff --git a/GameHandler/DeathGame/DeathGameHandler.cs b/GameHandler/DeathGame/DeathGameHandler.cs index 8380c63..d2772bc 100644 --- a/GameHandler/DeathGame/DeathGameHandler.cs +++ b/GameHandler/DeathGame/DeathGameHandler.cs @@ -172,9 +172,6 @@ namespace GameHandler.DeathGame coffins.Insert(idx, previousUpdated); } - - - var result = gm with { Coffins = coffins.ToArray(), Id = gm.Id + 1 }; return result; diff --git a/GameHandler/GameService.cs b/GameHandler/GameService.cs new file mode 100644 index 0000000..bb219e9 --- /dev/null +++ b/GameHandler/GameService.cs @@ -0,0 +1,54 @@ +using GameModel; +using GameModel.Exceptions; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace GameHandler +{ + public class GameService + { + private bool _isStarted = false; + private ThrowHandler _th; + private BoardState _lastState; + + public BoardState Start() + { + if (_isStarted) + { + throw new InvalidGameStateExcpetion("Game already started"); + } + if (!_isStarted) + { + _isStarted = true; + } + + _th = new ThrowHandler(); + + _lastState = BoardState.Create(ThrowMode.Decrease); + return _lastState; + } + + public BoardState HandleThrow(PinThrow pinThrow) + { + if (!_isStarted) + { + throw new InvalidGameStateExcpetion("Game not started"); + } + + _lastState = _th.Update(_lastState, pinThrow); + return _lastState; + } + + public void Stop() + { + if (!_isStarted) + { + throw new InvalidGameStateExcpetion("Game not started"); + } + _isStarted = false; + } + } +} diff --git a/GameHandler/MainHandler.cs b/GameHandler/MainHandler.cs deleted file mode 100644 index d29c5f5..0000000 --- a/GameHandler/MainHandler.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace GameHandler -{ - internal class MainHandler - { - - } -} diff --git a/GameModel.UnitTests/GameModel.UnitTests.csproj b/GameModel.UnitTests/GameModel.UnitTests.csproj new file mode 100644 index 0000000..f7e431d --- /dev/null +++ b/GameModel.UnitTests/GameModel.UnitTests.csproj @@ -0,0 +1,30 @@ + + + + net7.0 + enable + enable + + false + true + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + diff --git a/GameModel.UnitTests/GlobalUsings.cs b/GameModel.UnitTests/GlobalUsings.cs new file mode 100644 index 0000000..cefced4 --- /dev/null +++ b/GameModel.UnitTests/GlobalUsings.cs @@ -0,0 +1 @@ +global using NUnit.Framework; \ No newline at end of file diff --git a/GameModel.UnitTests/Helper/IEnumerableExtension.cs b/GameModel.UnitTests/Helper/IEnumerableExtension.cs new file mode 100644 index 0000000..307a7b2 --- /dev/null +++ b/GameModel.UnitTests/Helper/IEnumerableExtension.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace GameModel.UnitTests.Helper +{ + public static class IEnumerableExtension + { + public static IEnumerable AsWeakEnumerable(this IEnumerable source) + { + foreach (object o in source) + { + yield return o; + } + } + } +} diff --git a/GameHandler.UnitTests/PinPictureTests.cs b/GameModel.UnitTests/PinPictureTests.cs similarity index 99% rename from GameHandler.UnitTests/PinPictureTests.cs rename to GameModel.UnitTests/PinPictureTests.cs index 32b5fb2..b71a2fc 100644 --- a/GameHandler.UnitTests/PinPictureTests.cs +++ b/GameModel.UnitTests/PinPictureTests.cs @@ -1,4 +1,4 @@ -using GameHandler.UnitTests.Helper; +using GameModel.UnitTests.Helper; using GameModel; using GameModel.Exceptions; using NuGet.Frameworks; @@ -6,7 +6,7 @@ using NUnit.Framework.Legacy; using System.Collections; using System.Numerics; -namespace GameHandler.UnitTests +namespace GameModel.UnitTests { [TestFixture] internal class PinPictureTests diff --git a/GameHandler.UnitTests/PinThrowTests.cs b/GameModel.UnitTests/PinThrowTests.cs similarity index 98% rename from GameHandler.UnitTests/PinThrowTests.cs rename to GameModel.UnitTests/PinThrowTests.cs index 9787604..047b38f 100644 --- a/GameHandler.UnitTests/PinThrowTests.cs +++ b/GameModel.UnitTests/PinThrowTests.cs @@ -5,7 +5,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace GameHandler.UnitTests +namespace GameModel.UnitTests { [TestFixture] internal class PinThrowTests diff --git a/GameModel/Exceptions/InvalidGameStateExcpetion.cs b/GameModel/Exceptions/InvalidGameStateExcpetion.cs new file mode 100644 index 0000000..a4e5926 --- /dev/null +++ b/GameModel/Exceptions/InvalidGameStateExcpetion.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace GameModel.Exceptions +{ + public class InvalidGameStateExcpetion : KoogleException + { + public InvalidGameStateExcpetion(string message) : base(message, null) + { + } + } +} diff --git a/GameModel/PinPicture.cs b/GameModel/PinPicture.cs index 2b1aae0..2008f3d 100644 --- a/GameModel/PinPicture.cs +++ b/GameModel/PinPicture.cs @@ -195,5 +195,27 @@ namespace GameModel var states = new List(new[] { PinState.Down, PinState.Down, PinState.Down, PinState.Down, PinState.Up, PinState.Down, PinState.Down, PinState.Down, PinState.Down }).ToArray(); return PinPicture.Create(states); } + + internal static PinPicture Create(string pindata) + { + if (!int.TryParse(pindata, out int dummy)) + { + throw new InvalidDataException($"{pindata} cannot be parsed as throw"); + } + + var states = new[] { + pindata.Contains("1") ? PinState.Down : PinState.Up, + pindata.Contains("2") ? PinState.Down : PinState.Up, + pindata.Contains("3") ? PinState.Down : PinState.Up, + pindata.Contains("4") ? PinState.Down : PinState.Up, + pindata.Contains("5") ? PinState.Down : PinState.Up, + pindata.Contains("6") ? PinState.Down : PinState.Up, + pindata.Contains("7") ? PinState.Down : PinState.Up, + pindata.Contains("8") ? PinState.Down : PinState.Up, + pindata.Contains("9") ? PinState.Down : PinState.Up, + }; + + return PinPicture.Create(states); + } } } diff --git a/GameModel/PinThrow.cs b/GameModel/PinThrow.cs index 5319539..f6cdd63 100644 --- a/GameModel/PinThrow.cs +++ b/GameModel/PinThrow.cs @@ -19,9 +19,9 @@ namespace GameModel public bool IsNoWood => PicPicture.DownCount == 0 && !IsSink; - public static PinThrow Create(int PlayerId, PinPicture PicPicture, bool IsBell, bool IsSink) + public static PinThrow Create(int playerId, PinPicture picPicture, bool isBell, bool isSink) { - return new PinThrow(PlayerId, PicPicture, IsBell, IsSink); + return new PinThrow(playerId, picPicture, isBell, isSink); } public static PinThrow Create(int PlayerId, bool IsBell, bool IsSink) @@ -29,5 +29,16 @@ namespace GameModel var p = PinPicture.Create(); return Create(PlayerId, p, IsBell, IsSink); } + + public static PinThrow Create(string pindata, bool isBell, bool isSink, int playerId) + { + if (!int.TryParse(pindata, out int dummy)) + { + throw new InvalidDataException($"{pindata} cannot be parsed as throw"); + } + + var pic = PinPicture.Create(pindata); + return PinThrow.Create(playerId, pic, isBell, isSink); + } } } diff --git a/KoogleCli/KoogleCli.csproj b/KoogleCli/KoogleCli.csproj new file mode 100644 index 0000000..a502f8c --- /dev/null +++ b/KoogleCli/KoogleCli.csproj @@ -0,0 +1,20 @@ + + + + Exe + net7.0 + enable + enable + + + + + + + + + + + + + diff --git a/KoogleCli/Model/Option.cs b/KoogleCli/Model/Option.cs new file mode 100644 index 0000000..e5d5041 --- /dev/null +++ b/KoogleCli/Model/Option.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace KoogleCli.Model +{ + internal record Option(string Name,Action Action) + { + public override string ToString() + { + return Name; + } + } +} diff --git a/KoogleCli/Model/ThrowData.cs b/KoogleCli/Model/ThrowData.cs new file mode 100644 index 0000000..bb4161e --- /dev/null +++ b/KoogleCli/Model/ThrowData.cs @@ -0,0 +1,13 @@ +using CommandLine; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace KoogleCli.Model +{ + public record ThrowData(int PlayerId, string Pindata, bool Bell, bool Sink, bool Abort) + { + } +} diff --git a/KoogleCli/Parser/ThrowDataParser.cs b/KoogleCli/Parser/ThrowDataParser.cs new file mode 100644 index 0000000..c09c6bf --- /dev/null +++ b/KoogleCli/Parser/ThrowDataParser.cs @@ -0,0 +1,25 @@ +using KoogleCli.Model; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using static System.Runtime.InteropServices.JavaScript.JSType; + +namespace KoogleCli.Parser +{ + public static class ThrowDataParser + { + public static ThrowData Parse(string data) + { + if (string.IsNullOrEmpty(data)) + throw new ArgumentNullException("data"); + + var player = data.Substring(0, 1); + var playerId = int.Parse(player); + var pindata = data.Substring(2, data.Length -2); + return new ThrowData(playerId, Regex.Match(pindata, @"\d+").Value, data.Contains("b"), data.Contains("s"), data.Contains("e")); + } + } +} diff --git a/KoogleCli/Program.cs b/KoogleCli/Program.cs new file mode 100644 index 0000000..7044683 --- /dev/null +++ b/KoogleCli/Program.cs @@ -0,0 +1,176 @@ +// See https://aka.ms/new-console-template for more information +using CommandLine; +using GameHandler; +using GameModel; +using KoogleCli.Model; +using KoogleCli.Parser; +using Spectre.Console; +using static System.Runtime.InteropServices.JavaScript.JSType; + +AnsiConsole.MarkupLine("Welcome to [green]koogle[/]"); + +do +{ + var option = AnsiConsole.Prompt( + new SelectionPrompt