diff --git a/src/Koogle.Application/Games/FoxHunt/FoxHuntGameLogicService.cs b/src/Koogle.Application/Games/FoxHunt/FoxHuntGameLogicService.cs index f5569b7..da10773 100644 --- a/src/Koogle.Application/Games/FoxHunt/FoxHuntGameLogicService.cs +++ b/src/Koogle.Application/Games/FoxHunt/FoxHuntGameLogicService.cs @@ -73,6 +73,8 @@ namespace Koogle.Application.Games.FoxHunt var triggers = new List(); var foxId = model.PlayerOrder[model.FoxIndex]; + var lastHunterId = GetPrev(model, model.FoxIndex); + var isLastHunter = lastHunterId == playerId; if (model.FoxTurn) { @@ -81,15 +83,41 @@ namespace Koogle.Application.Games.FoxHunt else { playerStates[foxId].PinCountHunters+= afterThrow.PinsKnocked; + if (playerStates[foxId].PinCountHunters >= playerStates[foxId].PinCountFox ) + { + // fox has been caught + isLastHunter = true; + playerStates[foxId].FoxCaught = true; + } + else + { + if (isLastHunter) + { + playerStates[foxId].FoxEscaped = true; + } + } } - // 5. Check GAME END - bool isGameOver = false; - Guid? winnerId = null; + + var nextPlayerId = GetNextId(model, isLastHunter); + + // Check GAME END + bool isGameOver = isLastHunter && model.FoxIndex == 0; + + if (isGameOver) + { + // looking for winner(s) + var maxLeading = playerStates.Values.Where(s => !s.FoxCaught) + .Select(s => s.PinCountFox - s.PinCountHunters).Max(); + foreach (var key in playerStates.Keys) + { + if (playerStates[key].PinCountFox - playerStates[key].PinCountHunters == maxLeading) + { + playerStates[key].IsWinner = true; + } + } + } - - var nextPlayerId = GetNextId(model); - //var nextName = GetPlayerName(nextPlayerId).Result; // Update model model = model with @@ -105,7 +133,7 @@ namespace Koogle.Application.Games.FoxHunt PointsScored = pinsKnocked, ShouldRotatePlayer = true, IsGameOver = isGameOver, - WinnerId = winnerId, + WinnerId = null, Triggers = triggers, Overrides = isGameOver ? null : new GameLogicOverrides { @@ -125,13 +153,22 @@ namespace Koogle.Application.Games.FoxHunt /// /// /// - private Guid GetNextId(FoxHuntGameModel model) + private Guid GetNextId(FoxHuntGameModel model, bool chooseNextFox) { // Abbruch: alle waren einmal Fuchs if (model.FoxIndex >= model.PlayerOrder.Length) throw new InvalidOperationException("Alle Spieler waren bereits Fuchs."); - Guid foxId = model.PlayerOrder[model.FoxIndex]; + var foxId = model.PlayerOrder[model.FoxIndex]; + + if (chooseNextFox) + { + model.FoxIndex = GetNextIndex(model, model.FoxIndex); + model.FoxTurnsRemaining = model.LeadingThrows - 1; // nächster Wurf zählt schon + model.FoxTurn = true; + model.NonFoxIndex = model.FoxIndex; // NonFoxIndex = FoxIndex -> Increment will choose next person after fox + return model.PlayerOrder[model.FoxIndex]; + } // 1️⃣ Fuchs ist 2x hintereinander dran if (model.FoxTurnsRemaining > 0) @@ -146,33 +183,72 @@ namespace Koogle.Application.Games.FoxHunt // 2️⃣ Abwechselnd Nicht-Fuchs → Fuchs if (!model.FoxTurn) { - // nächsten Nicht-Fuchs suchen - while (model.NonFoxIndex == model.FoxIndex) - model.NonFoxIndex++; + var nextNonFoxIndex = GetNextIndex(model, model.NonFoxIndex); + if (nextNonFoxIndex == model.FoxIndex) + { + throw new InvalidOperationException("this should never happen"); + //nextNoneFoxIndex = GetNextIndex(model, model.NonFoxIndex); + } + model.NonFoxIndex = nextNonFoxIndex; + return model.PlayerOrder[nextNonFoxIndex]; - if (model.NonFoxIndex < model.PlayerOrder.Length) - { - Guid next = model.PlayerOrder[model.NonFoxIndex]; - model.NonFoxIndex++; - //model.FoxTurn = true; - return next; - } - else - { - // Alle Nicht-Füchse durch → neuer Fuchs - model.FoxIndex++; - model.NonFoxIndex = 0; - model.FoxTurnsRemaining = model.LeadingThrows - 1; - model.FoxTurn = true; - return GetNextId(model); - } + // nächsten Nicht-Fuchs suchen + //while (model.NonFoxIndex == model.FoxIndex) + // model.NonFoxIndex++; + + //if (model.NonFoxIndex < model.PlayerOrder.Length) + //{ + // Guid next = model.PlayerOrder[model.NonFoxIndex]; + // model.NonFoxIndex++; + // //model.FoxTurn = true; + // return next; + //} + //else + //{ + // // Alle Nicht-Füchse durch → neuer Fuchs + // model.FoxIndex++; + // model.NonFoxIndex = 0; + // model.FoxTurnsRemaining = model.LeadingThrows - 1; + // model.FoxTurn = true; + // return GetNextId(model); + //} } + + + // 3️⃣ Fuchs-Zug im Wechsel //model.FoxTurn = false; return foxId; } + private Guid GetPrev(FoxHuntGameModel model, int index) + { + if (index == 0) + { + return model.PlayerOrder[^1]; + } + return model.PlayerOrder[index - 1]; + } + + private Guid GetNext(FoxHuntGameModel model, int index) + { + if (index == model.PlayerOrder.Length -1) + { + return model.PlayerOrder[0]; + } + return model.PlayerOrder[index + 1]; + } + + private int GetNextIndex(FoxHuntGameModel model, int index) + { + if (index == model.PlayerOrder.Length - 1) + { + return 0; + } + return index + 1; + } + private static int GetNextActivePlayerIndex( Guid[] playerOrder, int currentIndex, diff --git a/src/Koogle.Application/Games/FoxHunt/FoxHuntGameModel.cs b/src/Koogle.Application/Games/FoxHunt/FoxHuntGameModel.cs index 378993d..151a6fa 100644 --- a/src/Koogle.Application/Games/FoxHunt/FoxHuntGameModel.cs +++ b/src/Koogle.Application/Games/FoxHunt/FoxHuntGameModel.cs @@ -35,5 +35,9 @@ public int PinCountFox { get; set; } public int PinCountHunters { get; set; } + + public bool FoxCaught { get; set; } + public bool IsWinner { get; set; } + public bool FoxEscaped { get; set; } } } diff --git a/src/Koogle.Web/Components/Game/FoxHunt/FoxBoard.razor b/src/Koogle.Web/Components/Game/FoxHunt/FoxBoard.razor index eb18945..735d258 100644 --- a/src/Koogle.Web/Components/Game/FoxHunt/FoxBoard.razor +++ b/src/Koogle.Web/Components/Game/FoxHunt/FoxBoard.razor @@ -1,18 +1,18 @@ -@inherits Fluxor.Blazor.Web.Components.FluxorComponent - -@using System.Text.Json +@using System.Text.Json @using Koogle.Application.Games.FoxHunt @using Koogle.Web.Store.DayState @using Koogle.Web.Store.GameState @using Koogle.Application.Games; +@inherits Fluxor.Blazor.Web.Components.FluxorComponent + @implements IDisposable @inject IState GameState @inject IState DayState -
+@* 
     @_debug
-
+
*@ @if (_model == null) @@ -29,16 +29,16 @@ Vorsprung für den Fuchs: - @_model.LeadingThrows Vorsprung + @_model.LeadingThrows Wurf - +@* Füchse übrig: 0 - + *@ @* Last throw info *@ @@ -70,12 +70,12 @@ Class="mb-4"> Spieler - Status - Xs - Eier Status + Punkte + Ergebnis + @if (context.IsCurrentPlayer && !_model.IsGameOver) { @@ -89,14 +89,14 @@ } else { - + @context.PlayerName } - - + + @if (context.IsWinner) { @@ -105,18 +105,56 @@ SIEGER } - else if (context.IsEliminated) - { - - ☠️ Platz @context.FoxSurvivalOrder - - } else if (context.IsCurrentPlayer) { - + Am Zug } + + @if (context.IsFox) + { + + Fuchs + + } + else + { + + Jäger + + } + + + + + + + @if (context.LeadingCount > 0) + { + @($"Fuchs: {context.PinCountFox} Jäger: {@context.PinCountHunters} Vorsprung: {@context.LeadingCount}"); + } + else + { + @($"Fuchs: {context.PinCountFox} Jäger: {@context.PinCountHunters}") + } + + + + + + @if (context.FoxCaught) + { + + ☠️ @context.PlayerName ist ein toter Fuchs + + } + @if (context.FoxEscaped) + { + + 🗸 Fuchs @context.PlayerName ist entkommen + + } @@ -186,6 +224,35 @@ return; } + var currentPlayerId = gameState.Participants.CurrentPlayerId; + var persons = DayState.Value.AvailablePersons; + var foxId = _model.PlayerOrder[_model.FoxIndex]; + + foreach (var playerId in _model.PlayerOrder) + { + if (!_model.PlayerStates.TryGetValue(playerId, out var state)) + continue; + + var person = persons.FirstOrDefault(p => p.Id == playerId); + var playerName = person?.Name ?? "Unbekannt"; + var foxModel = _model.PlayerStates[playerId]; + + // var eliminationOrder = _model.EliminatedPlayers.IndexOf(playerId); + + _playerStats.Add(new PlayerStatsRow + { + PlayerId = playerId, + PlayerName = playerName, + IsCurrentPlayer = playerId == currentPlayerId, + IsFox = playerId == foxId, + FoxCaught = foxModel.FoxCaught, + IsWinner = foxModel.IsWinner, + PinCountFox = foxModel.PinCountFox, + PinCountHunters = foxModel.PinCountHunters, + LeadingCount = foxModel.PinCountFox - foxModel.PinCountHunters, + FoxEscaped = foxModel.FoxEscaped + }); + } } public void Dispose() @@ -206,8 +273,13 @@ public string Status { get; init; } = ""; public bool IsWinner { get; init; } public bool IsCurrentPlayer { get; init; } - public bool IsEliminated { get; init; } + public bool IsFox { get; init; } public int FoxSurvivalOrder { get; init; } + public bool FoxCaught { get; init; } + public int PinCountFox { get; set; } + public int PinCountHunters { get; set; } + public int LeadingCount { get; set; } + public bool FoxEscaped { get; set; } } }