dev foxhunt
This commit is contained in:
parent
433b61618d
commit
187a7e14c8
|
|
@ -73,6 +73,8 @@ namespace Koogle.Application.Games.FoxHunt
|
||||||
var triggers = new List<TriggerEvent>();
|
var triggers = new List<TriggerEvent>();
|
||||||
|
|
||||||
var foxId = model.PlayerOrder[model.FoxIndex];
|
var foxId = model.PlayerOrder[model.FoxIndex];
|
||||||
|
var lastHunterId = GetPrev(model, model.FoxIndex);
|
||||||
|
var isLastHunter = lastHunterId == playerId;
|
||||||
|
|
||||||
if (model.FoxTurn)
|
if (model.FoxTurn)
|
||||||
{
|
{
|
||||||
|
|
@ -81,15 +83,41 @@ namespace Koogle.Application.Games.FoxHunt
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
playerStates[foxId].PinCountHunters+= afterThrow.PinsKnocked;
|
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
|
// Update model
|
||||||
model = model with
|
model = model with
|
||||||
|
|
@ -105,7 +133,7 @@ namespace Koogle.Application.Games.FoxHunt
|
||||||
PointsScored = pinsKnocked,
|
PointsScored = pinsKnocked,
|
||||||
ShouldRotatePlayer = true,
|
ShouldRotatePlayer = true,
|
||||||
IsGameOver = isGameOver,
|
IsGameOver = isGameOver,
|
||||||
WinnerId = winnerId,
|
WinnerId = null,
|
||||||
Triggers = triggers,
|
Triggers = triggers,
|
||||||
Overrides = isGameOver ? null : new GameLogicOverrides
|
Overrides = isGameOver ? null : new GameLogicOverrides
|
||||||
{
|
{
|
||||||
|
|
@ -125,13 +153,22 @@ namespace Koogle.Application.Games.FoxHunt
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
/// <exception cref="InvalidOperationException"></exception>
|
/// <exception cref="InvalidOperationException"></exception>
|
||||||
private Guid GetNextId(FoxHuntGameModel model)
|
private Guid GetNextId(FoxHuntGameModel model, bool chooseNextFox)
|
||||||
{
|
{
|
||||||
// Abbruch: alle waren einmal Fuchs
|
// Abbruch: alle waren einmal Fuchs
|
||||||
if (model.FoxIndex >= model.PlayerOrder.Length)
|
if (model.FoxIndex >= model.PlayerOrder.Length)
|
||||||
throw new InvalidOperationException("Alle Spieler waren bereits Fuchs.");
|
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
|
// 1️⃣ Fuchs ist 2x hintereinander dran
|
||||||
if (model.FoxTurnsRemaining > 0)
|
if (model.FoxTurnsRemaining > 0)
|
||||||
|
|
@ -146,33 +183,72 @@ namespace Koogle.Application.Games.FoxHunt
|
||||||
// 2️⃣ Abwechselnd Nicht-Fuchs → Fuchs
|
// 2️⃣ Abwechselnd Nicht-Fuchs → Fuchs
|
||||||
if (!model.FoxTurn)
|
if (!model.FoxTurn)
|
||||||
{
|
{
|
||||||
// nächsten Nicht-Fuchs suchen
|
var nextNonFoxIndex = GetNextIndex(model, model.NonFoxIndex);
|
||||||
while (model.NonFoxIndex == model.FoxIndex)
|
if (nextNonFoxIndex == model.FoxIndex)
|
||||||
model.NonFoxIndex++;
|
{
|
||||||
|
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)
|
// nächsten Nicht-Fuchs suchen
|
||||||
{
|
//while (model.NonFoxIndex == model.FoxIndex)
|
||||||
Guid next = model.PlayerOrder[model.NonFoxIndex];
|
// model.NonFoxIndex++;
|
||||||
model.NonFoxIndex++;
|
|
||||||
//model.FoxTurn = true;
|
//if (model.NonFoxIndex < model.PlayerOrder.Length)
|
||||||
return next;
|
//{
|
||||||
}
|
// Guid next = model.PlayerOrder[model.NonFoxIndex];
|
||||||
else
|
// model.NonFoxIndex++;
|
||||||
{
|
// //model.FoxTurn = true;
|
||||||
// Alle Nicht-Füchse durch → neuer Fuchs
|
// return next;
|
||||||
model.FoxIndex++;
|
//}
|
||||||
model.NonFoxIndex = 0;
|
//else
|
||||||
model.FoxTurnsRemaining = model.LeadingThrows - 1;
|
//{
|
||||||
model.FoxTurn = true;
|
// // Alle Nicht-Füchse durch → neuer Fuchs
|
||||||
return GetNextId(model);
|
// model.FoxIndex++;
|
||||||
}
|
// model.NonFoxIndex = 0;
|
||||||
|
// model.FoxTurnsRemaining = model.LeadingThrows - 1;
|
||||||
|
// model.FoxTurn = true;
|
||||||
|
// return GetNextId(model);
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 3️⃣ Fuchs-Zug im Wechsel
|
// 3️⃣ Fuchs-Zug im Wechsel
|
||||||
//model.FoxTurn = false;
|
//model.FoxTurn = false;
|
||||||
return foxId;
|
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(
|
private static int GetNextActivePlayerIndex(
|
||||||
Guid[] playerOrder,
|
Guid[] playerOrder,
|
||||||
int currentIndex,
|
int currentIndex,
|
||||||
|
|
|
||||||
|
|
@ -35,5 +35,9 @@
|
||||||
public int PinCountFox { get; set; }
|
public int PinCountFox { get; set; }
|
||||||
|
|
||||||
public int PinCountHunters { get; set; }
|
public int PinCountHunters { get; set; }
|
||||||
|
|
||||||
|
public bool FoxCaught { get; set; }
|
||||||
|
public bool IsWinner { get; set; }
|
||||||
|
public bool FoxEscaped { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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.Application.Games.FoxHunt
|
||||||
@using Koogle.Web.Store.DayState
|
@using Koogle.Web.Store.DayState
|
||||||
@using Koogle.Web.Store.GameState
|
@using Koogle.Web.Store.GameState
|
||||||
@using Koogle.Application.Games;
|
@using Koogle.Application.Games;
|
||||||
|
|
||||||
|
@inherits Fluxor.Blazor.Web.Components.FluxorComponent
|
||||||
|
|
||||||
@implements IDisposable
|
@implements IDisposable
|
||||||
@inject IState<GameState> GameState
|
@inject IState<GameState> GameState
|
||||||
@inject IState<DayState> DayState
|
@inject IState<DayState> DayState
|
||||||
|
|
||||||
<pre>
|
@* <pre>
|
||||||
@_debug
|
@_debug
|
||||||
</pre>
|
</pre> *@
|
||||||
|
|
||||||
<MudPaper Class="pa-4">
|
<MudPaper Class="pa-4">
|
||||||
@if (_model == null)
|
@if (_model == null)
|
||||||
|
|
@ -29,16 +29,16 @@
|
||||||
<MudText Typo="Typo.body1">
|
<MudText Typo="Typo.body1">
|
||||||
<strong>Vorsprung für den Fuchs:</strong>
|
<strong>Vorsprung für den Fuchs:</strong>
|
||||||
<MudChip T="string" Size="Size.Small" Color="Color.Default" Variant="Variant.Outlined">
|
<MudChip T="string" Size="Size.Small" Color="Color.Default" Variant="Variant.Outlined">
|
||||||
@_model.LeadingThrows Vorsprung
|
@_model.LeadingThrows Wurf
|
||||||
</MudChip>
|
</MudChip>
|
||||||
</MudText>
|
</MudText>
|
||||||
<MudText Typo="Typo.body1">
|
@* <MudText Typo="Typo.body1">
|
||||||
<strong>Füchse übrig:</strong>
|
<strong>Füchse übrig:</strong>
|
||||||
<MudChip T="string" Size="Size.Small" Color="Color.Primary" Variant="Variant.Filled">
|
<MudChip T="string" Size="Size.Small" Color="Color.Primary" Variant="Variant.Filled">
|
||||||
0
|
0
|
||||||
</MudChip>
|
</MudChip>
|
||||||
</MudText>
|
</MudText>
|
||||||
</MudStack>
|
*@ </MudStack>
|
||||||
</MudPaper>
|
</MudPaper>
|
||||||
|
|
||||||
@* Last throw info *@
|
@* Last throw info *@
|
||||||
|
|
@ -70,12 +70,12 @@
|
||||||
Class="mb-4">
|
Class="mb-4">
|
||||||
<HeaderContent>
|
<HeaderContent>
|
||||||
<MudTh>Spieler</MudTh>
|
<MudTh>Spieler</MudTh>
|
||||||
<MudTh>Status</MudTh>
|
|
||||||
<MudTh Style="text-align: center">Xs</MudTh>
|
|
||||||
<MudTh Style="text-align: center">Eier</MudTh>
|
|
||||||
<MudTh Style="text-align: center">Status</MudTh>
|
<MudTh Style="text-align: center">Status</MudTh>
|
||||||
|
<MudTh>Punkte</MudTh>
|
||||||
|
<MudTh Style="text-align: center">Ergebnis</MudTh>
|
||||||
</HeaderContent>
|
</HeaderContent>
|
||||||
<RowTemplate>
|
<RowTemplate>
|
||||||
|
<!-- Spieler -->
|
||||||
<MudTd>
|
<MudTd>
|
||||||
@if (context.IsCurrentPlayer && !_model.IsGameOver)
|
@if (context.IsCurrentPlayer && !_model.IsGameOver)
|
||||||
{
|
{
|
||||||
|
|
@ -89,14 +89,14 @@
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<MudText Typo="Typo.body1" Style="@(context.IsEliminated ? "text-decoration: line-through; color: var(--mud-palette-text-disabled);" : "")">
|
<MudText Typo="Typo.body1">
|
||||||
@context.PlayerName
|
@context.PlayerName
|
||||||
</MudText>
|
</MudText>
|
||||||
}
|
}
|
||||||
</MudTd>
|
</MudTd>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Status -->
|
||||||
<MudTd Style="text-align: center">
|
<MudTd Style="text-align: center">
|
||||||
@if (context.IsWinner)
|
@if (context.IsWinner)
|
||||||
{
|
{
|
||||||
|
|
@ -105,18 +105,56 @@
|
||||||
SIEGER
|
SIEGER
|
||||||
</MudChip>
|
</MudChip>
|
||||||
}
|
}
|
||||||
else if (context.IsEliminated)
|
|
||||||
{
|
|
||||||
<MudChip T="string" Size="Size.Small" Color="Color.Error" Variant="Variant.Outlined">
|
|
||||||
☠️ Platz @context.FoxSurvivalOrder
|
|
||||||
</MudChip>
|
|
||||||
}
|
|
||||||
else if (context.IsCurrentPlayer)
|
else if (context.IsCurrentPlayer)
|
||||||
{
|
{
|
||||||
<MudChip T="string" Size="Size.Small" Color="Color.Primary" Variant="Variant.Outlined">
|
<MudChip T="string" Size="Size.Small" Color="Color.Warning" Variant="Variant.Outlined">
|
||||||
Am Zug
|
Am Zug
|
||||||
</MudChip>
|
</MudChip>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@if (context.IsFox)
|
||||||
|
{
|
||||||
|
<MudChip T="string" Size="Size.Small" Color="Color.Warning" Variant="Variant.Outlined">
|
||||||
|
Fuchs
|
||||||
|
</MudChip>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<MudChip T="string" Size="Size.Small" Color="Color.Info" Variant="Variant.Outlined">
|
||||||
|
Jäger
|
||||||
|
</MudChip>
|
||||||
|
}
|
||||||
|
</MudTd>
|
||||||
|
|
||||||
|
<!-- Punkte -->
|
||||||
|
<MudTd>
|
||||||
|
|
||||||
|
<MudText Typo="Typo.body1" Color="@(context.IsFox ? Color.Warning : Color.Secondary)">
|
||||||
|
@if (context.LeadingCount > 0)
|
||||||
|
{
|
||||||
|
@($"Fuchs: {context.PinCountFox} Jäger: {@context.PinCountHunters} Vorsprung: {@context.LeadingCount}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
@($"Fuchs: {context.PinCountFox} Jäger: {@context.PinCountHunters}")
|
||||||
|
}
|
||||||
|
</MudText>
|
||||||
|
</MudTd>
|
||||||
|
|
||||||
|
<!-- Fuchs gefangen -->
|
||||||
|
<MudTd Style="text-align: center">
|
||||||
|
@if (context.FoxCaught)
|
||||||
|
{
|
||||||
|
<MudChip T="string" Size="Size.Small" Color="Color.Error" Variant="Variant.Outlined">
|
||||||
|
☠️ @context.PlayerName ist ein toter Fuchs
|
||||||
|
</MudChip>
|
||||||
|
}
|
||||||
|
@if (context.FoxEscaped)
|
||||||
|
{
|
||||||
|
<MudChip T="string" Size="Size.Small" Color="Color.Success" Variant="Variant.Outlined">
|
||||||
|
🗸 Fuchs @context.PlayerName ist entkommen
|
||||||
|
</MudChip>
|
||||||
|
}
|
||||||
</MudTd>
|
</MudTd>
|
||||||
</RowTemplate>
|
</RowTemplate>
|
||||||
</MudTable>
|
</MudTable>
|
||||||
|
|
@ -186,6 +224,35 @@
|
||||||
return;
|
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()
|
public void Dispose()
|
||||||
|
|
@ -206,8 +273,13 @@
|
||||||
public string Status { get; init; } = "";
|
public string Status { get; init; } = "";
|
||||||
public bool IsWinner { get; init; }
|
public bool IsWinner { get; init; }
|
||||||
public bool IsCurrentPlayer { get; init; }
|
public bool IsCurrentPlayer { get; init; }
|
||||||
public bool IsEliminated { get; init; }
|
public bool IsFox { get; init; }
|
||||||
public int FoxSurvivalOrder { 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; }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue