From b3b4d01130659f945deef54534f50253ff204317 Mon Sep 17 00:00:00 2001 From: beo3000 Date: Thu, 27 Nov 2025 18:06:45 +0100 Subject: [PATCH] support different setup models --- .../Components/Controls/ThrowPanelMenu.razor | 3 +- .../Components/Dialogs/StartGameDialog.razor | 26 ++++++++---- KoogleApp/Components/Pages/Game.razor | 2 +- KoogleApp/Games/IGameService.cs | 29 +++++++++++-- KoogleApp/Games/IKnownGame.cs | 2 + KoogleApp/Games/Shit/Setup.razor | 5 +++ KoogleApp/Games/Shit/ShitBoard.razor | 4 ++ KoogleApp/Games/Shit/ShitGame.cs | 14 +++++++ KoogleApp/Games/Shit/ShitGameService.cs | 26 ++++++++++++ KoogleApp/Games/Shit/ShitState.cs | 15 +++++++ KoogleApp/Games/Training/Actions.cs | 4 -- KoogleApp/Games/Training/GameTraining.cs | 2 + .../Games/Training/GameTrainingService.cs | 10 ++--- KoogleApp/Games/Training/TrainingState.cs | 4 ++ KoogleApp/Model/GameStatus.cs | 2 +- KoogleApp/Model/StartParams.cs | 18 ++++---- KoogleApp/Services/GameStatusDataService.cs | 9 ++-- KoogleApp/Store/Game/Setup/Effects.cs | 2 +- KoogleApp/Store/Game/ThrowPanel/Actions.cs | 4 +- KoogleApp/Store/Game/ThrowPanel/Effects.cs | 2 +- KoogleApp/appdata.json | 41 ++++++++++--------- 21 files changed, 161 insertions(+), 63 deletions(-) create mode 100644 KoogleApp/Games/Shit/Setup.razor create mode 100644 KoogleApp/Games/Shit/ShitBoard.razor create mode 100644 KoogleApp/Games/Shit/ShitGame.cs create mode 100644 KoogleApp/Games/Shit/ShitGameService.cs create mode 100644 KoogleApp/Games/Shit/ShitState.cs delete mode 100644 KoogleApp/Games/Training/Actions.cs diff --git a/KoogleApp/Components/Controls/ThrowPanelMenu.razor b/KoogleApp/Components/Controls/ThrowPanelMenu.razor index 6396924..eb31503 100644 --- a/KoogleApp/Components/Controls/ThrowPanelMenu.razor +++ b/KoogleApp/Components/Controls/ThrowPanelMenu.razor @@ -1,4 +1,5 @@ @using KoogleApp.Components.Dialogs +@using KoogleApp.Games @using KoogleApp.Model @using KoogleApp.Store.DayFeature @using KoogleApp.Store.Game.Participants @@ -59,7 +60,7 @@ var dialog = await DialogService.ShowAsync("Spiel starten", parameters, options); var result = await dialog.Result; - var startParams = result.Data as StartParams; + var startParams = result.Data as IGameSetupModel; if (!result.Canceled) { var action = new StartStopAction(ThrowPanelState.Value, startParams); diff --git a/KoogleApp/Components/Dialogs/StartGameDialog.razor b/KoogleApp/Components/Dialogs/StartGameDialog.razor index acba049..9ba70eb 100644 --- a/KoogleApp/Components/Dialogs/StartGameDialog.razor +++ b/KoogleApp/Components/Dialogs/StartGameDialog.razor @@ -101,13 +101,23 @@ private void Start() { - MudDialog.Close(DialogResult.Ok(new StartParams( - DayState.Value.Id, - SetupState.Value.ThrowMode, - SetupState.Value.ThrowsPerRound, - PlayerIds, - SetupState.Value.ParticipantsMode, - SetupState.Value.Game.GetType().Name - ))); + var setupModel = Activator.CreateInstance(_selectedGameType.SetupModelType) as IGameSetupModel; + setupModel.ParticipantsMode = SetupState.Value.ParticipantsMode; + setupModel.ThrowMode = SetupState.Value.ThrowMode; + setupModel.ThrowsPerRound = SetupState.Value.ThrowsPerRound; + setupModel.Participants = PlayerIds; + setupModel.DayId = DayState.Value.Id; + setupModel.KnownGameType = SetupState.Value.Game.GetType().Name; + + // MudDialog.Close(DialogResult.Ok(new StartParams( + // DayState.Value.Id, + // SetupState.Value.ThrowMode, + // SetupState.Value.ThrowsPerRound, + // PlayerIds, + // SetupState.Value.ParticipantsMode, + // SetupState.Value.Game.GetType().Name + // ))); + + MudDialog.Close(DialogResult.Ok(setupModel)); } } diff --git a/KoogleApp/Components/Pages/Game.razor b/KoogleApp/Components/Pages/Game.razor index bd9167e..6c0a88c 100644 --- a/KoogleApp/Components/Pages/Game.razor +++ b/KoogleApp/Components/Pages/Game.razor @@ -47,7 +47,7 @@ @* @DayState.Value *@ @GetParticipantsState() - @* @StartParams(); *@ + @* @SetupModel(); *@ @if (DayState.Value.Status != DayStatus.Started) { diff --git a/KoogleApp/Games/IGameService.cs b/KoogleApp/Games/IGameService.cs index 8d83ef0..a0d5a1c 100644 --- a/KoogleApp/Games/IGameService.cs +++ b/KoogleApp/Games/IGameService.cs @@ -1,5 +1,6 @@ using System.Text.Json.Serialization; using Fluxor; +using KoogleApp.Games.Shit; using KoogleApp.Games.Training; using KoogleApp.Model; using KoogleApp.Store.Game.ThrowPanel; @@ -7,22 +8,42 @@ using KoogleApp.Store.Game.ThrowPanel; namespace KoogleApp.Games { [JsonDerivedType(typeof(TrainingState), typeDiscriminator: "TrainingState")] - //[JsonDerivedType(typeof(v2), typeDiscriminator: "v2")] + [JsonDerivedType(typeof(ShitState), typeDiscriminator: "ShitState")] public interface IGameModel { } + [JsonDerivedType(typeof(TrainingSetupState), typeDiscriminator: "TrainingSetupState")] + [JsonDerivedType(typeof(ShitSetupState), typeDiscriminator: "ShitSetupState")] + public interface IGameSetupModel + { + int DayId { get; set; } + ThrowMode ThrowMode { get; set; } + int ThrowsPerRound { get; set; } + int[] Participants { get; set; } + ParticipantsMode ParticipantsMode { get; set; } + string KnownGameType { get; set; } + } + + public abstract record GameSetupModelBase : IGameSetupModel + { + public int DayId { get; set; } + public ThrowMode ThrowMode { get; set; } + public int ThrowsPerRound { get; set; } + public int[] Participants { get; set; } + public ParticipantsMode ParticipantsMode { get; set; } + public string KnownGameType { get; set; } + } + public interface IGameService { public IKnownGame Game { get; } public GameProgress HandleThrow(GameProgress progress, IDispatcher dispatcher); - public IGameModel InitGameModel(StartParams startParams); + public IGameModel InitGameModel(IGameSetupModel startParams); IGameModel FinalizeGameModel(); - - public IGameModel GameModel { get; } } } diff --git a/KoogleApp/Games/IKnownGame.cs b/KoogleApp/Games/IKnownGame.cs index 77f6f8a..8c12106 100644 --- a/KoogleApp/Games/IKnownGame.cs +++ b/KoogleApp/Games/IKnownGame.cs @@ -9,5 +9,7 @@ public Type GameServiceType { get; } public Type BoardComponentType { get; } + + public Type SetupModelType { get; } } } diff --git a/KoogleApp/Games/Shit/Setup.razor b/KoogleApp/Games/Shit/Setup.razor new file mode 100644 index 0000000..8cb86cd --- /dev/null +++ b/KoogleApp/Games/Shit/Setup.razor @@ -0,0 +1,5 @@ +

Setup

+ +@code { + +} diff --git a/KoogleApp/Games/Shit/ShitBoard.razor b/KoogleApp/Games/Shit/ShitBoard.razor new file mode 100644 index 0000000..341daae --- /dev/null +++ b/KoogleApp/Games/Shit/ShitBoard.razor @@ -0,0 +1,4 @@ + +@code { + +} diff --git a/KoogleApp/Games/Shit/ShitGame.cs b/KoogleApp/Games/Shit/ShitGame.cs new file mode 100644 index 0000000..93dd6b9 --- /dev/null +++ b/KoogleApp/Games/Shit/ShitGame.cs @@ -0,0 +1,14 @@ +using KoogleApp.Games.Training; + +namespace KoogleApp.Games.Shit +{ + public class ShitGame: IKnownGame + { + public string Name => "Scheiss-Spiel"; + + public Type SetupComponentType => typeof(Setup); + public Type SetupModelType => typeof(ShitSetupState); + public Type GameServiceType => typeof(ShitGameService); + public Type BoardComponentType => typeof(ShitBoard); + } +} diff --git a/KoogleApp/Games/Shit/ShitGameService.cs b/KoogleApp/Games/Shit/ShitGameService.cs new file mode 100644 index 0000000..fb648e1 --- /dev/null +++ b/KoogleApp/Games/Shit/ShitGameService.cs @@ -0,0 +1,26 @@ +using Fluxor; +using KoogleApp.Model; +using KoogleApp.Store.Game.ThrowPanel; + +namespace KoogleApp.Games.Shit +{ + public class ShitGameService : IGameService + { + public IKnownGame Game => new ShitGame(); + + public GameProgress HandleThrow(GameProgress progress, IDispatcher dispatcher) + { + return progress; + } + + public IGameModel InitGameModel(IGameSetupModel startParams) + { + return null; + } + + public IGameModel FinalizeGameModel() + { + return null; + } + } +} diff --git a/KoogleApp/Games/Shit/ShitState.cs b/KoogleApp/Games/Shit/ShitState.cs new file mode 100644 index 0000000..fa81c0a --- /dev/null +++ b/KoogleApp/Games/Shit/ShitState.cs @@ -0,0 +1,15 @@ +using Fluxor; +using KoogleApp.Store.Game.ThrowPanel; + +namespace KoogleApp.Games.Shit +{ + [FeatureState] + public record ShitState : IGameModel + {} + + [FeatureState] + public record ShitSetupState: GameSetupModelBase + { + public int ShitNumber { get; set; } = 5; + } +} diff --git a/KoogleApp/Games/Training/Actions.cs b/KoogleApp/Games/Training/Actions.cs deleted file mode 100644 index 6c105e5..0000000 --- a/KoogleApp/Games/Training/Actions.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace KoogleApp.Games.Training -{ - //public record UpdateTrainingStateAction(TrainingState TrainingState); -} diff --git a/KoogleApp/Games/Training/GameTraining.cs b/KoogleApp/Games/Training/GameTraining.cs index 0c04227..97d12f2 100644 --- a/KoogleApp/Games/Training/GameTraining.cs +++ b/KoogleApp/Games/Training/GameTraining.cs @@ -9,5 +9,7 @@ public Type GameServiceType => typeof(GameTrainingService); public Type BoardComponentType => typeof(BoardTraining); + + public Type SetupModelType => typeof(TrainingSetupState); } } diff --git a/KoogleApp/Games/Training/GameTrainingService.cs b/KoogleApp/Games/Training/GameTrainingService.cs index bf5baf7..4a921bb 100644 --- a/KoogleApp/Games/Training/GameTrainingService.cs +++ b/KoogleApp/Games/Training/GameTrainingService.cs @@ -12,11 +12,9 @@ namespace KoogleApp.Games.Training { public IKnownGame Game => new GameTraining(); - private TrainingState _gameModel; - - public IGameModel InitGameModel(StartParams startParams) + public IGameModel InitGameModel(IGameSetupModel startParams) { - _gameModel = new TrainingState(); + var _gameModel = new TrainingState(); var dict = new Dictionary(); @@ -32,11 +30,9 @@ namespace KoogleApp.Games.Training public IGameModel FinalizeGameModel() { - return _gameModel; + return null; } - public IGameModel GameModel => _gameModel; - public GameProgress HandleThrow(GameProgress progress, IDispatcher dispatcher) { var res = new List(); diff --git a/KoogleApp/Games/Training/TrainingState.cs b/KoogleApp/Games/Training/TrainingState.cs index bf4d573..8296e80 100644 --- a/KoogleApp/Games/Training/TrainingState.cs +++ b/KoogleApp/Games/Training/TrainingState.cs @@ -35,6 +35,10 @@ namespace KoogleApp.Games.Training } } + [FeatureState] + public record TrainingSetupState : GameSetupModelBase + {} + public static class TrainingStateExtension { public static TrainingState DeepCopy(this TrainingState State) diff --git a/KoogleApp/Model/GameStatus.cs b/KoogleApp/Model/GameStatus.cs index 68c7ba8..482176c 100644 --- a/KoogleApp/Model/GameStatus.cs +++ b/KoogleApp/Model/GameStatus.cs @@ -16,7 +16,7 @@ namespace KoogleApp.Model public class GameStatus { - public StartParams StartParams { get; set; } + public IGameSetupModel SetupModel { get; set; } public ThrowPanelState? ThrowPanelState { get; set; } diff --git a/KoogleApp/Model/StartParams.cs b/KoogleApp/Model/StartParams.cs index 4c68588..96cbaf6 100644 --- a/KoogleApp/Model/StartParams.cs +++ b/KoogleApp/Model/StartParams.cs @@ -4,14 +4,14 @@ using KoogleApp.Store.Game.ThrowPanel; namespace KoogleApp.Model { - public record StartParams(int DayId, ThrowMode ThrowMode, int ThrowsPerRound, int[] Participants, - ParticipantsMode ParticipantsMode, string KnownGameType) + //public record StartParams(int DayId, ThrowMode ThrowMode, int ThrowsPerRound, int[] Participants, + // ParticipantsMode ParticipantsMode, string KnownGameType) - { - public StartParams() : this(DayId: 0, ThrowMode: ThrowMode.Reposition, - ThrowsPerRound: 3, [], - ParticipantsMode: ParticipantsMode.FreeToChoose, KnownGameType: nameof(GameTraining)) - { - } - } + //{ + // public StartParams() : this(DayId: 0, ThrowMode: ThrowMode.Reposition, + // ThrowsPerRound: 3, [], + // ParticipantsMode: ParticipantsMode.FreeToChoose, KnownGameType: nameof(GameTraining)) + // { + // } + //} } diff --git a/KoogleApp/Services/GameStatusDataService.cs b/KoogleApp/Services/GameStatusDataService.cs index c355a8f..77e2131 100644 --- a/KoogleApp/Services/GameStatusDataService.cs +++ b/KoogleApp/Services/GameStatusDataService.cs @@ -1,5 +1,6 @@ using KoogleApp.Model; using System.Text.Json; +using KoogleApp.Games; namespace KoogleApp.Services { @@ -21,7 +22,7 @@ namespace KoogleApp.Services //void Initialize(GameStatus content, string username); GameStatusSnapshot GetInitialData(); - StartParams? StartParams { get; } + IGameSetupModel? StartParams { get; } } public class GameStatusDataService : IGameStatusDataService @@ -84,7 +85,7 @@ namespace KoogleApp.Services return GetCurrentData(); } } - public StartParams? StartParams => GetInitialData()?.Status?.StartParams; + public IGameSetupModel? StartParams => GetInitialData()?.Status?.SetupModel; public Task SaveToDatabaseAndReset(GameStatus lastContent, string username) @@ -123,10 +124,10 @@ namespace KoogleApp.Services var isInitialSnapshot = _currentData == null; if (isInitialSnapshot) { - if (content.StartParams == null) + if (content.SetupModel == null) { return; - //throw new InvalidOperationException("Service not initialized. StartParams required"); + //throw new InvalidOperationException("Service not initialized. SetupModel required"); } _currentData = new GameStatusSnapshot diff --git a/KoogleApp/Store/Game/Setup/Effects.cs b/KoogleApp/Store/Game/Setup/Effects.cs index c6b9181..b114081 100644 --- a/KoogleApp/Store/Game/Setup/Effects.cs +++ b/KoogleApp/Store/Game/Setup/Effects.cs @@ -27,7 +27,7 @@ namespace KoogleApp.Store.Game.Setup var data = _dataService.GetInitialData(); if (data.Status != null) { - var startParams = data.Status.StartParams; + var startParams = data.Status.SetupModel; if (startParams != null) { var setupState = new SetupState(startParams.ThrowMode, startParams.ThrowsPerRound, startParams.Participants, diff --git a/KoogleApp/Store/Game/ThrowPanel/Actions.cs b/KoogleApp/Store/Game/ThrowPanel/Actions.cs index 84747a2..d233cf3 100644 --- a/KoogleApp/Store/Game/ThrowPanel/Actions.cs +++ b/KoogleApp/Store/Game/ThrowPanel/Actions.cs @@ -7,7 +7,7 @@ namespace KoogleApp.Store.Game.ThrowPanel { public record TogglePinValueAction(bool IsHit, int PinNumber); - public record StartStopAction(ThrowPanelState State, StartParams? StartParams); + public record StartStopAction(ThrowPanelState State, IGameSetupModel? StartParams); public record ConnectToHubAction(); @@ -46,7 +46,7 @@ namespace KoogleApp.Store.Game.ThrowPanel public record GameProgress(ThrowPanelState? BeforeThrowState, ParticipantsState? BeforeParticipantsState, ThrowPanelState AfterThrowState, ParticipantsState AfterParticipantsState, - StartParams StartParams, IGameModel GameModel, + IGameSetupModel StartParams, IGameModel GameModel, ThrowPanelState? NextThrowState); public record DeleteThrowPanelSessionAction(); diff --git a/KoogleApp/Store/Game/ThrowPanel/Effects.cs b/KoogleApp/Store/Game/ThrowPanel/Effects.cs index ae12df7..1c1a903 100644 --- a/KoogleApp/Store/Game/ThrowPanel/Effects.cs +++ b/KoogleApp/Store/Game/ThrowPanel/Effects.cs @@ -61,7 +61,7 @@ namespace KoogleApp.Store.Game.ThrowPanel { ThrowPanelState = throwPanelState.Value, ParticipantsState = participantsState, - StartParams = startStopAction.StartParams, + SetupModel = startStopAction.StartParams, GameModel = gameModel }, username); } diff --git a/KoogleApp/appdata.json b/KoogleApp/appdata.json index 69cd8a4..b156e5c 100644 --- a/KoogleApp/appdata.json +++ b/KoogleApp/appdata.json @@ -1,7 +1,7 @@ { "CurrentData": { "Status": { - "StartParams": null, + "SetupModel": null, "ThrowPanelState": { "IsStated": true, "BellValue": false, @@ -14,8 +14,8 @@ "Pin7State": 0, "Pin8State": 0, "Pin9State": 0, - "ThrowsPerRound": 1, - "ThrowCounterPerRound": 1, + "ThrowsPerRound": 3, + "ThrowCounterPerRound": 2, "ThrowMode": 0, "ThrowPanelStateStatus": 3, "ThrowCounter": 1, @@ -23,11 +23,11 @@ }, "ParticipantsState": { "PlayerIds": [ + 12, + 5, 3, 10, - 12, - 9, - 5 + 9 ], "Eliminated": [] }, @@ -37,12 +37,12 @@ "5": { "PlayerId": 5, "TeamNr": 0, - "PinCount": 1, + "PinCount": 0, "CircleCount": 0, "SinkCount": 0, "StrikeCount": 0, "ClearedCount": 0, - "ThrowCount": 1, + "ThrowCount": 0, "BellCount": 0 }, "3": { @@ -70,12 +70,12 @@ "12": { "PlayerId": 12, "TeamNr": 0, - "PinCount": 0, + "PinCount": 1, "CircleCount": 0, "SinkCount": 0, "StrikeCount": 0, "ClearedCount": 0, - "ThrowCount": 0, + "ThrowCount": 1, "BellCount": 0 }, "9": { @@ -93,13 +93,13 @@ } }, "Version": 3, - "LastModified": "2025-11-27T08:57:54.4108241+01:00", + "LastModified": "2025-11-27T18:02:52.0439516+01:00", "LastModifiedBy": "test1@test.de" }, "UndoHistory": [ { "Status": { - "StartParams": null, + "SetupModel": null, "ThrowPanelState": { "IsStated": true, "BellValue": false, @@ -112,7 +112,7 @@ "Pin7State": 0, "Pin8State": 0, "Pin9State": 1, - "ThrowsPerRound": 1, + "ThrowsPerRound": 3, "ThrowCounterPerRound": 1, "ThrowMode": 0, "ThrowPanelStateStatus": 2, @@ -121,10 +121,10 @@ }, "ParticipantsState": { "PlayerIds": [ + 12, 5, 3, 10, - 12, 9 ], "Eliminated": [] @@ -191,15 +191,16 @@ } }, "Version": 2, - "LastModified": "2025-11-27T08:57:54.3513899+01:00", + "LastModified": "2025-11-27T18:02:52.0372178+01:00", "LastModifiedBy": "test1@test.de" }, { "Status": { - "StartParams": { + "SetupModel": { + "$type": "TrainingSetupState", "DayId": 35, "ThrowMode": 0, - "ThrowsPerRound": 1, + "ThrowsPerRound": 3, "Participants": [ 5, 3, @@ -207,7 +208,7 @@ 12, 9 ], - "ParticipantsMode": 0, + "ParticipantsMode": 1, "KnownGameType": "GameTraining" }, "ThrowPanelState": { @@ -222,7 +223,7 @@ "Pin7State": 0, "Pin8State": 0, "Pin9State": 0, - "ThrowsPerRound": 1, + "ThrowsPerRound": 3, "ThrowCounterPerRound": 1, "ThrowMode": 0, "ThrowPanelStateStatus": 1, @@ -301,7 +302,7 @@ } }, "Version": 1, - "LastModified": "2025-11-27T07:56:55.6527668Z", + "LastModified": "2025-11-27T17:02:45.406402Z", "LastModifiedBy": "test1@test.de" } ],