KoogleApp/src/Koogle.Application/Games/DeathBox/DeathBoxGameModel.cs

187 lines
5.1 KiB
C#

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