Matchups: implemented matchups
This commit is contained in:
@@ -54,6 +54,14 @@ type Champion = {
|
||||
name: string
|
||||
alias: string
|
||||
}
|
||||
type MatchupData = {
|
||||
championId: number
|
||||
winrate: number
|
||||
games: number
|
||||
championName: string
|
||||
championAlias: string
|
||||
}
|
||||
|
||||
type LaneData = {
|
||||
data: string
|
||||
count: number
|
||||
@@ -63,6 +71,7 @@ type LaneData = {
|
||||
pickrate: number
|
||||
runes: Array<Rune>
|
||||
builds: Builds
|
||||
matchups?: Array<MatchupData>
|
||||
}
|
||||
type ChampionData = {
|
||||
champion: Champion
|
||||
@@ -231,11 +240,17 @@ function handleMatch(match: any, champions: Map<number, ChampionData>) {
|
||||
winningMatches: 0,
|
||||
losingMatches: 0,
|
||||
winrate: 0,
|
||||
pickrate: 0
|
||||
pickrate: 0,
|
||||
matchups: []
|
||||
}
|
||||
champion.lanes.push(lane)
|
||||
} else lane.count += 1
|
||||
|
||||
// Initialize matchups if not present
|
||||
if (!lane.matchups) {
|
||||
lane.matchups = []
|
||||
}
|
||||
|
||||
// Winrate
|
||||
if (participant.win) {
|
||||
champion.winningMatches++
|
||||
@@ -245,6 +260,38 @@ function handleMatch(match: any, champions: Map<number, ChampionData>) {
|
||||
lane.losingMatches++
|
||||
}
|
||||
|
||||
// Track counter matchups - find opponent in same lane
|
||||
const opponentTeam = participant.teamId === 100 ? 200 : 100
|
||||
const opponent = match.info.participants.find(
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(p: any) => p.teamId === opponentTeam && p.teamPosition === participant.teamPosition
|
||||
)
|
||||
|
||||
if (opponent) {
|
||||
const opponentChampionId = opponent.championId
|
||||
|
||||
// Track this matchup for current champion
|
||||
const matchup = lane.matchups.find(c => c.championId === opponentChampionId)
|
||||
if (matchup) {
|
||||
matchup.games += 1
|
||||
if (participant.win) {
|
||||
matchup.winrate = (matchup.winrate * (matchup.games - 1) + 1) / matchup.games
|
||||
} else {
|
||||
matchup.winrate = (matchup.winrate * (matchup.games - 1)) / matchup.games
|
||||
}
|
||||
} else {
|
||||
const opponentChampion = champions.get(opponentChampionId)
|
||||
|
||||
lane.matchups.push({
|
||||
championId: opponentChampionId,
|
||||
winrate: participant.win ? 1 : 0,
|
||||
games: 1,
|
||||
championName: opponentChampion.champion.name,
|
||||
championAlias: opponentChampion.champion.alias
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Runes
|
||||
handleParticipantRunes(participant, lane.runes)
|
||||
|
||||
@@ -326,6 +373,38 @@ async function finalizeChampionStats(champion: ChampionData, totalMatches: numbe
|
||||
lane.pickrate = lane.count / totalMatches
|
||||
}
|
||||
|
||||
// Sort matchups by score (games * winrate) in descending order
|
||||
for (const lane of champion.lanes) {
|
||||
if (lane.matchups && lane.matchups.length > 0) {
|
||||
// Filter out matchups with insufficient games (minimum 5 games)
|
||||
const filteredMatchups = lane.matchups.filter(m => m.games >= 5)
|
||||
|
||||
// Sort by score (games * (winrate - 0.5)^2) descending
|
||||
filteredMatchups.sort((a, b) => {
|
||||
// Handle special case of exactly 50% winrate
|
||||
if (a.winrate === 0.5 && b.winrate === 0.5) {
|
||||
// Both have 50% winrate, sort by games (more games first)
|
||||
return b.games - a.games
|
||||
}
|
||||
if (a.winrate === 0.5 || b.winrate === 0.5) {
|
||||
// a has 50% winrate, b doesn't - b comes first
|
||||
return b.winrate - a.winrate
|
||||
}
|
||||
|
||||
if (a.winrate > 0.5 && b.winrate < 0.5) return -1
|
||||
if (a.winrate < 0.5 && b.winrate > 0.5) return 1
|
||||
if (a.winrate > 0.5) {
|
||||
return b.games * (b.winrate - 0.5) ** 2 - a.games * (a.winrate - 0.5) ** 2
|
||||
} else {
|
||||
return -1 * b.games * (0.5 - b.winrate) ** 2 - -1 * a.games * (0.5 - a.winrate) ** 2
|
||||
}
|
||||
})
|
||||
|
||||
// Limit to top matchups (or keep all if we want comprehensive data)
|
||||
lane.matchups = filteredMatchups
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
name: champion.champion.name,
|
||||
alias: champion.champion.alias.toLowerCase(),
|
||||
|
||||
Reference in New Issue
Block a user