Tune early battle objective QA

This commit is contained in:
2026-07-04 12:03:35 +09:00
parent 14e83efbeb
commit 05fdc3dff4
3 changed files with 102 additions and 11 deletions

View File

@@ -674,9 +674,17 @@ try {
const stockLine = result.campaign
? ` stock=${result.campaign.supplies.bean}/${result.campaign.supplies.salve}/${result.campaign.supplies.wine} gold=${result.campaign.gold} avgLv=${result.campaign.levelAvg}`
: '';
const missedObjectiveLine = result.objectiveDetails?.some((objective) => !objective.achieved)
? ` missed=${result.objectiveDetails.filter((objective) => !objective.achieved).map((objective) => objective.id).join(',')}`
: '';
console.log(
`QA result ${result.no}: ${result.outcome} turn=${result.finalTurn} allies=${result.alliesAlive} enemies=${result.enemiesAlive} items=${result.itemsUsed} objectives=${result.objectivesAchieved}/${result.objectiveCount}${stockLine}`
`QA result ${result.no}: ${result.outcome} turn=${result.finalTurn} allies=${result.alliesAlive} enemies=${result.enemiesAlive} items=${result.itemsUsed} objectives=${result.objectivesAchieved}/${result.objectiveCount}${missedObjectiveLine}${stockLine}`
);
if (missedObjectiveLine) {
console.log(
`QA missed detail ${result.no}: objectives=${JSON.stringify(result.objectiveDetails)} allies=${result.allyStatus.join(' | ')} enemies=${result.enemyStatus.join(' | ')}`
);
}
if (result.outcome !== 'victory') {
break;
}
@@ -698,7 +706,8 @@ try {
level: result.campaign ? `${result.campaign.levelMin}-${result.campaign.levelMax} (${result.campaign.levelAvg})` : '',
lowHp: result.campaign?.lowHp ?? '',
supports: result.supports,
objectives: `${result.objectivesAchieved}/${result.objectiveCount}`
objectives: `${result.objectivesAchieved}/${result.objectiveCount}`,
missed: result.objectiveDetails?.filter((objective) => !objective.achieved).map((objective) => objective.id).join(',') ?? ''
}))
);
@@ -777,11 +786,17 @@ async function setupBattle(page, battle) {
await page.waitForFunction(
(battleId) => {
const state = window.__HEROS_DEBUG__?.battle();
return state?.scene === 'BattleScene' && state?.battleId === battleId && state?.phase === 'idle' && state?.mapBackgroundReady === true;
return (
state?.scene === 'BattleScene' &&
state?.battleId === battleId &&
(state?.phase === 'deployment' || state?.phase === 'idle') &&
state?.mapBackgroundReady === true
);
},
battle.id,
{ timeout: 90000 }
);
await startDeploymentIfNeeded(page, battle.id);
}
async function setupCumulativeBattle(page, battle, firstBattle) {
@@ -907,14 +922,41 @@ async function setupCumulativeBattle(page, battle, firstBattle) {
await page.waitForFunction(
(battleId) => {
const state = window.__HEROS_DEBUG__?.battle();
return state?.scene === 'BattleScene' && state?.battleId === battleId && state?.phase === 'idle' && state?.mapBackgroundReady === true;
return (
state?.scene === 'BattleScene' &&
state?.battleId === battleId &&
(state?.phase === 'deployment' || state?.phase === 'idle') &&
state?.mapBackgroundReady === true
);
},
battle.id,
{ timeout: 90000 }
);
await startDeploymentIfNeeded(page, battle.id);
return preparation;
}
async function startDeploymentIfNeeded(page, battleId) {
const state = await page.evaluate((expectedBattleId) => {
const battle = window.__HEROS_DEBUG__?.battle();
return battle?.battleId === expectedBattleId ? battle : undefined;
}, battleId);
if (state?.phase !== 'deployment') {
return;
}
await page.mouse.click(1085, 637);
await page.waitForFunction(
(expectedBattleId) => {
const battle = window.__HEROS_DEBUG__?.battle();
return battle?.battleId === expectedBattleId && battle?.phase === 'idle';
},
battleId,
{ timeout: 30000 }
);
}
async function writeCampaignSnapshot(page, snapshotPath) {
const snapshot = await page.evaluate(
({ slotKey, storageKey }) => window.localStorage.getItem(slotKey) ?? window.localStorage.getItem(storageKey),
@@ -988,6 +1030,7 @@ async function playBattleWithoutDebugVictory(page, battle) {
enemyAttacks: 0,
objectivesAchieved: 0,
objectiveCount: 0,
objectiveDetails: [],
protectedStatus: [],
targetStatus: [],
allyStatus: [],
@@ -1399,6 +1442,12 @@ async function playBattleWithoutDebugVictory(page, battle) {
metrics.enemiesAlive = finalState.units.filter((unit) => unit.faction === 'enemy' && unit.hp > 0).length;
metrics.objectiveCount = finalState.objectives.length;
metrics.objectivesAchieved = finalState.objectives.filter((objective) => objective.achieved).length;
metrics.objectiveDetails = finalState.objectives.map((objective) => ({
id: objective.id,
achieved: objective.achieved,
status: objective.status,
detail: objective.detail
}));
metrics.protectedStatus = protectedUnitIds.map((unitId) => {
const unit = finalState.units.find((candidate) => candidate.id === unitId);
return unit ? `${unit.id}:${unit.hp}/${unit.maxHp}@${unit.x},${unit.y}` : `${unitId}:missing`;