fix: round-trip match objectives through ScenarioSerializer

This commit is contained in:
Keith Solomon
2026-07-25 22:21:25 -05:00
parent a6d93dd1d3
commit a0dcff2c2a
2 changed files with 55 additions and 1 deletions
+18 -1
View File
@@ -130,6 +130,14 @@ final class ScenarioSerializer
$units[] = self::unitToArray($unit); $units[] = self::unitToArray($unit);
} }
$objectives = [];
foreach ($match->objectives as $id => $objective) {
$objectives[(string) $id] = [
'id' => $objective->id,
'position' => self::positionToArray($objective->position),
];
}
return [ return [
'battlefield' => [ 'battlefield' => [
'width' => $match->battlefield->width, 'width' => $match->battlefield->width,
@@ -141,6 +149,7 @@ final class ScenarioSerializer
'round' => $match->round, 'round' => $match->round,
'winnerTeamId' => $match->winnerTeamId, 'winnerTeamId' => $match->winnerTeamId,
'actionLog' => $match->actionLog, 'actionLog' => $match->actionLog,
'objectives' => $objectives,
'victoryCondition' => $match->victoryCondition->value, 'victoryCondition' => $match->victoryCondition->value,
'holdRoundsRequired' => $match->holdRoundsRequired, 'holdRoundsRequired' => $match->holdRoundsRequired,
'objectiveControl' => $match->objectiveControl, 'objectiveControl' => $match->objectiveControl,
@@ -166,6 +175,14 @@ final class ScenarioSerializer
$units[] = self::unitFromArray($row); $units[] = self::unitFromArray($row);
} }
$objectives = [];
foreach (($data['objectives'] ?? []) as $id => $row) {
$objectives[(string) $id] = new ObjectiveMarker(
(string) $row['id'],
self::positionFromArray($row['position']),
);
}
return new MatchState( return new MatchState(
battlefield: $battlefield, battlefield: $battlefield,
units: $units, units: $units,
@@ -173,7 +190,7 @@ final class ScenarioSerializer
round: (int) $data['round'], round: (int) $data['round'],
winnerTeamId: $data['winnerTeamId'] ?? null, winnerTeamId: $data['winnerTeamId'] ?? null,
actionLog: array_map(static fn (mixed $entry): string => (string) $entry, $data['actionLog'] ?? []), actionLog: array_map(static fn (mixed $entry): string => (string) $entry, $data['actionLog'] ?? []),
objectives: [], objectives: $objectives,
victoryCondition: VictoryCondition::from((string) $data['victoryCondition']), victoryCondition: VictoryCondition::from((string) $data['victoryCondition']),
holdRoundsRequired: (int) $data['holdRoundsRequired'], holdRoundsRequired: (int) $data['holdRoundsRequired'],
objectiveControl: $data['objectiveControl'] ?? [], objectiveControl: $data['objectiveControl'] ?? [],
@@ -135,4 +135,41 @@ final class ScenarioSerializerTest extends TestCase
// missing 'name', 'battlefield', 'units', etc. // missing 'name', 'battlefield', 'units', etc.
]); ]);
} }
public function testMatchRoundTripsItsObjectives(): void
{
$battlefield = new Battlefield(10, 8);
$units = [
new UnitState('a1', 'alpha', new Position(0, 0), 10, 10, 3, 3, 2, 2, false),
new UnitState('a2', 'alpha', new Position(1, 0), 10, 10, 3, 3, 2, 2, false),
new UnitState('a3', 'alpha', new Position(2, 0), 10, 10, 3, 3, 2, 2, false),
new UnitState('b1', 'bravo', new Position(9, 7), 10, 10, 3, 3, 2, 2, false),
new UnitState('b2', 'bravo', new Position(8, 7), 10, 10, 3, 3, 2, 2, false),
new UnitState('b3', 'bravo', new Position(7, 7), 10, 10, 3, 3, 2, 2, false),
];
$objective = new ObjectiveMarker('objective-1', new Position(5, 4));
$original = new MatchState(
battlefield: $battlefield,
units: $units,
activeTeamId: 'alpha',
objectives: ['objective-1' => $objective],
victoryCondition: VictoryCondition::HoldObjective,
holdRoundsRequired: 3,
);
$array = ScenarioSerializer::matchToArray($original);
self::assertArrayHasKey('objectives', $array);
self::assertSame(
['id' => 'objective-1', 'position' => ['x' => 5, 'y' => 4]],
$array['objectives']['objective-1'] ?? null,
);
$rebuilt = ScenarioSerializer::matchFromArray($array);
self::assertArrayHasKey('objective-1', $rebuilt->objectives);
self::assertSame('objective-1', $rebuilt->objectives['objective-1']->id);
self::assertSame(5, $rebuilt->objectives['objective-1']->position->x);
self::assertSame(4, $rebuilt->objectives['objective-1']->position->y);
self::assertSame(VictoryCondition::HoldObjective, $rebuilt->victoryCondition);
self::assertSame(3, $rebuilt->holdRoundsRequired);
}
} }