refactor/match_collector: refactor platform handling logic

This commit is contained in:
2026-04-23 18:08:17 +02:00
parent a5728a147f
commit 360be86c10
4 changed files with 140 additions and 83 deletions

View File

@@ -1,11 +1,12 @@
type GoldAdvantageTag = 'ahead' | 'behind' | 'even'
import {
PlatformCounts,
REGION_KEYS,
initPlatformCounts,
mergePlatformCounts,
singlePlatformCount
} from './platform'
type PlatformCounts = {
euw: number
eun: number
na: number
kr: number
}
type GoldAdvantageTag = 'ahead' | 'behind' | 'even'
// Item tags that can be derived from purchase patterns
type ItemTag = 'ahead' | 'behind' | 'region_euw' | 'region_eun' | 'region_na' | 'region_kr'
@@ -30,10 +31,6 @@ type ItemTree = {
tags: Array<ItemTag>
}
function initPlatformCounts(): PlatformCounts {
return { euw: 0, eun: 0, na: 0, kr: 0 }
}
function treeInit(): ItemTree {
return {
data: undefined,
@@ -63,10 +60,7 @@ function nodeMerge(itemtree: ItemTree, node: ItemTree) {
child.boughtWhen.behindCount += node.boughtWhen.behindCount
// Merge platform counts
child.platformCount.euw += node.platformCount.euw
child.platformCount.eun += node.platformCount.eun
child.platformCount.na += node.platformCount.na
child.platformCount.kr += node.platformCount.kr
mergePlatformCounts(child.platformCount, node.platformCount)
next = child
break
@@ -99,7 +93,6 @@ function treeMerge(
let current = itemtree
for (const item of items) {
const platformKey = item.platform ? item.platform.toLowerCase() : null
current = nodeMerge(current, {
data: item.itemId,
count: 1,
@@ -110,12 +103,7 @@ function treeMerge(
meanGold: 0
},
children: [],
platformCount: {
euw: platformKey === 'euw1' ? 1 : 0,
eun: platformKey === 'eun1' ? 1 : 0,
na: platformKey === 'na1' ? 1 : 0,
kr: platformKey === 'kr' ? 1 : 0
},
platformCount: item.platform ? singlePlatformCount(item.platform) : initPlatformCounts(),
tags: []
})
}
@@ -174,12 +162,7 @@ function treeClone(tree: ItemTree): ItemTree {
evenCount: tree.boughtWhen.evenCount,
meanGold: tree.boughtWhen.meanGold
},
platformCount: {
euw: tree.platformCount.euw,
eun: tree.platformCount.eun,
na: tree.platformCount.na,
kr: tree.platformCount.kr
},
platformCount: { ...tree.platformCount },
tags: [...tree.tags]
}
}
@@ -192,10 +175,7 @@ function treeMergeTree(t1: ItemTree, t2: ItemTree): ItemTree {
t1.count += t2.count
// Merge platform counts
t1.platformCount.euw += t2.platformCount.euw
t1.platformCount.eun += t2.platformCount.eun
t1.platformCount.na += t2.platformCount.na
t1.platformCount.kr += t2.platformCount.kr
mergePlatformCounts(t1.platformCount, t2.platformCount)
// Merge boughtWhen
t1.boughtWhen.aheadCount += t2.boughtWhen.aheadCount
@@ -302,44 +282,31 @@ function deriveTags(node: ItemTree, expectedRegionDistribution?: PlatformCounts)
}
// Derive region tags by comparing against expected distribution
const totalRegionCount =
node.platformCount.euw + node.platformCount.eun + node.platformCount.na + node.platformCount.kr
const totalRegionCount = REGION_KEYS.reduce((sum, key) => sum + node.platformCount[key], 0)
if (totalRegionCount > 0 && expectedRegionDistribution) {
const totalExpected =
expectedRegionDistribution.euw +
expectedRegionDistribution.eun +
expectedRegionDistribution.na +
expectedRegionDistribution.kr
const totalExpected = REGION_KEYS.reduce((sum, key) => sum + expectedRegionDistribution[key], 0)
if (totalExpected > 0) {
// Calculate expected percentages
const expectedEuwPct = expectedRegionDistribution.euw / totalExpected
const expectedEunPct = expectedRegionDistribution.eun / totalExpected
const expectedNaPct = expectedRegionDistribution.na / totalExpected
const expectedKrPct = expectedRegionDistribution.kr / totalExpected
// Calculate actual percentages for this item
const actualEuwPct = node.platformCount.euw / totalRegionCount
const actualEunPct = node.platformCount.eun / totalRegionCount
const actualNaPct = node.platformCount.na / totalRegionCount
const actualKrPct = node.platformCount.kr / totalRegionCount
// Tag if the item is significantly more popular in a region (>= 1.5x expected rate)
// and has a minimum absolute percentage (>= 10%)
const SIGNIFICANCE_THRESHOLD = 1.5
const MINIMUM_PCT = 0.1
if (actualEuwPct >= expectedEuwPct * SIGNIFICANCE_THRESHOLD && actualEuwPct >= MINIMUM_PCT) {
tags.push('region_euw')
}
if (actualEunPct >= expectedEunPct * SIGNIFICANCE_THRESHOLD && actualEunPct >= MINIMUM_PCT) {
tags.push('region_eun')
}
if (actualNaPct >= expectedNaPct * SIGNIFICANCE_THRESHOLD && actualNaPct >= MINIMUM_PCT) {
tags.push('region_na')
}
if (actualKrPct >= expectedKrPct * SIGNIFICANCE_THRESHOLD && actualKrPct >= MINIMUM_PCT) {
tags.push('region_kr')
// Loop through all regions to derive tags
const regionTags: Array<{ key: keyof PlatformCounts; tag: ItemTag }> = [
{ key: 'euw', tag: 'region_euw' },
{ key: 'eun', tag: 'region_eun' },
{ key: 'na', tag: 'region_na' },
{ key: 'kr', tag: 'region_kr' }
]
for (const { key, tag } of regionTags) {
const expectedPct = expectedRegionDistribution[key] / totalExpected
const actualPct = node.platformCount[key] / totalRegionCount
if (actualPct >= expectedPct * SIGNIFICANCE_THRESHOLD && actualPct >= MINIMUM_PCT) {
tags.push(tag)
}
}
}
}