namespace Koogle.Application.Games.DeathBox;
///
/// Game model for DeathBox (Totenkisten) game type.
/// Players collect marks (Striche) and are eliminated when their coffin is full.
/// Last player standing wins.
///
public record DeathBoxGameModel : IGameModel
{
///
/// Coffin size (6-12 marks). When a player reaches this many marks, they're eliminated.
///
public int CoffinSize { get; init; } = 12;
///
/// State for each player (marks, X's, eggs, eliminated status).
///
public Dictionary PlayerStates { get; init; } = new();
///
/// Fixed player order (randomized at game start).
///
public Guid[] PlayerOrder { get; init; } = [];
///
/// Current player index in PlayerOrder.
///
public int CurrentPlayerIndex { get; set; }
///
/// ID of the previous player who threw (for "cleared pins" penalty).
///
public Guid? PreviousPlayerId { get; set; }
///
/// List of eliminated player IDs in elimination order.
///
public List EliminatedPlayers { get; init; } = [];
///
/// ID of the winner (last player standing).
///
public Guid? WinnerId { get; set; }
///
/// Whether the game has ended.
///
public bool IsGameOver { get; set; }
///
/// Last throw info for display.
///
public DeathBoxLastThrow? LastThrow { get; set; }
///
/// Pending game events that require UI notification.
///
public List PendingGameEvents { get; init; } = [];
}
///
/// State for a single player in DeathBox.
///
public record DeathBoxPlayerState
{
///
/// Current marks (Striche). Player is eliminated when this reaches CoffinSize.
///
public int Marks { get; set; }
///
/// Current X count. 3 X's = +1 mark + reset X's.
///
public int XCount { get; set; }
///
/// Current egg count. 3 eggs = -1 mark (if possible) + reset eggs.
///
public int EggCount { get; set; }
///
/// Whether this player is eliminated.
///
public bool IsEliminated { get; set; }
///
/// Total throws made by this player.
///
public int ThrowCount { get; set; }
///
/// Total pins knocked down.
///
public int TotalPins { get; set; }
}
///
/// Info about the last throw for UI display.
///
public record DeathBoxLastThrow
{
///
/// Player who made the throw.
///
public Guid PlayerId { get; init; }
///
/// Number of pins knocked down.
///
public int PinsKnocked { get; init; }
///
/// Whether this was a new round (all 9 pins were standing).
///
public bool IsNewRound { get; init; }
///
/// Whether a penalty was applied for <3 pins on new round.
///
public bool WasPenalty { get; init; }
///
/// Whether the throw was a gutter.
///
public bool WasGutter { get; init; }
///
/// Whether the throw was "no wood" (0 pins but not gutter).
///
public bool WasNoWood { get; init; }
///
/// Whether all remaining pins were cleared.
///
public bool WasCleared { get; init; }
///
/// Whether player earned an X (always on new round).
///
public bool EarnedX { get; init; }
///
/// Whether player earned an egg (on clearing).
///
public bool EarnedEgg { get; init; }
///
/// Whether 3 X's were converted to 1 mark.
///
public bool ConvertedXsToMark { get; init; }
///
/// Whether 3 eggs were converted to remove 1 mark.
///
public bool ConvertedEggsToRemoveMark { get; init; }
///
/// Whether the next player got a mark (cleared penalty).
///
public bool NextPlayerGotMark { get; init; }
///
/// ID of next player who got a mark (if any).
///
public Guid? NextPlayerPenalizedId { get; init; }
///
/// Whether the previous player got a mark (cleared penalty).
///
public bool PreviousPlayerGotMark { get; init; }
///
/// ID of previous player who got a mark (if any).
///
public Guid? PreviousPlayerPenalizedId { get; init; }
///
/// Whether the current player was eliminated this throw.
///
public bool PlayerEliminated { get; init; }
///
/// Whether the previous player was eliminated due to cleared penalty.
///
public bool PreviousPlayerEliminated { get; init; }
}