refactoring GameSetup

This commit is contained in:
beo3000 2025-12-27 13:15:18 +01:00
parent f1880f08a8
commit 92dfb47a08
5 changed files with 112 additions and 70 deletions

View File

@ -0,0 +1,14 @@
using Koogle.Application.Games;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Koogle.Application.Interfaces
{
public interface IGameSetupControl
{
IGameSetupModel GameSetupModel { get; }
}
}

View File

@ -3,6 +3,7 @@
@using Koogle.Application.Games @using Koogle.Application.Games
@using Koogle.Application.Games.Shit @using Koogle.Application.Games.Shit
@using Koogle.Application.Games.Training @using Koogle.Application.Games.Training
@using Koogle.Application.Interfaces
@using Koogle.Domain.Enums @using Koogle.Domain.Enums
@using Koogle.Domain.Interfaces @using Koogle.Domain.Interfaces
@using Koogle.Web.Store.DayState @using Koogle.Web.Store.DayState
@ -23,13 +24,23 @@
OnGameDefinitionChanged="OnGameDefinitionChanged" /> OnGameDefinitionChanged="OnGameDefinitionChanged" />
</MudExpansionPanel> </MudExpansionPanel>
@* Step 2: Game-specific Setup *@ @* Step 2: Participant Selection *@
<MudExpansionPanel Text="2. Spieleinstellungen" <MudExpansionPanel Text="2. Teilnehmer"
IsExpanded="@(_currentStep == 3)"
Disabled="@(_selectedDefinition == null)">
<ParticipantSelector AvailableParticipants="@_availableParticipants"
@bind-SelectedParticipantIds="_selectedParticipantIds"
MinimumParticipants="1" />
</MudExpansionPanel>
@* Step 3: Game-specific Setup *@
<MudExpansionPanel Text="3. Spieleinstellungen"
IsExpanded="@(_currentStep == 2)" IsExpanded="@(_currentStep == 2)"
Disabled="@(_selectedDefinition == null)"> Disabled="@(_selectedDefinition == null)">
@if (_selectedDefinition != null) @if (_selectedDefinition != null)
{ {
<DynamicComponent Type="@_selectedDefinition.SetupComponentType" <DynamicComponent Type="@_selectedDefinition.SetupComponentType"
@ref="dynamicComponentRef"
Parameters="@GetSetupParameters()" /> Parameters="@GetSetupParameters()" />
} }
else else
@ -40,23 +51,14 @@
} }
</MudExpansionPanel> </MudExpansionPanel>
@* Step 3: Participant Selection *@
<MudExpansionPanel Text="3. Teilnehmer"
IsExpanded="@(_currentStep == 3)"
Disabled="@(_selectedDefinition == null)">
<ParticipantSelector AvailableParticipants="@_availableParticipants"
@bind-SelectedParticipantIds="_selectedParticipantIds"
MinimumParticipants="1" />
</MudExpansionPanel>
@* Step 4: Common Options *@ @* Step 4: Common Options *@
<MudExpansionPanel Text="4. Grundeinstellungen" @* <MudExpansionPanel Text="4. Grundeinstellungen"
IsExpanded="@(_currentStep == 4)" IsExpanded="@(_currentStep == 4)"
Disabled="@(_selectedParticipantIds.Count == 0)"> Disabled="@(_selectedParticipantIds.Count == 0)">
<CommonSetupOptions @bind-ThrowMode="_throwMode" <CommonSetupOptions @bind-ThrowMode="_throwMode"
@bind-ThrowsPerRound="_throwsPerRound" @bind-ThrowsPerRound="_throwsPerRound"
@bind-ParticipantsMode="_participantsMode" /> @bind-ParticipantsMode="_participantsMode" />
</MudExpansionPanel> </MudExpansionPanel> *@
</MudExpansionPanels> </MudExpansionPanels>
@* Validation errors *@ @* Validation errors *@
@ -79,7 +81,7 @@
<strong>Teilnehmer:</strong> @_selectedParticipantIds.Count Spieler <strong>Teilnehmer:</strong> @_selectedParticipantIds.Count Spieler
</MudText> </MudText>
<MudText Typo="Typo.body2"> <MudText Typo="Typo.body2">
<strong>Modus:</strong> @GetThrowModeLabel(_throwMode) <strong>Modus:</strong> @GetThrowModeLabel()
</MudText> </MudText>
</MudStack> </MudStack>
</MudPaper> </MudPaper>
@ -107,6 +109,8 @@
</MudDialog> </MudDialog>
@code { @code {
private DynamicComponent? dynamicComponentRef;
/// <summary> /// <summary>
/// ID of the day to start the game for. /// ID of the day to start the game for.
/// </summary> /// </summary>
@ -125,10 +129,10 @@
private IGameDefinition? _selectedDefinition; private IGameDefinition? _selectedDefinition;
private IReadOnlyList<DayParticipantDto> _availableParticipants = []; private IReadOnlyList<DayParticipantDto> _availableParticipants = [];
private IReadOnlyList<Guid> _selectedParticipantIds = []; private IReadOnlyList<Guid> _selectedParticipantIds = [];
private object? _gameSpecificSetupOptions; // private object? _gameSpecificSetupOptions;
private ThrowMode _throwMode = ThrowMode.Reposition; // private ThrowMode _throwMode = ThrowMode.Reposition;
private int _throwsPerRound = 3; // private int _throwsPerRound = 3;
private ParticipantsMode _participantsMode = ParticipantsMode.GameLogic; // private ParticipantsMode _participantsMode = ParticipantsMode.GameLogic;
private string? _validationError; private string? _validationError;
private bool _isStarting; private bool _isStarting;
@ -147,7 +151,7 @@
private void OnGameDefinitionChanged(IGameDefinition? definition) private void OnGameDefinitionChanged(IGameDefinition? definition)
{ {
_selectedDefinition = definition; _selectedDefinition = definition;
_gameSpecificSetupOptions = null; // _gameSpecificSetupOptions = null;
_validationError = null; _validationError = null;
if (definition != null) if (definition != null)
@ -161,13 +165,13 @@
return new Dictionary<string, object> return new Dictionary<string, object>
{ {
["OnOptionsChanged"] = EventCallback.Factory.Create<object>(this, OnSetupOptionsChanged), ["OnOptionsChanged"] = EventCallback.Factory.Create<object>(this, OnSetupOptionsChanged),
["InitialOptions"] = _gameSpecificSetupOptions! // ["InitialOptions"] = _gameSpecificSetupOptions!
}; };
} }
private void OnSetupOptionsChanged(object options) private void OnSetupOptionsChanged(object options)
{ {
_gameSpecificSetupOptions = options; // _gameSpecificSetupOptions = options;
_validationError = null; _validationError = null;
} }
@ -192,9 +196,12 @@
try try
{ {
// Create typed setup model based on game type
IGameSetupModel? setup = CreateSetupModel(_selectedDefinition.Name);
// Validate setup options // Validate setup options
var logicService = GameRegistry.GetLogicService(_selectedDefinition.Name); var logicService = GameRegistry.GetLogicService(_selectedDefinition.Name);
var validationResult = logicService.ValidateSetup(_gameSpecificSetupOptions); var validationResult = logicService.ValidateSetup(setup);
if (!validationResult.IsValid) if (!validationResult.IsValid)
{ {
@ -206,19 +213,17 @@
// Create initial game model and setup // Create initial game model and setup
var playerIds = _selectedParticipantIds.ToArray(); var playerIds = _selectedParticipantIds.ToArray();
// Create typed setup model based on game type
IGameSetupModel? setup = CreateSetupModel(_selectedDefinition.Name);
var initialModel = logicService.CreateInitialModel(playerIds, setup ?? _gameSpecificSetupOptions); var initialModel = logicService.CreateInitialModel(playerIds, setup);
// Dispatch start game action // Dispatch start game action
var action = new StartGameAction( var action = new StartGameAction(
DayId: DayId, DayId: DayId,
GameTypeName: _selectedDefinition.Name, GameTypeName: _selectedDefinition.Name,
PlayerIds: playerIds, PlayerIds: playerIds,
ThrowMode: _throwMode, ThrowMode: setup.ThrowMode,
ThrowsPerRound: _throwsPerRound, ThrowsPerRound: setup.ThrowsPerRound,
ParticipantsMode: _participantsMode, ParticipantsMode: setup.ParticipantsMode,
InitialGameModel: initialModel, InitialGameModel: initialModel,
Setup: setup); Setup: setup);
@ -244,48 +249,29 @@
MudDialog?.Cancel(); MudDialog?.Cancel();
} }
private string GetThrowModeLabel(ThrowMode mode) => mode switch private string GetThrowModeLabel()
{ {
ThrowMode.Reposition => "In die Vollen", IGameSetupModel? setup = CreateSetupModel(_selectedDefinition.Name);
ThrowMode.Decrease => "Abräumen", switch (setup.ThrowMode)
_ => mode.ToString() {
}; case ThrowMode.Reposition:
return "In die Vollen";
case ThrowMode.Decrease:
return "Abräumen";
}
return "";
}
private IGameSetupModel? CreateSetupModel(string gameTypeName) private IGameSetupModel? CreateSetupModel(string gameTypeName)
{ {
return gameTypeName switch var setupModel = (dynamicComponentRef.Instance as IGameSetupControl).GameSetupModel;
{ // setupModel.DayId = DayState.Value.Id;
"Shit" => CreateShitSetup(), // setupModel.KnownGameType = SetupState.Value.Game.GetType().Name;
"Training" => CreateTrainingSetup(), // setupModel.Participants = PlayerIds;
_ => null return setupModel;
};
} }
private ShitGameSetup CreateShitSetup()
{
// Extract game-specific options if available
var shitNumber = 5;
var startNumber = 50;
if (_gameSpecificSetupOptions is ShitGameSetup existingSetup)
{
shitNumber = existingSetup.ShitNumber;
startNumber = existingSetup.StartNumber;
}
return ShitGameSetup.Create(
throwMode: _throwMode,
throwsPerRound: _throwsPerRound,
participantsMode: _participantsMode,
shitNumber: shitNumber,
startNumber: startNumber);
}
private TrainingGameSetup CreateTrainingSetup()
{
return TrainingGameSetup.Create(
throwMode: _throwMode,
throwsPerRound: _throwsPerRound,
participantsMode: _participantsMode);
}
} }

View File

@ -7,7 +7,18 @@
<MudPaper Class="pa-4" Elevation="0"> <MudPaper Class="pa-4" Elevation="0">
<MudText Typo="Typo.subtitle1" Class="mb-3">Spieltyp auswählen</MudText> <MudText Typo="Typo.subtitle1" Class="mb-3">Spieltyp auswählen</MudText>
<MudRadioGroup T="string" @bind-Value="_selectedGameType" Class="d-flex flex-column gap-2"> <MudSelect T="string" @bind-Value="_selectedGameType" Class="d-flex flex-column gap-2">
@foreach (var definition in _gameDefinitions)
{
<MudSelectItem Value="@definition.Name">
<MudStack Row="true" AlignItems="AlignItems.Center" Spacing="2">
<MudIcon Icon="@GetGameIcon(definition.Name)" Size="Size.Small" />
<MudText Typo="Typo.body1">@definition.DisplayName</MudText>
</MudStack>
</MudSelectItem>
}
</MudSelect>
@* <MudRadioGroup T="string" @bind-Value="_selectedGameType" Class="d-flex flex-column gap-2">
@foreach (var definition in _gameDefinitions) @foreach (var definition in _gameDefinitions)
{ {
<MudRadio Value="@definition.Name" <MudRadio Value="@definition.Name"
@ -19,7 +30,7 @@
</MudStack> </MudStack>
</MudRadio> </MudRadio>
} }
</MudRadioGroup> </MudRadioGroup> *@
@if (_gameDefinitions.Count == 0) @if (_gameDefinitions.Count == 0)
{ {

View File

@ -1,10 +1,11 @@
@using Koogle.Application.Games
@using Koogle.Application.Games.Shit @using Koogle.Application.Games.Shit
@using Koogle.Application.Interfaces @using Koogle.Application.Interfaces
@using Koogle.Domain.Enums @using Koogle.Domain.Enums
@using MudBlazor @using MudBlazor
@inject ITriggerService TriggerService @inject ITriggerService TriggerService
@implements IGameSetupControl
<MudPaper Class="pa-4"> <MudPaper Class="pa-4">
<MudText Typo="Typo.h6" Class="mb-4">Scheiss-Spiel Einstellungen</MudText> <MudText Typo="Typo.h6" Class="mb-4">Scheiss-Spiel Einstellungen</MudText>
@ -130,4 +131,21 @@
public int StartNumber { get; set; } = 50; public int StartNumber { get; set; } = 50;
public ParticipantsMode ParticipantsMode { get; set; } = ParticipantsMode.GameLogic; public ParticipantsMode ParticipantsMode { get; set; } = ParticipantsMode.GameLogic;
} }
public IGameSetupModel GameSetupModel => CreateShitSetup();
private ShitGameSetup CreateShitSetup()
{
// Extract game-specific options if available
var shitNumber = 5;
var startNumber = 50;
return ShitGameSetup.Create(
throwMode: ThrowMode.Reposition,
throwsPerRound: int.MaxValue,
participantsMode: ParticipantsMode.GameLogic,
shitNumber: _options.ShitNumber,
startNumber: _options.StartNumber);
}
} }

View File

@ -1,7 +1,10 @@
@using Koogle.Application.Games
@using Koogle.Application.Games.Training @using Koogle.Application.Games.Training
@using Koogle.Domain.Enums @using Koogle.Domain.Enums
@using MudBlazor @using MudBlazor
@using Koogle.Application.Interfaces;
@implements IGameSetupControl
<MudPaper Class="pa-4"> <MudPaper Class="pa-4">
<MudText Typo="Typo.h6" Class="mb-4">Training-Einstellungen</MudText> <MudText Typo="Typo.h6" Class="mb-4">Training-Einstellungen</MudText>
@ -123,4 +126,14 @@
set => _participantsMode = value; set => _participantsMode = value;
} }
} }
public IGameSetupModel GameSetupModel => CreateTrainingSetup();
private TrainingGameSetup CreateTrainingSetup()
{
return TrainingGameSetup.Create(
throwMode: _options.ThrowMode,
throwsPerRound: _options.ThrowsPerRound,
participantsMode: _options.ParticipantsMode);
}
} }