using GameHandler.Extensions; using GameModel; using GameModel.Exceptions; using System; using System.Collections.Generic; 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; using GameModel.Contracts; using System.Data; using Autofac.Core; using Autofac; using static System.Formats.Asn1.AsnWriter; namespace GameHandler { public class GameService { private IContainer _container { get; set; } private bool _isStarted = false; private ILifetimeScope _scope; private IGameHandler _gh; private ThrowHandler _th; private ExpenseHandler _eh; private GameState _lastState; public GameState GameModel { get => _lastState; } private IExpenseRepository _expenseRepository { get => _scope.Resolve(); } public GameService(IContainer container =null) { _container = container; } public string ThrowModeName { get { if (_lastState != null) { return _lastState.ThrowState.BoardState.ThrowMode == ThrowMode.Decrease ? "Abräumen" : "Volle"; } return string.Empty; } } static int[] defaultPlayerIds => new[] {1,2,3,4}; public GameState Start(string gameName = FreeGameHandler.GAMENAME_FREETRAINING) { return Start(defaultPlayerIds, new DeathGameSettings(6), gameName); } public GameState Start(int[] playerIds, IGameSettings gameSettings, string gameName = FreeGameHandler.GAMENAME_FREETRAINING) { if (_isStarted) { throw new InvalidGameStateExcpetion("Game already started"); } _isStarted = true; _scope = _container?.BeginLifetimeScope(); _gh = this.GetGameHandler(gameName); var gm = _gh.InitGameModel(playerIds, gameSettings); _th = new ThrowHandler(); _eh = new ExpenseHandler(_expenseRepository); var throwState = ThrowState.Create(_gh.ThrowMode(), _gh.ThrowsPerRount()); _lastState = GameState.Create(throwState, _gh.GetCurrentPlayerId(gm), gm, ExpenseModel.Create()); return _lastState; } public GameState HandleThrow(PinThrow pinThrow) { if (!_isStarted) { throw new InvalidGameStateExcpetion("Game not started"); } var boardStateBeforeUpdate = _lastState.ThrowState.BoardState; pinThrow = AutoCompletePlayerId(pinThrow); var throwState = _th.Update(_lastState.ThrowState, pinThrow); var gameModel = _gh.Update(pinThrow, _lastState.GameModel, boardStateBeforeUpdate); var expenseModel = _eh.CheckThrow(throwState.BoardState, pinThrow, gameModel.PlayerIds, _lastState.ExpenseModel); _lastState = _lastState with { ThrowState = throwState, GameModel = gameModel, NextPlayerId = _gh.GetCurrentPlayerId(gameModel), ExpenseModel = expenseModel }; return _lastState ; } private PinThrow AutoCompletePlayerId(PinThrow pinThrow) { if (_gh.FreePlayerSelection() && pinThrow.PlayerId == 0) { throw new InvalidPinThrowException("PlayerId connot be 0"); } if (_gh.FreePlayerSelection()) { return pinThrow; } return pinThrow with { PlayerId = _gh.GetCurrentPlayerId(_lastState.GameModel) }; } public void Stop() { if (!_isStarted) { throw new InvalidGameStateExcpetion("Game not started"); } _isStarted = false; _scope?.Dispose(); } public ThrowCommandData ParseThrowData(string stringData) { return ThrowCommandParser.Parse(stringData, _gh.FreePlayerSelection(), 0); } public bool FreePlayerSelection => _gh.FreePlayerSelection(); } }