@using Fluxor @using Koogle.Application.DTOs @using Koogle.Application.Games @using Koogle.Application.Games.Shit @using Koogle.Web.Store.GameState @using Koogle.Web.Store.DayState @using MudBlazor @inherits Fluxor.Blazor.Web.Components.FluxorComponent @implements IDisposable @inject IState GameState @inject IState DayState @* Scheiss-Spiel - Tafel *@ @if (_model == null) { Spiel noch nicht gestartet. } else { @* Game info header *@ Scheiss-Zahl: @_model.ShitNumber Gesammelte Punkte: @if (_model.CollectedPoints > 0) { @_model.CollectedPoints } else { 0 } @* Last throw info *@ @if (_model.LastThrowPins.HasValue) { @if (_model.LastThrowWasShitNumber) { Scheiss-Zahl getroffen! Du bekommst alle gesammelten Punkte. } else if (_model.LastThrowWasGutter) { Rinne! Du bekommst alle gesammelten Punkte. } else { @_model.LastThrowPins Kegel - @_model.LastThrowPins Punkte abgezogen. } } @* Winner announcement *@ @if (_model.IsGameOver && _model.WinnerId.HasValue) { var winnerName = GetPlayerName(_model.WinnerId.Value); @winnerName hat gewonnen! } @* Players table *@ Spieler Punkte Status @if (context.IsCurrentPlayer && !_model.IsGameOver) { @context.PlayerName } else { @context.PlayerName } @context.Points @if (context.IsWinner) { GEWINNER } else if (_model.IsGameOver) { -@context.Points Strafe } else if (context.IsCurrentPlayer) { Am Zug } @* Progress indicator *@ @if (!_model.IsGameOver) { Wer zuerst 0 Punkte erreicht, gewinnt! } } @code { private ShitGameModel? _model; private List _playerStats = []; protected override void OnInitialized() { base.OnInitialized(); GameState.StateChanged += OnGameStateChanged; UpdateStats(); } private void OnGameStateChanged(object? sender, EventArgs e) { UpdateStats(); InvokeAsync(StateHasChanged); } private void UpdateStats() { _playerStats.Clear(); _model = null; var gameState = GameState.Value; if (gameState.GameModel is ShitGameModel model) { _model = model; } else if (gameState.GameModel is System.Text.Json.JsonElement jsonElement) { try { _model = System.Text.Json.JsonSerializer.Deserialize( jsonElement.GetRawText(), GameModelFactory.JsonSerializerOptions); } catch { return; } } if (_model?.PlayerPoints == null) { return; } var currentPlayerId = gameState.Participants.CurrentPlayerId; var persons = DayState.Value.AvailablePersons; foreach (var (playerId, points) in _model.PlayerPoints) { var person = persons.FirstOrDefault(p => p.Id == playerId); var playerName = person?.Name ?? "Unbekannt"; _playerStats.Add(new PlayerStatsRow { PlayerId = playerId, PlayerName = playerName, Points = points, IsWinner = _model.WinnerId == playerId, IsCurrentPlayer = playerId == currentPlayerId }); } // Sort: Winner first, then by points ascending (lowest is best) _playerStats = _playerStats .OrderByDescending(p => p.IsWinner) .ThenBy(p => p.Points) .ToList(); } private string GetPlayerName(Guid playerId) { var person = DayState.Value.AvailablePersons.FirstOrDefault(p => p.Id == playerId); return person?.Name ?? "Unbekannt"; } private Severity GetLastThrowSeverity() { if (_model?.LastThrowWasShitNumber == true || _model?.LastThrowWasGutter == true) { return Severity.Error; } return Severity.Info; } private string GetPointsStyle(PlayerStatsRow row) { if (row.IsWinner) { return "color: var(--mud-palette-success); font-weight: bold;"; } if (_model?.IsGameOver == true) { return "color: var(--mud-palette-error);"; } if (row.Points <= 10) { return "color: var(--mud-palette-warning);"; } return ""; } public void Dispose() { GameState.StateChanged -= OnGameStateChanged; } private record PlayerStatsRow { public Guid PlayerId { get; init; } public string PlayerName { get; init; } = ""; public int Points { get; init; } public bool IsWinner { get; init; } public bool IsCurrentPlayer { get; init; } } }