플레이 감사를 3단 대시보드와 국가 추이 그래프로 개선한다

This commit is contained in:
2026-09-26 04:36:31 +00:00
parent 2b2edeaeff
commit e35679335c
12 changed files with 1040 additions and 321 deletions
@@ -10,6 +10,7 @@ export type AuditPopulation = 'human' | 'npc' | 'troopNpc';
export interface AuditPopulationSummary {
count: number;
crew: number;
gold: number;
rice: number;
dex: AuditDex;
@@ -44,6 +45,7 @@ export interface AuditNationSnapshot {
const emptyDex = (): AuditDex => ({ dex1: 0, dex2: 0, dex3: 0, dex4: 0, dex5: 0 });
const emptyPopulation = (): AuditPopulationSummary => ({
count: 0,
crew: 0,
gold: 0,
rice: 0,
dex: emptyDex(),
@@ -173,6 +175,7 @@ export const buildAuditSnapshot = (input: {
const population = nations.get(general.nationId)?.populations[projected.population];
if (!population) continue;
population.count++;
population.crew += projected.crew;
population.gold += projected.gold;
population.rice += projected.rice;
for (const key of AUDIT_DEX_KEYS) population.dex[key] += projected.dex[key];
@@ -76,13 +76,15 @@ describe('play audit monthly projection', () => {
it('separates humans, NPCs and troop NPCs and retains empty nations and neutral generals', () => {
const humans = [buildGeneral(1, 1), { ...buildGeneral(2, 1), npcState: 1, gold: 0 }];
humans[0]!.meta.dex1 = 10;
humans[0]!.crew = 3210;
humans[1]!.crew = 790;
const result = buildAuditSnapshot({
nations: [buildNation(0, 0, {}), buildNation(1, 0, {}), buildNation(2, 0, {})],
cities: [buildCity(1, 2)],
generals: [
...humans,
{ ...buildGeneral(3, 1), npcState: 2 },
{ ...buildGeneral(4, 1), npcState: 5 },
{ ...buildGeneral(3, 1), npcState: 2, crew: 1200 },
{ ...buildGeneral(4, 1), npcState: 5, crew: 800 },
buildGeneral(5, 0),
],
settlements: [],
@@ -91,12 +93,13 @@ describe('play audit monthly projection', () => {
const nation = result.nations.find((row) => row.id === 1)!;
expect(nation.populations.human).toMatchObject({
count: 2,
crew: 4000,
gold: 2000,
averageGold: 1000,
averageDex: { dex1: 5 },
});
expect(nation.populations.npc.count).toBe(1);
expect(nation.populations.troopNpc.count).toBe(1);
expect(nation.populations.npc).toMatchObject({ count: 1, crew: 1200 });
expect(nation.populations.troopNpc).toMatchObject({ count: 1, crew: 800 });
expect(result.nations.find((row) => row.id === 2)!.populations.human.averageGold).toBeNull();
expect(result.nations.find((row) => row.id === 0)!.populations.npc.count).toBe(1);
expect(result.cities[0]!.nationId).toBe(2);