diff --git a/src/Koogle.Application/Games/ChristmasTree/ChristmasTreeGameLogicService.cs b/src/Koogle.Application/Games/ChristmasTree/ChristmasTreeGameLogicService.cs index 50dd8d5..23a3de4 100644 --- a/src/Koogle.Application/Games/ChristmasTree/ChristmasTreeGameLogicService.cs +++ b/src/Koogle.Application/Games/ChristmasTree/ChristmasTreeGameLogicService.cs @@ -38,6 +38,7 @@ public class ChristmasTreeGameLogicService : IGameLogicService return new ChristmasTreeGameModel { Variant = options.Variant, + EndCondition = options.EndCondition, TeamTrees = teamTrees, Teams = options.Teams.ToList(), CurrentTeamIndex = 0, @@ -123,8 +124,8 @@ public class ChristmasTreeGameLogicService : IGameLogicService CrossedOutCount = teamTrees[playerTeamIndex].CrossedOutCount + 1 }; - // Check if game ended (last 5 crossed) - bool gameEnded = CheckAllFivesGone(teamTrees); + // Check if game ended + bool gameEnded = CheckGameEndCondition(teamTrees, model.EndCondition); if (gameEnded) { lastThrow = lastThrow with { TriggeredGameEnd = true }; @@ -154,7 +155,7 @@ public class ChristmasTreeGameLogicService : IGameLogicService }; // Check if game ended - bool gameEnded = CheckAllFivesGone(teamTrees); + bool gameEnded = CheckGameEndCondition(teamTrees, model.EndCondition); if (gameEnded) { lastThrow = lastThrow with { TriggeredGameEnd = true }; @@ -557,7 +558,7 @@ public class ChristmasTreeGameLogicService : IGameLogicService }; // Check for game end - bool gameEnded = CheckAllFivesGone(teamTrees); + bool gameEnded = CheckGameEndCondition(teamTrees, model.EndCondition); var triggers = new List(); if (gameEnded) @@ -735,6 +736,18 @@ public class ChristmasTreeGameLogicService : IGameLogicService return crossedTeams; } + private static bool CheckGameEndCondition( + Dictionary teamTrees, + GameEndCondition endCondition) + { + return endCondition switch + { + GameEndCondition.AllFivesGone => CheckAllFivesGone(teamTrees), + GameEndCondition.TreeCleared => CheckAnyTreeCleared(teamTrees), + _ => CheckAllFivesGone(teamTrees) + }; + } + private static bool CheckAllFivesGone(Dictionary teamTrees) { foreach (var state in teamTrees.Values) @@ -747,6 +760,18 @@ public class ChristmasTreeGameLogicService : IGameLogicService return true; } + private static bool CheckAnyTreeCleared(Dictionary teamTrees) + { + foreach (var state in teamTrees.Values) + { + if (state.RemainingNumbers.Values.Sum() == 0) + { + return true; + } + } + return false; + } + private static ChristmasTreeGameSetup ParseSetupOptions(object? setupOptions) { if (setupOptions is null) diff --git a/src/Koogle.Application/Games/ChristmasTree/ChristmasTreeGameModel.cs b/src/Koogle.Application/Games/ChristmasTree/ChristmasTreeGameModel.cs index a96cb94..2966e92 100644 --- a/src/Koogle.Application/Games/ChristmasTree/ChristmasTreeGameModel.cs +++ b/src/Koogle.Application/Games/ChristmasTree/ChristmasTreeGameModel.cs @@ -10,6 +10,11 @@ public record ChristmasTreeGameModel : IGameModel /// public TreeVariant Variant { get; init; } + /// + /// The game end condition. + /// + public GameEndCondition EndCondition { get; init; } + /// /// Tree state for each team. Key = team index (0-based). /// diff --git a/src/Koogle.Application/Games/ChristmasTree/ChristmasTreeGameSetup.cs b/src/Koogle.Application/Games/ChristmasTree/ChristmasTreeGameSetup.cs index a42afb7..18d7568 100644 --- a/src/Koogle.Application/Games/ChristmasTree/ChristmasTreeGameSetup.cs +++ b/src/Koogle.Application/Games/ChristmasTree/ChristmasTreeGameSetup.cs @@ -2,6 +2,22 @@ using Koogle.Domain.Enums; namespace Koogle.Application.Games.ChristmasTree; +/// +/// Game end condition for the Christmas Tree game. +/// +public enum GameEndCondition +{ + /// + /// Game ends when all 5s are crossed out from all trees. + /// + AllFivesGone, + + /// + /// Game ends when any team has cleared their entire tree. + /// + TreeCleared +} + /// /// Tree variant for the Christmas Tree game. /// @@ -47,6 +63,11 @@ public record ChristmasTreeGameSetup : GameSetupModelBase /// public int MaxContinueThrows { get; init; } = 3; + /// + /// Condition that triggers game end. + /// + public GameEndCondition EndCondition { get; init; } = GameEndCondition.AllFivesGone; + /// /// Creates a new setup with default values. /// @@ -56,6 +77,7 @@ public record ChristmasTreeGameSetup : GameSetupModelBase TreeVariant variant = TreeVariant.Beginner, bool enableContinueOnMiss = false, int maxContinueThrows = 3, + GameEndCondition endCondition = GameEndCondition.AllFivesGone, IReadOnlyList? teams = null) => new() { ThrowMode = throwMode, @@ -64,6 +86,7 @@ public record ChristmasTreeGameSetup : GameSetupModelBase Variant = variant, EnableContinueOnMiss = enableContinueOnMiss, MaxContinueThrows = maxContinueThrows, + EndCondition = endCondition, Teams = teams }; diff --git a/src/Koogle.Web/Components/Game/ChristmasTree/ChristmasTreeSetup.razor b/src/Koogle.Web/Components/Game/ChristmasTree/ChristmasTreeSetup.razor index f971ca2..ad58dd8 100644 --- a/src/Koogle.Web/Components/Game/ChristmasTree/ChristmasTreeSetup.razor +++ b/src/Koogle.Web/Components/Game/ChristmasTree/ChristmasTreeSetup.razor @@ -21,6 +21,15 @@ Große Pyramide + + Alle 5er gestrichen + Ein Baum komplett leer + + "" }; + private string GetEndConditionDescription(GameEndCondition condition) => condition switch + { + GameEndCondition.AllFivesGone => "Spiel endet, wenn alle 5er bei allen Teams gestrichen sind", + GameEndCondition.TreeCleared => "Spiel endet, wenn ein Team alle Zahlen gestrichen hat", + _ => "" + }; + public IGameSetupModel GameSetupModel => new ChristmasTreeGameSetup { ThrowMode = ThrowMode.Reposition, @@ -139,6 +156,7 @@ Variant = _options.Variant, EnableContinueOnMiss = _options.EnableContinueOnMiss, MaxContinueThrows = _options.MaxContinueThrows, + EndCondition = _options.EndCondition, Teams = Teams }; @@ -147,5 +165,6 @@ public TreeVariant Variant { get; set; } = TreeVariant.Beginner; public bool EnableContinueOnMiss { get; set; } = false; public int MaxContinueThrows { get; set; } = 3; + public GameEndCondition EndCondition { get; set; } = GameEndCondition.AllFivesGone; } }