fix player rotation with different team sizes

This commit is contained in:
beo3000 2026-02-08 17:03:46 +01:00
parent 4c01fda12c
commit d0e4d01985
2 changed files with 31 additions and 27 deletions

View File

@ -35,6 +35,10 @@ public class ChristmasTreeGameLogicService : IGameLogicService
};
}
var playerIndexPerTeam = new Dictionary<int, int>();
for (int i = 0; i < options.Teams.Count; i++)
playerIndexPerTeam[i] = 0;
return new ChristmasTreeGameModel
{
Variant = options.Variant,
@ -43,6 +47,7 @@ public class ChristmasTreeGameLogicService : IGameLogicService
Teams = options.Teams.ToList(),
CurrentTeamIndex = 0,
CurrentPlayerIndexInTeam = 0,
PlayerIndexPerTeam = playerIndexPerTeam,
EnableContinueOnMiss = options.EnableContinueOnMiss,
MaxContinueThrows = options.MaxContinueThrows,
ContinueThrowsRemaining = 0,
@ -348,23 +353,16 @@ public class ChristmasTreeGameLogicService : IGameLogicService
ChristmasTreeGameModel model,
List<TriggerEvent> triggers)
{
// Rotate to next team and player
int nextTeamIndex = (model.CurrentTeamIndex + 1) % model.Teams.Count;
int nextPlayerIndex = 0;
// Advance current team's player index independently
var playerIndices = new Dictionary<int, int>(
model.PlayerIndexPerTeam.Count > 0 ? model.PlayerIndexPerTeam
: Enumerable.Range(0, model.Teams.Count).ToDictionary(i => i, _ => 0));
if (nextTeamIndex == 0)
{
// Wrapped around - increment player index within teams
// This assumes all teams have same number of players
// For varying team sizes, we track per-team player index
nextPlayerIndex = (model.CurrentPlayerIndexInTeam + 1) %
Math.Max(1, model.Teams[nextTeamIndex].PlayerIds.Count);
}
else
{
nextPlayerIndex = model.CurrentPlayerIndexInTeam %
Math.Max(1, model.Teams[nextTeamIndex].PlayerIds.Count);
}
int currentTeamSize = Math.Max(1, model.Teams[model.CurrentTeamIndex].PlayerIds.Count);
playerIndices[model.CurrentTeamIndex] = (playerIndices[model.CurrentTeamIndex] + 1) % currentTeamSize;
int nextTeamIndex = (model.CurrentTeamIndex + 1) % model.Teams.Count;
int nextPlayerIndex = playerIndices[nextTeamIndex];
var nextPlayerId = model.Teams[nextTeamIndex].PlayerIds.Count > nextPlayerIndex
? model.Teams[nextTeamIndex].PlayerIds[nextPlayerIndex]
@ -373,7 +371,8 @@ public class ChristmasTreeGameLogicService : IGameLogicService
model = model with
{
CurrentTeamIndex = nextTeamIndex,
CurrentPlayerIndexInTeam = nextPlayerIndex
CurrentPlayerIndexInTeam = nextPlayerIndex,
PlayerIndexPerTeam = playerIndices
};
return (model, new ThrowResult
@ -643,16 +642,15 @@ public class ChristmasTreeGameLogicService : IGameLogicService
}
// Clear selection state and rotate to next player
var playerIndices = new Dictionary<int, int>(
model.PlayerIndexPerTeam.Count > 0 ? model.PlayerIndexPerTeam
: Enumerable.Range(0, model.Teams.Count).ToDictionary(i => i, _ => 0));
int currentTeamSize = Math.Max(1, model.Teams[model.CurrentTeamIndex].PlayerIds.Count);
playerIndices[model.CurrentTeamIndex] = (playerIndices[model.CurrentTeamIndex] + 1) % currentTeamSize;
int nextTeamIndex = (model.CurrentTeamIndex + 1) % model.Teams.Count;
int nextPlayerIndex = model.CurrentPlayerIndexInTeam;
if (nextTeamIndex == 0)
{
nextPlayerIndex = (nextPlayerIndex + 1) % Math.Max(1, model.Teams[nextTeamIndex].PlayerIds.Count);
}
else
{
nextPlayerIndex = nextPlayerIndex % Math.Max(1, model.Teams[nextTeamIndex].PlayerIds.Count);
}
int nextPlayerIndex = playerIndices[nextTeamIndex];
var nextPlayerId = model.Teams[nextTeamIndex].PlayerIds.Count > nextPlayerIndex
? model.Teams[nextTeamIndex].PlayerIds[nextPlayerIndex]
@ -663,7 +661,8 @@ public class ChristmasTreeGameLogicService : IGameLogicService
TeamTrees = teamTrees,
OpponentSelectingTeamIndex = null,
CurrentTeamIndex = nextTeamIndex,
CurrentPlayerIndexInTeam = nextPlayerIndex
CurrentPlayerIndexInTeam = nextPlayerIndex,
PlayerIndexPerTeam = playerIndices
};
return GameActionResult.SuccessResult(

View File

@ -35,6 +35,11 @@ public record ChristmasTreeGameModel : IGameModel
/// </summary>
public int CurrentPlayerIndexInTeam { get; set; }
/// <summary>
/// Player index per team (key = team index). Each team cycles independently.
/// </summary>
public Dictionary<int, int> PlayerIndexPerTeam { get; init; } = new();
/// <summary>
/// Whether continue-on-miss variant is enabled.
/// </summary>