This commit is contained in:
Christian Kauer 2023-12-31 10:38:21 +01:00
parent 0331e7b2c3
commit a69a8f450d
10 changed files with 133 additions and 118 deletions

View File

@ -23,29 +23,25 @@ namespace GameHandler
_expenseRepository = expenseRepository; _expenseRepository = expenseRepository;
} }
public async Task<ExpenseModel> HandleGameExenseEventArgs(GameExenseEventArgs gameExenseEventArgs, ExpenseModel expenseModelToAppend) public async Task<IEnumerable<PlayerExpense>> HandleGameExenseEventArgs(GameExenseEventArgs gameExenseEventArgs)
{ {
if (!gameExenseEventArgs.PlayerIds.Any(_ => _ == gameExenseEventArgs.PlayerId)) if (!gameExenseEventArgs.PlayerIds.Any(_ => _ == gameExenseEventArgs.PlayerId))
{ {
throw new InvalidPinThrowException($"Player {gameExenseEventArgs.PlayerId} not found"); throw new InvalidPinThrowException($"Player {gameExenseEventArgs.PlayerId} not found");
} }
List<PlayerExpense> memberExpenses = PrepareResult(ref expenseModelToAppend); List<PlayerExpense> memberExpenses = new List<PlayerExpense>(); //PrepareResult(ref expenseModelToAppend);
var triggers = gameExenseEventArgs.Triggers; var triggers = gameExenseEventArgs.Triggers;
await AssignExpenses(gameExenseEventArgs.PlayerId, gameExenseEventArgs.PlayerIds, memberExpenses, triggers, await AssignExpenses(gameExenseEventArgs.PlayerId, gameExenseEventArgs.PlayerIds, memberExpenses, triggers);
gameExenseEventArgs.GameStateId);
return expenseModelToAppend with { MemberExpenses = memberExpenses.ToArray() }; return memberExpenses;
} }
private async Task AssignExpenses(int playerId, int[] playerIds, private async Task AssignExpenses(int playerId, int[] playerIds, List<PlayerExpense> memberExpenses, ExpenseTrigger[] triggers)
List<PlayerExpense> memberExpenses, ExpenseTrigger[] triggers,
Guid gameStateId)
{ {
var list = await _expenseRepository.GetAll(); var list = await _expenseRepository.GetAll();
var destExpenses = list var destExpenses = list.Where(_ => _.ExpenseTriggers.Any(et => triggers.Any(et2 => et2 == et)));
.Where(_ => _.ExpenseTriggers.Any(et => triggers.Any(et2 => et2 == et)));
var inversePlayers = playerIds.Where(_ => _ != playerId); var inversePlayers = playerIds.Where(_ => _ != playerId);
foreach (var expense in destExpenses) foreach (var expense in destExpenses)
@ -54,41 +50,39 @@ namespace GameHandler
{ {
foreach (var player in inversePlayers) foreach (var player in inversePlayers)
{ {
memberExpenses.Add(PlayerExpense.Create(player, expense, gameStateId)); memberExpenses.Add(PlayerExpense.Create(player, expense));
} }
} }
else else
{ {
memberExpenses.Add(PlayerExpense.Create(playerId, expense, gameStateId)); memberExpenses.Add(PlayerExpense.Create(playerId, expense));
} }
} }
} }
public async Task<ExpenseModel> CheckThrow(BoardState currentState, PinThrow pinThrow, int[] PlayerIds, public async Task<IEnumerable<PlayerExpense>> CheckThrow(BoardState currentState, PinThrow pinThrow, int[] PlayerIds)
Guid gameStateId,
ExpenseModel expenseModelToAppend = null)
{ {
if (!PlayerIds.Any(_ => _ == pinThrow.PlayerId)) if (!PlayerIds.Any(_ => _ == pinThrow.PlayerId))
{ {
throw new InvalidPinThrowException($"Player {pinThrow.PlayerId} not found"); throw new InvalidPinThrowException($"Player {pinThrow.PlayerId} not found");
} }
List<PlayerExpense> memberExpenses = PrepareResult(ref expenseModelToAppend); List<PlayerExpense> memberExpenses = new List<PlayerExpense>(); //PrepareResult(ref expenseModelToAppend);
var triggers = pinThrow.GetExpenseTriggers(currentState); var triggers = pinThrow.GetExpenseTriggers(currentState);
await AssignExpenses(pinThrow.PlayerId, PlayerIds, memberExpenses, triggers, gameStateId); await AssignExpenses(pinThrow.PlayerId, PlayerIds, memberExpenses, triggers);
return expenseModelToAppend with { MemberExpenses = memberExpenses.ToArray() };
}
private static List<PlayerExpense> PrepareResult(ref ExpenseModel expenseModelToAppend)
{
if (expenseModelToAppend == null)
{
expenseModelToAppend = new ExpenseModel(Array.Empty<PlayerExpense>());
}
var memberExpenses = new List<PlayerExpense>(expenseModelToAppend.MemberExpenses);
return memberExpenses; return memberExpenses;
} }
//private static List<PlayerExpense> PrepareResult(ref ExpenseModel expenseModelToAppend)
//{
// if (expenseModelToAppend == null)
// {
// expenseModelToAppend = new ExpenseModel(Array.Empty<PlayerExpense>());
// }
// var memberExpenses = new List<PlayerExpense>(expenseModelToAppend.MemberExpenses);
// return memberExpenses;
//}
} }
} }

View File

@ -11,15 +11,13 @@ namespace GameHandler
{ {
public int[] PlayerIds { get; set; } public int[] PlayerIds { get; set; }
public int PlayerId { get; set; } public int PlayerId { get; set; }
public Guid GameStateId { get; set; }
public ExpenseTrigger[] Triggers { get; set; } public ExpenseTrigger[] Triggers { get; set; }
public GameExenseEventArgs(int playerId, ExpenseTrigger[] triggers, int[] playerIds, Guid gameStateId) public GameExenseEventArgs(int playerId, ExpenseTrigger[] triggers, int[] playerIds)
{ {
PlayerId = playerId; PlayerId = playerId;
Triggers = triggers; Triggers = triggers;
PlayerIds = playerIds; PlayerIds = playerIds;
GameStateId = gameStateId;
} }
} }
} }

View File

@ -73,17 +73,17 @@ namespace GameHandler.DeathGame
} }
public IGameModel Update(PinThrow pinThrow, IGameModel gameModel, BoardState boardStateBeforeUpdate, public IGameModel Update(PinThrow pinThrow, IGameModel gameModel, BoardState boardStateBeforeUpdate,
ThrowState throwStateAfterUpdate, Guid gameStateId) ThrowState throwStateAfterUpdate)
{ {
var isTrowIntoAllPins = boardStateBeforeUpdate.PinPicture.UpCount == 9; var isTrowIntoAllPins = boardStateBeforeUpdate.PinPicture.UpCount == 9;
var boardCleared = pinThrow.IsCleared; var boardCleared = pinThrow.IsCleared;
var firstThrowInRound = throwStateAfterUpdate.ThrowCount == 1; var firstThrowInRound = throwStateAfterUpdate.ThrowCount == 1;
return CalcNextModel(gameModel as DeathGameModel, pinThrow.PinCount, return CalcNextModel(gameModel as DeathGameModel, pinThrow.PinCount,
isTrowIntoAllPins, boardCleared, firstThrowInRound, gameStateId); isTrowIntoAllPins, boardCleared, firstThrowInRound);
} }
public DeathGameModel CalcNextModel(DeathGameModel gm, int pinCount, bool isTrowIntoAllPins, public DeathGameModel CalcNextModel(DeathGameModel gm, int pinCount, bool isTrowIntoAllPins,
bool boardCleared, bool firstThrowInRound, Guid gameStateId) bool boardCleared, bool firstThrowInRound)
{ {
var current = gm.Coffins.First(); var current = gm.Coffins.First();
var next = gm.Coffins.Skip(1).First(); var next = gm.Coffins.Skip(1).First();
@ -96,7 +96,7 @@ namespace GameHandler.DeathGame
incX = true; incX = true;
if ((pinCount < 3) && firstThrowInRound) if ((pinCount < 3) && firstThrowInRound)
{ {
OnFirstThrowFailed(gm, current, gameStateId); OnFirstThrowFailed(gm, current);
incLine = true; incLine = true;
} }
} }
@ -195,9 +195,9 @@ namespace GameHandler.DeathGame
return result; return result;
} }
private void OnFirstThrowFailed(DeathGameModel gm, Coffin current, Guid gameStateId) private void OnFirstThrowFailed(DeathGameModel gm, Coffin current)
{ {
OnGameExpenseOccured(new GameExenseEventArgs(current.PlayerId, new[] { ExpenseTrigger.FirstThrowFail }, gm.PlayerIds, gameStateId)); OnGameExpenseOccured(new GameExenseEventArgs(current.PlayerId, new[] { ExpenseTrigger.FirstThrowFail }, gm.PlayerIds));
} }
public static string GameName() public static string GameName()

View File

@ -34,7 +34,7 @@ namespace GameHandler.GameHandler
} }
public IGameModel Update(PinThrow pinThrow, IGameModel gameModel, BoardState boardStateBeforeUpdate, public IGameModel Update(PinThrow pinThrow, IGameModel gameModel, BoardState boardStateBeforeUpdate,
ThrowState throwStateAfterUpdate, Guid gameStateId) ThrowState throwStateAfterUpdate)
{ {
if (gameModel == null) if (gameModel == null)
{ {

View File

@ -69,8 +69,6 @@ namespace GameHandler
InitGameServiceBehaviour(gameName); InitGameServiceBehaviour(gameName);
var state = await InitGameState(playerIds, gameSettings, gameName); var state = await InitGameState(playerIds, gameSettings, gameName);
await _gameStateHandler.Add(state);
await _gameStateHandler.Add(ExpenseModel.Create());
await _gameStateHandler.Save(); await _gameStateHandler.Save();
return state; return state;
@ -82,8 +80,11 @@ namespace GameHandler
var throwState = ThrowState.Create(_gh.ThrowMode(), _gh.ThrowsPerRount()); var throwState = ThrowState.Create(_gh.ThrowMode(), _gh.ThrowsPerRount());
_game = await _gameStateHandler.CreateNewGame(gameName); _game = await _gameStateHandler.CreateNewGame(gameName);
_gameStateHandler.StartNewState();
var state = GameState.Create(_game.Id, gameName, throwState, _gh.GetCurrentPlayerId(gm), gm); var state = GameState.Create(_game.Id, gameName, throwState, _gh.GetCurrentPlayerId(gm), gm);
_gameStateHandler.Add(state);
return state; return state;
} }
@ -99,8 +100,8 @@ namespace GameHandler
private void _gh_GameExpenseOccured(object? sender, EventArgs e) private void _gh_GameExpenseOccured(object? sender, EventArgs e)
{ {
var expenseModel = _eh.HandleGameExenseEventArgs(e as GameExenseEventArgs, _gameStateHandler.ExpenseModel).Result; var items = _eh.HandleGameExenseEventArgs(e as GameExenseEventArgs).Result;
_gameStateHandler.Add(expenseModel); _gameStateHandler.Add(items);
//_lastState = _lastState with { ExpenseModel = expenseModel }; //_lastState = _lastState with { ExpenseModel = expenseModel };
} }
@ -111,24 +112,25 @@ namespace GameHandler
throw new InvalidGameStateExcpetion("Game not started"); throw new InvalidGameStateExcpetion("Game not started");
} }
_gameStateHandler.StartNewState();
var lastGameState = _gameStateHandler.GameState; var lastGameState = _gameStateHandler.GameState;
var nextGameStateId = Guid.NewGuid();
var boardStateBeforeUpdate = lastGameState.ThrowState.BoardState; var boardStateBeforeUpdate = lastGameState.ThrowState.BoardState;
pinThrow = AutoCompletePlayerId(pinThrow); pinThrow = AutoCompletePlayerId(pinThrow);
var throwStateAfterUpdate = _th.Update(lastGameState.ThrowState, pinThrow); var throwStateAfterUpdate = _th.Update(lastGameState.ThrowState, pinThrow);
var gameModel = _gh.Update(pinThrow, lastGameState.GameModel, boardStateBeforeUpdate, throwStateAfterUpdate, nextGameStateId); var gameModel = _gh.Update(pinThrow, lastGameState.GameModel, boardStateBeforeUpdate, throwStateAfterUpdate);
var expenseModel = await _eh.CheckThrow(throwStateAfterUpdate.BoardState, pinThrow, gameModel.PlayerIds, nextGameStateId, var expenseModel = await _eh.CheckThrow(throwStateAfterUpdate.BoardState, pinThrow, gameModel.PlayerIds);
_gameStateHandler.ExpenseModel);
var newGameState = lastGameState with { Id = nextGameStateId, ThrowState = throwStateAfterUpdate, GameModel = gameModel, NextPlayerId = _gh.GetCurrentPlayerId(gameModel) }; var newGameState = lastGameState with { Id = _gameStateHandler.NextGameStateId, ThrowState = throwStateAfterUpdate, GameModel = gameModel, NextPlayerId = _gh.GetCurrentPlayerId(gameModel) };
_gameStateHandler.Add(newGameState);
_gameStateHandler.Add(expenseModel);
await _gameStateHandler.Add(newGameState);
await _gameStateHandler.Add(expenseModel);
await _gameStateHandler.Save(); await _gameStateHandler.Save();
// todo: bei undo wird gamestate nicht korrekt gelöscht
return newGameState; return newGameState;
} }

View File

@ -27,11 +27,11 @@ namespace GameHandler
private Guid _gameStateId; private Guid _gameStateId;
private List<GameStateHandlerItem<GameState>> gameStates = new List<GameStateHandlerItem<GameState>>(); private List<GameStateHandlerItem<GameState>> gameStates = new List<GameStateHandlerItem<GameState>>();
private List<GameStateHandlerItem<ExpenseModel>> expenseModels = new List<GameStateHandlerItem<ExpenseModel>>(); //private List<GameStateHandlerItem<ExpenseModel>> expenseModels = new List<GameStateHandlerItem<ExpenseModel>>();
private List<GameStateHandlerItem<PlayerExpense>> memberExpenses = new List<GameStateHandlerItem<PlayerExpense>>(); private List<GameStateHandlerItem<PlayerExpense>> memberExpenses = new List<GameStateHandlerItem<PlayerExpense>>();
private List<GameStateHandlerItem<GameState>> redoableGameStates = new List<GameStateHandlerItem<GameState>>(); private List<GameStateHandlerItem<GameState>> redoableGameStates = new List<GameStateHandlerItem<GameState>>();
private List<GameStateHandlerItem<ExpenseModel>> redoableExpenseModels = new List<GameStateHandlerItem<ExpenseModel>>(); //private List<GameStateHandlerItem<ExpenseModel>> redoableExpenseModels = new List<GameStateHandlerItem<ExpenseModel>>();
private List<GameStateHandlerItem<PlayerExpense>> redoableMeberExpenses = new List<GameStateHandlerItem<PlayerExpense>>(); private List<GameStateHandlerItem<PlayerExpense>> redoableMeberExpenses = new List<GameStateHandlerItem<PlayerExpense>>();
private IGameRepository _gameRepository; private IGameRepository _gameRepository;
@ -43,18 +43,18 @@ namespace GameHandler
_expenseRepository = expenseRepository; _expenseRepository = expenseRepository;
} }
public ExpenseModel ExpenseModel //public ExpenseModel ExpenseModel
{ //{
get // get
{ // {
var res = expenseModels.LastOrDefault(); // var res = expenseModels.LastOrDefault();
if (res != null) // if (res != null)
{ // {
return res.Data; // return res.Data;
} // }
return null; // return null;
} // }
} //}
public GameState GameState public GameState GameState
{ {
@ -69,21 +69,50 @@ namespace GameHandler
} }
} }
internal async Task Add(ExpenseModel expenseModel) public Guid NextGameStateId
{ {
if (ExpenseModel != null) get
{ {
if (!expenseModel.Equals(ExpenseModel)) if (_gameStateId == Guid.Empty)
{ {
expenseModels.Add(new GameStateHandlerItem<ExpenseModel>(_gameStateId, expenseModel)); _gameStateId = Guid.NewGuid();
} }
return _gameStateId;
} }
else }
public Guid StartNewState()
{
_gameStateId = Guid.NewGuid();
return _gameStateId;
}
internal void Add(IEnumerable<PlayerExpense> playerExpenses)
{
foreach (var playerExpense in playerExpenses)
{ {
expenseModels.Add(new GameStateHandlerItem<ExpenseModel>(_gameStateId, expenseModel)); Add(playerExpense);
} }
} }
internal void Add(PlayerExpense playerExpense)
{
var model = playerExpense with { GamestateId = _gameStateId };
memberExpenses.Add(new GameStateHandlerItem<PlayerExpense>(_gameStateId, model));
}
internal void Add(GameState newState)
{
if (newState.Id != Guid.Empty && newState.Id != NextGameStateId)
{
throw new InvalidDataException("GameState is not new");
}
var model = newState with { Id = _gameStateId, Counter = gameStates.Count + 1 };
var item = new GameStateHandlerItem<GameState>(_gameStateId, model);
gameStates.Add(item);
}
public async Task Save() public async Task Save()
{ {
await DeleteRedoableStates(); // first delete undone items - otherwise ID is not unique in DB await DeleteRedoableStates(); // first delete undone items - otherwise ID is not unique in DB
@ -91,17 +120,22 @@ namespace GameHandler
var gameState = gameStates.FirstOrDefault(_ => _.GameStateId == _gameStateId); var gameState = gameStates.FirstOrDefault(_ => _.GameStateId == _gameStateId);
await Save(gameState); await Save(gameState);
var expenseModelItem = expenseModels.FirstOrDefault(_ => _.GameStateId == _gameStateId); foreach (var memberExpense in memberExpenses.Where(_ => _.GameStateId == _gameStateId))
if (expenseModelItem != null)
{ {
var expenseModel = expenseModelItem.Data; await Save(memberExpense);
foreach (var memberExpense in expenseModel.MemberExpenses.Where(_ => _.GamestateId == _gameStateId))
{
var item = new GameStateHandlerItem<PlayerExpense>(memberExpense.GamestateId, memberExpense);
memberExpenses.Add(item);
await Save(item);
}
} }
//var expenseModelItem = expenseModels.FirstOrDefault(_ => _.GameStateId == _gameStateId);
//if (expenseModelItem != null)
//{
// var expenseModel = expenseModelItem.Data;
// foreach (var memberExpense in expenseModel.MemberExpenses.Where(_ => _.GamestateId == _gameStateId))
// {
// var item = new GameStateHandlerItem<PlayerExpense>(memberExpense.GamestateId, memberExpense);
// memberExpenses.Add(item);
// await Save(item);
// }
//}
} }
@ -120,18 +154,11 @@ namespace GameHandler
redoableMeberExpenses.Clear(); redoableMeberExpenses.Clear();
} }
redoableExpenseModels.Clear(); //redoableExpenseModels.Clear();
} }
internal async Task Add(GameState newState)
{
if (!newState.Equals(GameState))
{
_gameStateId = newState.Id;
var item = new GameStateHandlerItem<GameState>(_gameStateId, newState with { Counter = gameStates.Count + 1 });
gameStates.Add(item);
}
}
private async Task Save(GameStateHandlerItem<PlayerExpense> item) private async Task Save(GameStateHandlerItem<PlayerExpense> item)
{ {
await _expenseRepository.Save(item.Data); await _expenseRepository.Save(item.Data);
@ -154,11 +181,11 @@ namespace GameHandler
var redoId = redoableGameStates.Last().GameStateId; var redoId = redoableGameStates.Last().GameStateId;
gameStates.AddRange(redoableGameStates.Where(_ => _.GameStateId == redoId)); gameStates.AddRange(redoableGameStates.Where(_ => _.GameStateId == redoId));
expenseModels.AddRange(redoableExpenseModels.Where(_ => _.GameStateId == redoId)); //expenseModels.AddRange(redoableExpenseModels.Where(_ => _.GameStateId == redoId));
memberExpenses.AddRange(redoableMeberExpenses.Where(_ => _.GameStateId == redoId)); memberExpenses.AddRange(redoableMeberExpenses.Where(_ => _.GameStateId == redoId));
redoableGameStates.RemoveAll(_ => _.GameStateId == redoId); redoableGameStates.RemoveAll(_ => _.GameStateId == redoId);
redoableExpenseModels.RemoveAll(_ => _.GameStateId == redoId); //redoableExpenseModels.RemoveAll(_ => _.GameStateId == redoId);
redoableMeberExpenses.RemoveAll(_ => _.GameStateId == redoId); redoableMeberExpenses.RemoveAll(_ => _.GameStateId == redoId);
} }
@ -174,11 +201,11 @@ namespace GameHandler
} }
redoableGameStates.AddRange(gameStates.Where(_ => _.GameStateId == _gameStateId)); redoableGameStates.AddRange(gameStates.Where(_ => _.GameStateId == _gameStateId));
redoableExpenseModels.AddRange(expenseModels.Where(_ => _.GameStateId == _gameStateId)); //redoableExpenseModels.AddRange(expenseModels.Where(_ => _.GameStateId == _gameStateId));
redoableMeberExpenses.AddRange(memberExpenses.Where(_ => _.GameStateId == _gameStateId)); redoableMeberExpenses.AddRange(memberExpenses.Where(_ => _.GameStateId == _gameStateId));
gameStates.RemoveAll(_ => _.GameStateId == _gameStateId); gameStates.RemoveAll(_ => _.GameStateId == _gameStateId);
expenseModels.RemoveAll(_ => _.GameStateId == _gameStateId); //expenseModels.RemoveAll(_ => _.GameStateId == _gameStateId);
memberExpenses.RemoveAll(_ => _.GameStateId == _gameStateId); memberExpenses.RemoveAll(_ => _.GameStateId == _gameStateId);
_gameStateId = gameStates.Last().GameStateId; _gameStateId = gameStates.Last().GameStateId;

View File

@ -23,7 +23,7 @@ namespace GameModel.Contract
int GetCurrentPlayerId(IGameModel gameModel); int GetCurrentPlayerId(IGameModel gameModel);
IGameModel Update(PinThrow pinThrow, IGameModel gameModel, BoardState boardStateBeforeUpdate, IGameModel Update(PinThrow pinThrow, IGameModel gameModel, BoardState boardStateBeforeUpdate,
ThrowState throwStateAfterUpdate, Guid gameStateId); ThrowState throwStateAfterUpdate);
event EventHandler GameExpenseOccured; event EventHandler GameExpenseOccured;
} }

View File

@ -6,20 +6,20 @@ using System.Threading.Tasks;
namespace GameModel namespace GameModel
{ {
public record ExpenseModel(PlayerExpense[] MemberExpenses) //public record ExpenseModel(PlayerExpense[] MemberExpenses)
{ //{
public virtual bool Equals(ExpenseModel other) // public virtual bool Equals(ExpenseModel other)
{ // {
if (ReferenceEquals(null, other)) return false; // if (ReferenceEquals(null, other)) return false;
return MemberExpenses.SequenceEqual(other.MemberExpenses); // return MemberExpenses.SequenceEqual(other.MemberExpenses);
} // }
public override int GetHashCode() => MemberExpenses.GetHashCode(); // public override int GetHashCode() => MemberExpenses.GetHashCode();
public static ExpenseModel Create() // public static ExpenseModel Create()
{ // {
return new ExpenseModel(Array.Empty<PlayerExpense>()); // return new ExpenseModel(Array.Empty<PlayerExpense>());
} // }
} //}
} }

View File

@ -12,7 +12,7 @@ namespace GameModel
{ {
public static GameState Create(Guid gameId, string gameName, ThrowState throwState, int nextPlayerId, IGameModel gameModel) public static GameState Create(Guid gameId, string gameName, ThrowState throwState, int nextPlayerId, IGameModel gameModel)
{ {
return new GameState(Guid.NewGuid(), gameId, gameName, throwState, nextPlayerId, gameModel, 0); return new GameState(Guid.Empty, gameId, gameName, throwState, nextPlayerId, gameModel, 0);
} }
} }
} }

View File

@ -14,11 +14,5 @@ namespace GameModel
return new PlayerExpense(Guid.NewGuid(), playerId, expense.Id, expense.ExpenseType, return new PlayerExpense(Guid.NewGuid(), playerId, expense.Id, expense.ExpenseType,
DateTime.Now, expense.Price, expense.Name, Guid.Empty); DateTime.Now, expense.Price, expense.Name, Guid.Empty);
} }
public static PlayerExpense Create(int playerId, Expense expense, Guid gameStateId)
{
return new PlayerExpense(Guid.NewGuid(), playerId, expense.Id, expense.ExpenseType,
DateTime.Now, expense.Price, expense.Name, gameStateId);
}
} }
} }