added christmasTree additional End Option:

ChristmasTreeGameSetup.cs
  - Neues Enum GameEndCondition mit AllFivesGone (Standard) und TreeCleared
  - Property EndCondition zum Setup hinzugefügt

  ChristmasTreeGameModel.cs
  - Property EndCondition hinzugefügt

  ChristmasTreeGameLogicService.cs
  - Neue Methode CheckGameEndCondition() prüft je nach Einstellung
  - Neue Methode CheckAnyTreeCleared() prüft ob ein Team alle Zahlen gestrichen hat
  - Alle 3 Stellen wo Spielende geprüft wird nutzen jetzt die flexible Methode

  ChristmasTreeSetup.razor
  - Neues Dropdown "Spielende" mit zwei Optionen:
    - "Alle 5er gestrichen" (Standard)
    - "Ein Baum komplett leer"
  - Hilfstexte erklären die jeweilige Bedingung
This commit is contained in:
beo3000 2026-01-08 18:58:28 +01:00
parent 56f3e63046
commit 65c18f4f51
4 changed files with 77 additions and 5 deletions

View File

@ -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<TriggerEvent>();
if (gameEnded)
@ -735,6 +736,18 @@ public class ChristmasTreeGameLogicService : IGameLogicService
return crossedTeams;
}
private static bool CheckGameEndCondition(
Dictionary<int, TeamTreeState> teamTrees,
GameEndCondition endCondition)
{
return endCondition switch
{
GameEndCondition.AllFivesGone => CheckAllFivesGone(teamTrees),
GameEndCondition.TreeCleared => CheckAnyTreeCleared(teamTrees),
_ => CheckAllFivesGone(teamTrees)
};
}
private static bool CheckAllFivesGone(Dictionary<int, TeamTreeState> teamTrees)
{
foreach (var state in teamTrees.Values)
@ -747,6 +760,18 @@ public class ChristmasTreeGameLogicService : IGameLogicService
return true;
}
private static bool CheckAnyTreeCleared(Dictionary<int, TeamTreeState> 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)

View File

@ -10,6 +10,11 @@ public record ChristmasTreeGameModel : IGameModel
/// </summary>
public TreeVariant Variant { get; init; }
/// <summary>
/// The game end condition.
/// </summary>
public GameEndCondition EndCondition { get; init; }
/// <summary>
/// Tree state for each team. Key = team index (0-based).
/// </summary>

View File

@ -2,6 +2,22 @@ using Koogle.Domain.Enums;
namespace Koogle.Application.Games.ChristmasTree;
/// <summary>
/// Game end condition for the Christmas Tree game.
/// </summary>
public enum GameEndCondition
{
/// <summary>
/// Game ends when all 5s are crossed out from all trees.
/// </summary>
AllFivesGone,
/// <summary>
/// Game ends when any team has cleared their entire tree.
/// </summary>
TreeCleared
}
/// <summary>
/// Tree variant for the Christmas Tree game.
/// </summary>
@ -47,6 +63,11 @@ public record ChristmasTreeGameSetup : GameSetupModelBase
/// </summary>
public int MaxContinueThrows { get; init; } = 3;
/// <summary>
/// Condition that triggers game end.
/// </summary>
public GameEndCondition EndCondition { get; init; } = GameEndCondition.AllFivesGone;
/// <summary>
/// Creates a new setup with default values.
/// </summary>
@ -56,6 +77,7 @@ public record ChristmasTreeGameSetup : GameSetupModelBase
TreeVariant variant = TreeVariant.Beginner,
bool enableContinueOnMiss = false,
int maxContinueThrows = 3,
GameEndCondition endCondition = GameEndCondition.AllFivesGone,
IReadOnlyList<GameTeam>? teams = null) => new()
{
ThrowMode = throwMode,
@ -64,6 +86,7 @@ public record ChristmasTreeGameSetup : GameSetupModelBase
Variant = variant,
EnableContinueOnMiss = enableContinueOnMiss,
MaxContinueThrows = maxContinueThrows,
EndCondition = endCondition,
Teams = teams
};

View File

@ -21,6 +21,15 @@
<MudSelectItem Value="TreeVariant.LargePyramid">Große Pyramide</MudSelectItem>
</MudSelect>
<MudSelect T="GameEndCondition"
@bind-Value="_options.EndCondition"
Label="Spielende"
Variant="Variant.Outlined"
HelperText="@GetEndConditionDescription(_options.EndCondition)">
<MudSelectItem Value="GameEndCondition.AllFivesGone">Alle 5er gestrichen</MudSelectItem>
<MudSelectItem Value="GameEndCondition.TreeCleared">Ein Baum komplett leer</MudSelectItem>
</MudSelect>
<MudSwitch T="bool"
@bind-Value="_options.EnableContinueOnMiss"
Label="Weiterkegeln bei Fehlwurf"
@ -103,7 +112,8 @@
{
Variant = setup.Variant,
EnableContinueOnMiss = setup.EnableContinueOnMiss,
MaxContinueThrows = setup.MaxContinueThrows
MaxContinueThrows = setup.MaxContinueThrows,
EndCondition = setup.EndCondition
};
}
@ -131,6 +141,13 @@
_ => ""
};
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;
}
}