From e9d2bc461fa5c02670950d53af415234aa3b9996 Mon Sep 17 00:00:00 2001 From: Wickedness Date: Tue, 7 Jul 2026 15:26:45 +0900 Subject: [PATCH] Expand representative QA report summary --- scripts/qa-representative-battles.mjs | 75 ++++++++++++++++++++++++--- 1 file changed, 69 insertions(+), 6 deletions(-) diff --git a/scripts/qa-representative-battles.mjs b/scripts/qa-representative-battles.mjs index 9ca313b..99817fd 100644 --- a/scripts/qa-representative-battles.mjs +++ b/scripts/qa-representative-battles.mjs @@ -3053,6 +3053,7 @@ function buildQaReport(results, failed) { failureReason: objective.failureReason ?? '' })) ); + const summary = buildQaReportSummary(results, failed, missedObjectives); return { app: 'heros_web', @@ -3064,12 +3065,7 @@ function buildQaReport(results, failed) { cumulativeMode, requestedBattles: [...requestedBattles], battleCount: results.length, - summary: { - victories: results.filter((result) => result.outcome === 'victory').length, - failures: failed.length, - missedObjectiveCount: missedObjectives.length, - battlesWithMissedObjectives: [...new Set(missedObjectives.map((objective) => objective.battleNo))] - }, + summary, missedObjectives, results: results.map((result) => ({ no: result.no, @@ -3093,3 +3089,70 @@ function buildQaReport(results, failed) { })) }; } + +function buildQaReportSummary(results, failed, missedObjectives) { + const turnValues = results.map((result) => result.finalTurn ?? 0).filter((turn) => turn > 0); + const totalTurns = turnValues.reduce((total, turn) => total + turn, 0); + const longestBattle = results.reduce((current, result) => { + if (!current || (result.finalTurn ?? 0) > (current.finalTurn ?? 0)) { + return result; + } + return current; + }, undefined); + const totals = results.reduce( + (summary, result) => { + summary.objectiveCount += result.objectiveCount ?? 0; + summary.objectivesAchieved += result.objectivesAchieved ?? 0; + summary.itemsUsed += result.itemsUsed ?? 0; + summary.supports += result.supports ?? 0; + if (result.campSuppliesUsed) { + summary.campSuppliesUsed.bean += result.campSuppliesUsed.bean ?? 0; + summary.campSuppliesUsed.salve += result.campSuppliesUsed.salve ?? 0; + summary.campSuppliesUsed.wine += result.campSuppliesUsed.wine ?? 0; + } + return summary; + }, + { + objectiveCount: 0, + objectivesAchieved: 0, + itemsUsed: 0, + supports: 0, + campSuppliesUsed: { bean: 0, salve: 0, wine: 0 } + } + ); + const latestCampaign = results.at(-1)?.campaign; + + return { + victories: results.filter((result) => result.outcome === 'victory').length, + failures: failed.length, + missedObjectiveCount: missedObjectives.length, + battlesWithMissedObjectives: [...new Set(missedObjectives.map((objective) => objective.battleNo))], + objectivesAchieved: totals.objectivesAchieved, + objectiveCount: totals.objectiveCount, + turns: { + total: totalTurns, + average: turnValues.length > 0 ? Number((totalTurns / turnValues.length).toFixed(1)) : 0, + min: turnValues.length > 0 ? Math.min(...turnValues) : 0, + max: turnValues.length > 0 ? Math.max(...turnValues) : 0, + longestBattle: longestBattle ? { no: longestBattle.no, id: longestBattle.id, turn: longestBattle.finalTurn ?? 0 } : null + }, + resources: { + itemsUsed: totals.itemsUsed, + supports: totals.supports, + campSuppliesUsed: totals.campSuppliesUsed + }, + latestCampaign: latestCampaign + ? { + battleCount: latestCampaign.battleCount, + gold: latestCampaign.gold, + supplies: latestCampaign.supplies, + rosterCount: latestCampaign.rosterCount, + levelMin: latestCampaign.levelMin, + levelMax: latestCampaign.levelMax, + levelAvg: latestCampaign.levelAvg, + lowHp: latestCampaign.lowHp, + topLevels: latestCampaign.topLevels + } + : null + }; +}