test: capture legacy battle parity fixtures
This commit is contained in:
@@ -71,6 +71,48 @@ final class ComparisonTracingRNG implements RNG
|
||||
}
|
||||
}
|
||||
|
||||
final class ComparisonTracingRandUtil extends RandUtil
|
||||
{
|
||||
/** @var array<int, array{rngSeq: int, probability: int|float, result: bool}> */
|
||||
public array $boolCalls = [];
|
||||
|
||||
public function __construct(private readonly ComparisonTracingRNG $tracingRng)
|
||||
{
|
||||
parent::__construct($tracingRng);
|
||||
}
|
||||
|
||||
public function nextBool(int|float $prob = 0.5): bool
|
||||
{
|
||||
$rngSeq = count($this->tracingRng->calls);
|
||||
$result = parent::nextBool($prob);
|
||||
$this->boolCalls[] = [
|
||||
'rngSeq' => $rngSeq,
|
||||
'probability' => $prob,
|
||||
'result' => $result,
|
||||
];
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
final class ComparisonGeneral extends General
|
||||
{
|
||||
public function getTurnTime(int $short = self::TURNTIME_FULL_MS): ?string
|
||||
{
|
||||
$formatted = (string)($this->getRaw()['turntime'] ?? '1970-01-01 00:00:00');
|
||||
return match ($short) {
|
||||
self::TURNTIME_FULL_MS => $formatted,
|
||||
self::TURNTIME_FULL => substr($formatted, 0, 19),
|
||||
self::TURNTIME_HMS => substr($formatted, 11, 8),
|
||||
self::TURNTIME_HM => substr($formatted, 11, 5),
|
||||
};
|
||||
}
|
||||
|
||||
public function getTurnTick(): ?int
|
||||
{
|
||||
return (int)($this->getRaw()['turntick'] ?? 0);
|
||||
}
|
||||
}
|
||||
|
||||
function comparisonExtractRankVar(array $raw): Map
|
||||
{
|
||||
$rankVars = new Map();
|
||||
@@ -97,7 +139,7 @@ function comparisonBuildGeneral(
|
||||
}
|
||||
$raw['aux'] = Json::encode($aux);
|
||||
$raw['owner'] = 0;
|
||||
return new General(
|
||||
return new ComparisonGeneral(
|
||||
$raw,
|
||||
comparisonExtractRankVar($raw),
|
||||
null,
|
||||
@@ -135,7 +177,7 @@ function comparisonRunBattle(array $fixture): array
|
||||
GameConst::$scenarioEffect = $scenarioEffect;
|
||||
|
||||
$tracingRng = new ComparisonTracingRNG(new LiteHashDRBG($seed));
|
||||
$warRng = new RandUtil($tracingRng);
|
||||
$warRng = new ComparisonTracingRandUtil($tracingRng);
|
||||
$attacker = new WarUnitGeneral(
|
||||
$warRng,
|
||||
comparisonBuildGeneral($rawAttacker, $rawAttackerCity, $rawAttackerNation, $year, $month),
|
||||
@@ -156,11 +198,17 @@ function comparisonRunBattle(array $fixture): array
|
||||
if (count($defenderList) && extractBattleOrder($city, $attacker) > 0) {
|
||||
$defenderList[] = $city;
|
||||
}
|
||||
$summarizeDefenderOrder = static fn(WarUnit $unit): array => [
|
||||
'id' => $unit instanceof WarUnitGeneral ? $unit->getGeneral()->getID() : 0,
|
||||
'order' => extractBattleOrder($unit, $attacker),
|
||||
];
|
||||
$defenderOrderBeforeSort = array_map($summarizeDefenderOrder, $defenderList);
|
||||
usort(
|
||||
$defenderList,
|
||||
fn(WarUnit $lhs, WarUnit $rhs): int =>
|
||||
-(extractBattleOrder($lhs, $attacker) <=> extractBattleOrder($rhs, $attacker)),
|
||||
);
|
||||
$defenderOrderAfterSort = array_map($summarizeDefenderOrder, $defenderList);
|
||||
|
||||
$iterDefender = new \ArrayIterator($defenderList);
|
||||
$iterDefender->rewind();
|
||||
@@ -213,8 +261,13 @@ function comparisonRunBattle(array $fixture): array
|
||||
'attacker' => buildWarTraceUnitSnapshot($attacker),
|
||||
'city' => buildWarTraceUnitSnapshot($city),
|
||||
'finishedDefenders' => $finishedDefenders,
|
||||
'defenderOrder' => [
|
||||
'before' => $defenderOrderBeforeSort,
|
||||
'after' => $defenderOrderAfterSort,
|
||||
],
|
||||
'events' => $events,
|
||||
'rng' => $tracingRng->calls,
|
||||
'boolRng' => $warRng->boolCalls,
|
||||
'logs' => [
|
||||
'attacker' => $attackerLogs,
|
||||
'defenders' => $defenderLogs,
|
||||
@@ -224,8 +277,27 @@ function comparisonRunBattle(array $fixture): array
|
||||
}
|
||||
|
||||
$fixturePath = $argv[1] ?? null;
|
||||
if ($fixturePath === '--jsonl') {
|
||||
try {
|
||||
while (($line = fgets(STDIN)) !== false) {
|
||||
$line = trim($line);
|
||||
if ($line === '') {
|
||||
continue;
|
||||
}
|
||||
$fixture = json_decode($line, true, flags: JSON_THROW_ON_ERROR);
|
||||
echo json_encode(
|
||||
comparisonRunBattle($fixture),
|
||||
JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRESERVE_ZERO_FRACTION,
|
||||
), PHP_EOL;
|
||||
}
|
||||
exit(0);
|
||||
} catch (\Throwable $throwable) {
|
||||
fwrite(STDERR, $throwable::class . ': ' . $throwable->getMessage() . PHP_EOL);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if ($fixturePath === null || ($fixturePath !== '-' && !is_file($fixturePath))) {
|
||||
fwrite(STDERR, "usage: php compare/battle_trace.php <fixture.json|->\n");
|
||||
fwrite(STDERR, "usage: php compare/battle_trace.php <fixture.json|-|--jsonl>\n");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user