fix: round-trip match objectives through ScenarioSerializer

This commit is contained in:
Keith Solomon committed 2026-07-25 22:21:25 -05:00
1 parent a6d93dd1d3
commit a0dcff2c2a
2 files changed
+55 -1

No files matched your search

+18 -1
View File
@@ -130,6 +130,14 @@ final class ScenarioSerializer
$units[] = self::unitToArray($unit);
}
$objectives = [];
foreach ($match->objectives as $id => $objective) {
$objectives[(string) $id] = [
'id' => $objective->id,
'position' => self::positionToArray($objective->position),
];
}
return [
'battlefield' => [
'width' => $match->battlefield->width,
@@ -141,6 +149,7 @@ final class ScenarioSerializer
'round' => $match->round,
'winnerTeamId' => $match->winnerTeamId,
'actionLog' => $match->actionLog,
'objectives' => $objectives,
'victoryCondition' => $match->victoryCondition->value,
'holdRoundsRequired' => $match->holdRoundsRequired,
'objectiveControl' => $match->objectiveControl,
@@ -166,6 +175,14 @@ final class ScenarioSerializer
$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(
battlefield: $battlefield,
units: $units,
@@ -173,7 +190,7 @@ final class ScenarioSerializer
round: (int) $data['round'],
winnerTeamId: $data['winnerTeamId'] ?? null,
actionLog: array_map(static fn (mixed $entry): string => (string) $entry, $data['actionLog'] ?? []),
objectives: [],
objectives: $objectives,
victoryCondition: VictoryCondition::from((string) $data['victoryCondition']),
holdRoundsRequired: (int) $data['holdRoundsRequired'],
objectiveControl: $data['objectiveControl'] ?? [],
@@ -135,4 +135,41 @@ final class ScenarioSerializerTest extends TestCase
// 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);
}
}