feat: resolve objective control and objective victory

This commit is contained in:
Keith Solomon
2026-07-05 20:06:27 -05:00
parent 6befe7b3e2
commit 84fb175c0c
2 changed files with 88 additions and 20 deletions
+25 -20
View File
@@ -180,12 +180,7 @@ final class CombatEngine
actionLog: [...$match->actionLog, "{$endingTeamId} ended turn"],
);
$winner = $this->resolveObjectiveVictory($next);
if ($winner !== null) {
$next = $next->withWinner($winner);
}
return $next;
return $this->resolveObjectiveVictory($next, $endingTeamId === $teamIds[0]);
}
/**
@@ -291,29 +286,39 @@ final class CombatEngine
return $match->withWinner($actingTeamId);
}
private function resolveObjectiveVictory(MatchState $match): ?string
/**
* @param bool $endingTeamIsFirstInOrder true when the team that just ended is the first team in
* sorted team order; this identifies the first half of a round.
*/
private function resolveObjectiveVictory(MatchState $match, bool $endingTeamIsFirstInOrder): MatchState
{
if ($match->victoryCondition !== VictoryCondition::HoldObjective || $match->objectives === []) {
return null;
return $match;
}
/** @var list<ObjectiveMarker> $objectiveList */
$objectiveList = array_values($match->objectives);
$objective = $objectiveList[0];
$controller = $this->objectiveController($match, $objective->position);
$next = $match;
if ($controller === null) {
return null;
if ($endingTeamIsFirstInOrder) {
/** @var list<ObjectiveMarker> $objectiveList */
$objectiveList = array_values($match->objectives);
$objective = $objectiveList[0];
$controller = $this->objectiveController($match, $objective->position);
if ($controller !== null) {
$control = (new ObjectiveControl($match->objectiveControl))->recordRound($controller);
$next = $match->withObjectiveControl($control->roundsByTeam);
}
return $next;
}
$control = (new ObjectiveControl($match->objectiveControl))->recordRound($controller);
$next = $match->withObjectiveControl($control->roundsByTeam);
if (($control->roundsByTeam[$controller] ?? 0) >= $next->holdRoundsRequired) {
return $controller;
foreach ($match->objectiveControl as $teamId => $count) {
if ($count >= $match->holdRoundsRequired) {
return $next->withWinner($teamId);
}
}
return null;
return $next;
}
private function objectiveController(MatchState $match, Position $tile): ?string