From d07c9049e47ec93bead6a895967314d0073dbaa2 Mon Sep 17 00:00:00 2001 From: beo3000 Date: Thu, 27 Nov 2025 13:02:48 +0100 Subject: [PATCH] undo and redo gameModelState --- KoogleApp/Components/Pages/Game.razor | 6 - KoogleApp/Games/IGameService.cs | 2 +- .../Games/Training/GameTrainingService.cs | 17 +- KoogleApp/Games/Training/TrainingState.cs | 27 +- KoogleApp/Store/Game/Effects.cs | 8 +- KoogleApp/Store/Game/ThrowPanel/Actions.cs | 2 +- KoogleApp/Store/Game/ThrowPanel/Effects.cs | 3 +- KoogleApp/Store/Game/UndoRedo/Effects.cs | 4 +- KoogleApp/appdata.json | 309 ++++++++++++++++++ 9 files changed, 356 insertions(+), 22 deletions(-) create mode 100644 KoogleApp/appdata.json diff --git a/KoogleApp/Components/Pages/Game.razor b/KoogleApp/Components/Pages/Game.razor index 046d669..bd9167e 100644 --- a/KoogleApp/Components/Pages/Game.razor +++ b/KoogleApp/Components/Pages/Game.razor @@ -107,12 +107,6 @@ private bool isAuthenticated; - protected override void OnInitialized() - { - - base.OnInitialized(); - } - protected override void OnAfterRender(bool firstRender) { if (firstRender) diff --git a/KoogleApp/Games/IGameService.cs b/KoogleApp/Games/IGameService.cs index ec63cf5..8d83ef0 100644 --- a/KoogleApp/Games/IGameService.cs +++ b/KoogleApp/Games/IGameService.cs @@ -8,7 +8,7 @@ namespace KoogleApp.Games { [JsonDerivedType(typeof(TrainingState), typeDiscriminator: "TrainingState")] //[JsonDerivedType(typeof(v2), typeDiscriminator: "v2")] - public interface IGameModel + public interface IGameModel { } diff --git a/KoogleApp/Games/Training/GameTrainingService.cs b/KoogleApp/Games/Training/GameTrainingService.cs index 8d7250d..bf5baf7 100644 --- a/KoogleApp/Games/Training/GameTrainingService.cs +++ b/KoogleApp/Games/Training/GameTrainingService.cs @@ -53,17 +53,20 @@ namespace KoogleApp.Games.Training } var playerId = progress.BeforeParticipantsState.PlayerIds.First(); + + var gm = progress.GameModel as TrainingState; + var newModel = gm.DeepCopy(); - var ts = progress.GameModel as TrainingState; - var tm = ts.Throws[playerId]; - ts.Throws[playerId] = tm with + var oldThrowStatistic = newModel.Throws[playerId]; + + newModel.Throws[playerId] = oldThrowStatistic with { - ThrowCount = tm.ThrowCount + 1, - PinCount = tm.PinCount + progress.PinCount(), - CircleCount = tm.CircleCount + Convert.ToInt32(progress.IsCircle()) + ThrowCount = oldThrowStatistic.ThrowCount + 1, + PinCount = oldThrowStatistic.PinCount + progress.PinCount(), + CircleCount = oldThrowStatistic.CircleCount + Convert.ToInt32(progress.IsCircle()) }; - var newModel = ((TrainingState)(progress.GameModel)) with { Throws = ts.Throws }; + //var newModel = ((TrainingState)(progress.GameModel)) with { Throws = ts.Throws }; //res.Add(new UpdateTrainingStateAction(newModel)); res.Add(new GameModelChanged(newModel)); diff --git a/KoogleApp/Games/Training/TrainingState.cs b/KoogleApp/Games/Training/TrainingState.cs index 28081ab..bf4d573 100644 --- a/KoogleApp/Games/Training/TrainingState.cs +++ b/KoogleApp/Games/Training/TrainingState.cs @@ -1,5 +1,6 @@ using Fluxor; using System.Text.Json.Serialization; +using static MudBlazor.CategoryTypes; namespace KoogleApp.Games.Training { @@ -26,11 +27,31 @@ namespace KoogleApp.Games.Training } [FeatureState] - public record TrainingState(Dictionary Throws) : IGameModel + public record TrainingState(Dictionary Throws) : IGameModel { - public TrainingState():this([]) + public TrainingState() : this([]) { - + } } + + public static class TrainingStateExtension + { + public static TrainingState DeepCopy(this TrainingState State) + { + //// Array und alle Elemente kopieren + //var itemsCopy = Throws.Select(item => item with { }).ToArray(); + //return this with { Throws = itemsCopy }; + + + // Dictionary und alle Elemente kopieren + // Dictionary und alle Values kopieren + var itemsCopy = State.Throws.ToDictionary( + kvp => kvp.Key, // Key kopieren (int ist value type) + kvp => kvp.Value with { } // Value als Record kopieren + ); + return State with { Throws = itemsCopy }; + } + } + } diff --git a/KoogleApp/Store/Game/Effects.cs b/KoogleApp/Store/Game/Effects.cs index 3067f81..7bfe80f 100644 --- a/KoogleApp/Store/Game/Effects.cs +++ b/KoogleApp/Store/Game/Effects.cs @@ -1,5 +1,6 @@ using Fluxor; using KoogleApp.Services; +using KoogleApp.Store.Game.ThrowPanel; namespace KoogleApp.Store.Game { @@ -14,7 +15,12 @@ namespace KoogleApp.Store.Game var gameModel = current.Status.GameModel; dispatcher.Dispatch(new GameModelChanged(gameModel)); } - + } + + [EffectMethod] + public async Task HandleUpdateStateAfterUndoRedo(UpdateStateAfterUndoRedo action, IDispatcher dispatcher) + { + dispatcher.Dispatch(new GameModelChanged(action.GameModel)); } } } diff --git a/KoogleApp/Store/Game/ThrowPanel/Actions.cs b/KoogleApp/Store/Game/ThrowPanel/Actions.cs index 7b8280e..84747a2 100644 --- a/KoogleApp/Store/Game/ThrowPanel/Actions.cs +++ b/KoogleApp/Store/Game/ThrowPanel/Actions.cs @@ -39,7 +39,7 @@ namespace KoogleApp.Store.Game.ThrowPanel public record ThrowUpdateAction(ThrowPanelState State); - public record UpdateStateAfterUndoRedo(ThrowPanelState ThrowPanelState, ParticipantsState ParticipantsState); + public record UpdateStateAfterUndoRedo(ThrowPanelState ThrowPanelState, ParticipantsState ParticipantsState, IGameModel GameModel); public record EnsureBeforeThrowStatusAction(ParticipantsState ParticipantsState, IGameModel GameModel); diff --git a/KoogleApp/Store/Game/ThrowPanel/Effects.cs b/KoogleApp/Store/Game/ThrowPanel/Effects.cs index 2a65d72..ae12df7 100644 --- a/KoogleApp/Store/Game/ThrowPanel/Effects.cs +++ b/KoogleApp/Store/Game/ThrowPanel/Effects.cs @@ -15,6 +15,7 @@ using System; using System.Diagnostics; using System.Text.Json; using KoogleApp.Games.Training; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; namespace KoogleApp.Store.Game.ThrowPanel { @@ -168,7 +169,7 @@ namespace KoogleApp.Store.Game.ThrowPanel StartParams: dataService.StartParams, GameModel: beforeStates.Status.GameModel, NextThrowState: nextState); - + dispatcher.Dispatch(generalGameProgress); // currently unused //var participants = throwAction.ParticipantsState; diff --git a/KoogleApp/Store/Game/UndoRedo/Effects.cs b/KoogleApp/Store/Game/UndoRedo/Effects.cs index 37a7617..85bb3b5 100644 --- a/KoogleApp/Store/Game/UndoRedo/Effects.cs +++ b/KoogleApp/Store/Game/UndoRedo/Effects.cs @@ -33,7 +33,7 @@ namespace KoogleApp.Store.Game.UndoRedo if (success) { var currentData = _dataService.GetCurrentData(); - dispatcher.Dispatch(new UpdateStateAfterUndoRedo(currentData.Status.ThrowPanelState, currentData.Status.ParticipantsState)); + dispatcher.Dispatch(new UpdateStateAfterUndoRedo(currentData.Status.ThrowPanelState, currentData.Status.ParticipantsState, currentData.Status.GameModel)); } dispatcher.Dispatch(new UpdateUndoRedoStateAction()); @@ -48,7 +48,7 @@ namespace KoogleApp.Store.Game.UndoRedo if (success) { var currentData = _dataService.GetCurrentData(); - dispatcher.Dispatch(new UpdateStateAfterUndoRedo(currentData.Status.ThrowPanelState, currentData.Status.ParticipantsState)); + dispatcher.Dispatch(new UpdateStateAfterUndoRedo(currentData.Status.ThrowPanelState, currentData.Status.ParticipantsState, currentData.Status.GameModel)); } dispatcher.Dispatch(new UpdateUndoRedoStateAction()); diff --git a/KoogleApp/appdata.json b/KoogleApp/appdata.json new file mode 100644 index 0000000..69cd8a4 --- /dev/null +++ b/KoogleApp/appdata.json @@ -0,0 +1,309 @@ +{ + "CurrentData": { + "Status": { + "StartParams": null, + "ThrowPanelState": { + "IsStated": true, + "BellValue": false, + "Pin1State": 0, + "Pin2State": 0, + "Pin3State": 0, + "Pin4State": 0, + "Pin5State": 0, + "Pin6State": 0, + "Pin7State": 0, + "Pin8State": 0, + "Pin9State": 0, + "ThrowsPerRound": 1, + "ThrowCounterPerRound": 1, + "ThrowMode": 0, + "ThrowPanelStateStatus": 3, + "ThrowCounter": 1, + "DayId": 35 + }, + "ParticipantsState": { + "PlayerIds": [ + 3, + 10, + 12, + 9, + 5 + ], + "Eliminated": [] + }, + "GameModel": { + "$type": "TrainingState", + "Throws": { + "5": { + "PlayerId": 5, + "TeamNr": 0, + "PinCount": 1, + "CircleCount": 0, + "SinkCount": 0, + "StrikeCount": 0, + "ClearedCount": 0, + "ThrowCount": 1, + "BellCount": 0 + }, + "3": { + "PlayerId": 3, + "TeamNr": 0, + "PinCount": 0, + "CircleCount": 0, + "SinkCount": 0, + "StrikeCount": 0, + "ClearedCount": 0, + "ThrowCount": 0, + "BellCount": 0 + }, + "10": { + "PlayerId": 10, + "TeamNr": 0, + "PinCount": 0, + "CircleCount": 0, + "SinkCount": 0, + "StrikeCount": 0, + "ClearedCount": 0, + "ThrowCount": 0, + "BellCount": 0 + }, + "12": { + "PlayerId": 12, + "TeamNr": 0, + "PinCount": 0, + "CircleCount": 0, + "SinkCount": 0, + "StrikeCount": 0, + "ClearedCount": 0, + "ThrowCount": 0, + "BellCount": 0 + }, + "9": { + "PlayerId": 9, + "TeamNr": 0, + "PinCount": 0, + "CircleCount": 0, + "SinkCount": 0, + "StrikeCount": 0, + "ClearedCount": 0, + "ThrowCount": 0, + "BellCount": 0 + } + } + } + }, + "Version": 3, + "LastModified": "2025-11-27T08:57:54.4108241+01:00", + "LastModifiedBy": "test1@test.de" + }, + "UndoHistory": [ + { + "Status": { + "StartParams": null, + "ThrowPanelState": { + "IsStated": true, + "BellValue": false, + "Pin1State": 0, + "Pin2State": 0, + "Pin3State": 0, + "Pin4State": 0, + "Pin5State": 0, + "Pin6State": 0, + "Pin7State": 0, + "Pin8State": 0, + "Pin9State": 1, + "ThrowsPerRound": 1, + "ThrowCounterPerRound": 1, + "ThrowMode": 0, + "ThrowPanelStateStatus": 2, + "ThrowCounter": 0, + "DayId": 35 + }, + "ParticipantsState": { + "PlayerIds": [ + 5, + 3, + 10, + 12, + 9 + ], + "Eliminated": [] + }, + "GameModel": { + "$type": "TrainingState", + "Throws": { + "5": { + "PlayerId": 5, + "TeamNr": 0, + "PinCount": 0, + "CircleCount": 0, + "SinkCount": 0, + "StrikeCount": 0, + "ClearedCount": 0, + "ThrowCount": 0, + "BellCount": 0 + }, + "3": { + "PlayerId": 3, + "TeamNr": 0, + "PinCount": 0, + "CircleCount": 0, + "SinkCount": 0, + "StrikeCount": 0, + "ClearedCount": 0, + "ThrowCount": 0, + "BellCount": 0 + }, + "10": { + "PlayerId": 10, + "TeamNr": 0, + "PinCount": 0, + "CircleCount": 0, + "SinkCount": 0, + "StrikeCount": 0, + "ClearedCount": 0, + "ThrowCount": 0, + "BellCount": 0 + }, + "12": { + "PlayerId": 12, + "TeamNr": 0, + "PinCount": 0, + "CircleCount": 0, + "SinkCount": 0, + "StrikeCount": 0, + "ClearedCount": 0, + "ThrowCount": 0, + "BellCount": 0 + }, + "9": { + "PlayerId": 9, + "TeamNr": 0, + "PinCount": 0, + "CircleCount": 0, + "SinkCount": 0, + "StrikeCount": 0, + "ClearedCount": 0, + "ThrowCount": 0, + "BellCount": 0 + } + } + } + }, + "Version": 2, + "LastModified": "2025-11-27T08:57:54.3513899+01:00", + "LastModifiedBy": "test1@test.de" + }, + { + "Status": { + "StartParams": { + "DayId": 35, + "ThrowMode": 0, + "ThrowsPerRound": 1, + "Participants": [ + 5, + 3, + 10, + 12, + 9 + ], + "ParticipantsMode": 0, + "KnownGameType": "GameTraining" + }, + "ThrowPanelState": { + "IsStated": true, + "BellValue": false, + "Pin1State": 0, + "Pin2State": 0, + "Pin3State": 0, + "Pin4State": 0, + "Pin5State": 0, + "Pin6State": 0, + "Pin7State": 0, + "Pin8State": 0, + "Pin9State": 0, + "ThrowsPerRound": 1, + "ThrowCounterPerRound": 1, + "ThrowMode": 0, + "ThrowPanelStateStatus": 1, + "ThrowCounter": 0, + "DayId": 35 + }, + "ParticipantsState": { + "PlayerIds": [ + 5, + 3, + 10, + 12, + 9 + ], + "Eliminated": [] + }, + "GameModel": { + "$type": "TrainingState", + "Throws": { + "5": { + "PlayerId": 5, + "TeamNr": 0, + "PinCount": 0, + "CircleCount": 0, + "SinkCount": 0, + "StrikeCount": 0, + "ClearedCount": 0, + "ThrowCount": 0, + "BellCount": 0 + }, + "3": { + "PlayerId": 3, + "TeamNr": 0, + "PinCount": 0, + "CircleCount": 0, + "SinkCount": 0, + "StrikeCount": 0, + "ClearedCount": 0, + "ThrowCount": 0, + "BellCount": 0 + }, + "10": { + "PlayerId": 10, + "TeamNr": 0, + "PinCount": 0, + "CircleCount": 0, + "SinkCount": 0, + "StrikeCount": 0, + "ClearedCount": 0, + "ThrowCount": 0, + "BellCount": 0 + }, + "12": { + "PlayerId": 12, + "TeamNr": 0, + "PinCount": 0, + "CircleCount": 0, + "SinkCount": 0, + "StrikeCount": 0, + "ClearedCount": 0, + "ThrowCount": 0, + "BellCount": 0 + }, + "9": { + "PlayerId": 9, + "TeamNr": 0, + "PinCount": 0, + "CircleCount": 0, + "SinkCount": 0, + "StrikeCount": 0, + "ClearedCount": 0, + "ThrowCount": 0, + "BellCount": 0 + } + } + } + }, + "Version": 1, + "LastModified": "2025-11-27T07:56:55.6527668Z", + "LastModifiedBy": "test1@test.de" + } + ], + "RedoHistory": [] +} \ No newline at end of file