This commit is contained in:
Christian Kauer 2023-12-23 15:04:29 +01:00
parent 113f7bb561
commit 99513fb9a1
25 changed files with 287 additions and 106 deletions

View File

@ -1,4 +1,5 @@
using System;
using GameModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -8,6 +9,15 @@ namespace GameContract
{
public interface IGameHandler
{
static string GetGameName() => "Default Hello from interface";
public const int INFINIT_THROWS = 9999;
static string GameName() => "Default Hello from IGameHandler";
ThrowMode ThrowMode() => GameModel.ThrowMode.Reposition;
int ThrowsPerRount() => INFINIT_THROWS;
bool FreePlayerSelection() => true;
}
}

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GameContract
{
public interface IGameSettings
{
}
}

View File

@ -25,7 +25,6 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\GameContract\GameContract.csproj" />
<ProjectReference Include="..\GameHandler\GameHandler.csproj" />
<ProjectReference Include="..\GameModel\GameModel.csproj" />
</ItemGroup>

View File

@ -1,4 +1,5 @@
using GameModel;
using GameHandler.DeathGame;
using GameModel;
using GameModel.Exceptions;
using System;
using System.Collections.Generic;
@ -44,10 +45,10 @@ namespace GameHandler.UnitTests
}
[Test]
public void HandleThrow_UpdateTheBoardState()
public void HandleThrow_UpdatesTheBoardState()
{
GameService service = new GameService();
var ts1 = service.Start(1);
var ts1 = service.Start(DeathGameHandler.GAMENAME_DEATHBOX);
var bs1 = ts1.BoardState;
var pinThrow = PinThrow.Create(1,PinPicture.Create(1,PinState.Down), false, false);

View File

@ -1,4 +1,4 @@
using GameContract;
using GameModel.Contract;
using System;
using System.Collections.Generic;
using System.Linq;

View File

@ -0,0 +1,20 @@
using GameModel.Exceptions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GameHandler.Exceptions
{
public class InvaildGameNameException : KoogleException
{
public InvaildGameNameException(string message) : base(message)
{
}
public InvaildGameNameException(string message, Exception innerException) : base(message, innerException)
{
}
}
}

View File

@ -1,6 +1,6 @@
using GameContract;
using GameHandler.Extensions;
using GameHandler.Extensions;
using GameModel;
using GameModel.Contract;
using GameModel.DeathGame;
using GameModel.Exceptions;
using System;

View File

@ -0,0 +1,45 @@
using GameHandler.Exceptions;
using GameModel.Contract;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace GameHandler.Extensions
{
public static class GameServiceExtension
{
public static IGameHandler GetGameHandler(this GameService gameService, string gameName)
{
var handlers = gameService.GetGameHandler();
if (!handlers.ContainsKey(gameName))
{
throw new InvaildGameNameException($"not handler found for {gameName}");
}
var type = handlers[gameName];
var res = (IGameHandler)Activator.CreateInstance(type);
return res;
}
public static Dictionary<string, Type> GetGameHandler(this GameService gameService)
{
var res = new Dictionary<string, Type>();
var type = typeof(IGameHandler);
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(p => type.IsAssignableFrom(p) && (!p.IsInterface));
foreach (var item in types)
{
MethodInfo staticMethodInfo = item.GetMethod("GameName");
string returnValue = Convert.ToString(staticMethodInfo.Invoke(null, Array.Empty<object>()));
res.Add(returnValue, item);
}
return res;
}
}
}

View File

@ -7,7 +7,6 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\GameContract\GameContract.csproj" />
<ProjectReference Include="..\GameModel\GameModel.csproj" />
</ItemGroup>

View File

@ -1,5 +1,6 @@
using GameContract;
using GameModel;
using GameModel;
using GameModel.Contract;
using GameModel.Contracts;
using GameModel.DeathGame;
using System;
using System.Collections.Generic;
@ -18,6 +19,7 @@ namespace GameHandler.DeathGame
const int MAX_PLAYER_COUNT = 12;
const int MIN_COFFIN_SIZE = 6;
const int MAX_COFFIN_SIZE = 12;
public const string GAMENAME_DEATHBOX = "Totenkiste";
public event CoffinCompleted CoffinCompleted;
public event FirstThrowFailed FirstThrowFailed;
@ -49,6 +51,11 @@ namespace GameHandler.DeathGame
{
}
public IGameModel InitGameModel(int[] playerIds, IGameSettings gameSettings)
{
return InitGameModel(playerIds, gameSettings as DeathGameSettings);
}
public DeathGameModel InitGameModel(int[] playerIds, DeathGameSettings deathGameSettings)
{
ValidatePlayerCount(playerIds.Count());
@ -178,9 +185,14 @@ namespace GameHandler.DeathGame
return result;
}
public static string GetGameName()
public static string GameName()
{
return "Totenkiste";
return GAMENAME_DEATHBOX;
}
public ThrowMode ThrowMode() => GameModel.ThrowMode.Decrease;
public bool FreePlayerSelection() => false;
}
}

View File

@ -1,4 +1,6 @@
using GameContract;
using GameModel.Contract;
using GameModel.Contracts;
using GameModel.FreeGame;
using System;
using System.Collections.Generic;
using System.Linq;
@ -9,9 +11,15 @@ namespace GameHandler.GameHandler
{
public class FreeGameHandler : IGameHandler
{
public static string GetGameName()
public const string GAMENAME_FREETRAINING = "Freies Spiel";
public static string GameName()
{
return "Freies Spiel";
return GAMENAME_FREETRAINING;
}
public IGameModel InitGameModel(int[] playerIds, IGameSettings gameSettings)
{
return new FreeGameModel();
}
}
}

View File

@ -1,4 +1,4 @@
using GameContract;
using GameHandler.Extensions;
using GameModel;
using GameModel.Exceptions;
using System;
@ -7,20 +7,23 @@ using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using GameHandler.GameHandler;
using GameHandler.Parser;
using GameModel.Contract;
using GameModel.DeathGame;
namespace GameHandler
{
public class GameService
{
public const int INFINIT_THROWS = 9999;
private bool _isStarted = false;
private IGameHandler _gh;
private ThrowHandler _th;
private ThrowState _lastState;
public GameService()
{
LoadGameHandler();
}
public string ThrowModeName
@ -35,26 +38,39 @@ namespace GameHandler
}
}
public ThrowState Start(string gameName) // TODO: add players
static int[] defaultPlayerIds => new[] {1,2,3,4};
public ThrowState Start(string gameName = FreeGameHandler.GAMENAME_FREETRAINING) // TODO: add players
{
return Start(defaultPlayerIds, new DeathGameSettings(6), gameName);
}
public ThrowState Start(int[] playerIds, IGameSettings gameSettings, string gameName = FreeGameHandler.GAMENAME_FREETRAINING) // TODO: add players
{
if (_isStarted)
{
throw new InvalidGameStateExcpetion("Game already started");
}
if (!_isStarted)
{
_isStarted = true;
}
_isStarted = true;
_gh = this.GetGameHandler(gameName);
var gm = _gh.InitGameModel(playerIds, gameSettings);
_th = new ThrowHandler();
//var throwMode = GameTypeId == 0 ? ThrowMode.Reposition : ThrowMode.Decrease;
//var throwsPerRount = GameTypeId == 0 ? INFINIT_THROWS : 3;
var throwMode = GameTypeId == 0 ? ThrowMode.Reposition : ThrowMode.Decrease;
var throwsPerRount = GameTypeId == 0 ? INFINIT_THROWS : 3;
_lastState = ThrowState.Create(throwMode, throwsPerRount);
_lastState = ThrowState.Create(_gh.ThrowMode(), _gh.ThrowsPerRount());
return _lastState;
}
//private IGameHandler GetGameHandler(string gameName)
//{
// throw new NotImplementedException();
//}
public ThrowState HandleThrow(PinThrow pinThrow)
{
if (!_isStarted)
@ -75,23 +91,11 @@ namespace GameHandler
_isStarted = false;
}
public static Dictionary<string, Type> LoadGameHandler()
public ThrowCommandData ParseThrowData(string stringData)
{
var res = new Dictionary<string, Type>();
var type = typeof(IGameHandler);
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(p => type.IsAssignableFrom(p) && (!p.IsInterface));
foreach (var item in types)
{
MethodInfo staticMethodInfo = item.GetMethod("GetGameName");
string returnValue = Convert.ToString(staticMethodInfo.Invoke(null, new object[] { }));
res.Add(returnValue, item);
}
return res;
return ThrowCommandParser.Parse(stringData, _gh.FreePlayerSelection(), 0); // TOOD: Player
}
public bool FreePlayerSelection => _gh.FreePlayerSelection();
}
}

View File

@ -0,0 +1,39 @@
using GameModel;
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 GameHandler.Parser
{
public static class ThrowCommandParser
{
public static ThrowCommandData Parse(string data, bool withFreePlayerSelection, int playerId = 0)
{
if (string.IsNullOrEmpty(data))
throw new ArgumentNullException("data");
if (!withFreePlayerSelection && playerId == 0)
{
throw new ArgumentNullException("playerid required");
}
string pindata;
if (withFreePlayerSelection)
{
var player = data.Substring(0, 1);
playerId = int.Parse(player);
pindata = data.Substring(2, data.Length - 2);
}
else
{
pindata = data;
}
return new ThrowCommandData(playerId, Regex.Match(pindata, @"\d+").Value, data.Contains("b"), data.Contains("s"), data.Contains("e"));
}
}
}

View File

@ -0,0 +1,9 @@
using GameModel;
namespace GameModel.Contract
{
public interface IExpenseRepository
{
IEnumerable<Expense> GetAll();
}
}

View File

@ -0,0 +1,25 @@
using GameModel;
using GameModel.Contracts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GameModel.Contract
{
public interface IGameHandler
{
public const int INFINIT_THROWS = 9999;
static string GameName() => "Default Hello from IGameHandler";
ThrowMode ThrowMode() => GameModel.ThrowMode.Reposition;
int ThrowsPerRount() => INFINIT_THROWS;
bool FreePlayerSelection() => true;
IGameModel InitGameModel(int[] playerIds, IGameSettings gameSettings);
}
}

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GameModel.Contracts
{
public interface IGameModel
{
}
}

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GameModel.Contract
{
public interface IGameSettings
{
}
}

View File

@ -1,4 +1,5 @@
using System;
using GameModel.Contracts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -6,5 +7,5 @@ using System.Threading.Tasks;
namespace GameModel.DeathGame
{
public record DeathGameModel(int Id, Coffin[] Coffins, DeathGameSettings deathGameSettings);
public record DeathGameModel(int Id, Coffin[] Coffins, DeathGameSettings deathGameSettings) : IGameModel;
}

View File

@ -1,4 +1,5 @@
using System;
using GameModel.Contract;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -6,6 +7,6 @@ using System.Threading.Tasks;
namespace GameModel.DeathGame
{
public record DeathGameSettings(int MaxCoffinSize);
public record DeathGameSettings(int MaxCoffinSize) : IGameSettings;
}

View File

@ -1,4 +1,5 @@
using System;
using GameModel.Contracts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -6,7 +7,7 @@ using System.Threading.Tasks;
namespace GameModel.FreeGame
{
public record FreeGameModel
public record FreeGameModel : IGameModel
{
}
}

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GameModel
{
public record ThrowCommandData(int PlayerId, string Pindata, bool Bell, bool Sink, bool Abort)
{
}
}

View File

@ -1,13 +0,0 @@
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)
{
}
}

View File

@ -1,25 +0,0 @@
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"));
}
}
}

View File

@ -1,9 +1,10 @@
// See https://aka.ms/new-console-template for more information
using CommandLine;
using GameHandler;
using GameHandler.Extensions;
using GameModel;
using GameModel.Contract;
using KoogleCli.Model;
using KoogleCli.Parser;
using Spectre.Console;
using static System.Runtime.InteropServices.JavaScript.JSType;
@ -44,7 +45,7 @@ void NewGameAction()
var option = string.Empty;
//do
//{
var games = GameService.LoadGameHandler().Keys.Order().ToList();
var games = new GameService().GetGameHandler().Keys.Order().ToList();
games.Add("Abbreche");
option = AnsiConsole.Prompt(
@ -73,22 +74,24 @@ void NewGameAction()
void StartGameAction(string gameName)
{
_gs = new GameService();
var bs = _gs.Start(gameName);
var bs = _gs.Start(new[] { 1,2,3,4}, null, gameName );
Show(bs);
do
{
{
var proptText = _gs.FreePlayerSelection ? $"Spieler,Wurf [yellow]{bs.ThrowCount + 1}[/]:" : $"Wurf [yellow]{bs.ThrowCount + 1}[/]";
var stringData = AnsiConsole.Prompt(
new TextPrompt<string>($"Wurf [yellow]{bs.ThrowCount + 1}[/]?")
new TextPrompt<string>(proptText)
.PromptStyle("green")
.ValidationErrorMessage("[red]That's not a valid throw[/]")
.Validate(data =>
{
try
{
ThrowDataParser.Parse(data);
_gs.ParseThrowData(data);
}
catch (Exception)
{
@ -97,7 +100,7 @@ void StartGameAction(string gameName)
return true;
}));
var throwData = ThrowDataParser.Parse(stringData);
var throwData = _gs.ParseThrowData(stringData);
if (throwData.Abort)
{
_gs.Stop();
@ -130,7 +133,7 @@ void ShowThrow(ThrowState throwState)
int throwCount = throwState.ThrowCount;
int throwsPerRount = throwState.ThrowsPerRount;
Text text1;
if (throwsPerRount == GameService.INFINIT_THROWS)
if (throwsPerRount == IGameHandler.INFINIT_THROWS)
{
text1 = new Text($"Würfe: {throwCount}", new Style(Color.Red, Color.Black));
}

View File

@ -9,11 +9,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GameHandler", "GameHandler\
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GameModel", "GameModel\GameModel.csproj", "{9B3CADB6-C335-46D1-B98B-07E73D53E16B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GameContract", "GameContract\GameContract.csproj", "{68897747-A9D4-4E45-A20C-6AB7E7AB22FD}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GameModel.UnitTests", "GameModel.UnitTests\GameModel.UnitTests.csproj", "{C752388E-815A-4911-AC75-B6C27337D81A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GameModel.UnitTests", "GameModel.UnitTests\GameModel.UnitTests.csproj", "{C752388E-815A-4911-AC75-B6C27337D81A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KoogleCli", "KoogleCli\KoogleCli.csproj", "{3FF45A02-42F9-4E75-993B-6582DD2A22BF}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KoogleCli", "KoogleCli\KoogleCli.csproj", "{3FF45A02-42F9-4E75-993B-6582DD2A22BF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -33,10 +31,6 @@ Global
{9B3CADB6-C335-46D1-B98B-07E73D53E16B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9B3CADB6-C335-46D1-B98B-07E73D53E16B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9B3CADB6-C335-46D1-B98B-07E73D53E16B}.Release|Any CPU.Build.0 = Release|Any CPU
{68897747-A9D4-4E45-A20C-6AB7E7AB22FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{68897747-A9D4-4E45-A20C-6AB7E7AB22FD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{68897747-A9D4-4E45-A20C-6AB7E7AB22FD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{68897747-A9D4-4E45-A20C-6AB7E7AB22FD}.Release|Any CPU.Build.0 = Release|Any CPU
{C752388E-815A-4911-AC75-B6C27337D81A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C752388E-815A-4911-AC75-B6C27337D81A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C752388E-815A-4911-AC75-B6C27337D81A}.Release|Any CPU.ActiveCfg = Release|Any CPU