diff --git a/src/worker/core/player/checkJerseyNumberRetirement.ts b/src/worker/core/player/checkJerseyNumberRetirement.ts index 3775df344..3541d24af 100644 --- a/src/worker/core/player/checkJerseyNumberRetirement.ts +++ b/src/worker/core/player/checkJerseyNumberRetirement.ts @@ -1,6 +1,6 @@ import { bySport, isSport } from "../../../common"; -import type { Player, Team } from "../../../common/types"; -import { orderBy } from "../../../common/utils"; +import type { Player, PlayerStats, Team } from "../../../common/types"; +import { maxBy, orderBy } from "../../../common/utils"; import { idb } from "../../db"; import { g, local, logEvent, helpers } from "../../util"; import { getThreshold } from "./madeHof.football"; @@ -37,26 +37,51 @@ export const getValueStatsRow = (ps: any) => { }); }; -export const getMostCommonPosition = (p: Player, tid: number) => { - const positionCounts = new Map(); - for (const pr of p.ratings) { - const ps = p.stats.find(ps => ps.season === pr.season && ps.tid === tid); - if (ps) { - const prevValue = positionCounts.get(pr.pos) ?? 0; - positionCounts.set(pr.pos, prevValue + 1); +// Ideally p should be a Player object, but a processed player object works too if it's in the right format +export const getBestPos = ( + p: { + ratings: { + pos: string; + season: number; + }[]; + stats: PlayerStats[]; + }, + tid: number | undefined, +): string => { + const posBySeason: Record = {}; + + for (const row of p.ratings) { + if (row.pos !== undefined && row.season !== undefined) { + posBySeason[row.season] = row.pos; } } - let maxValue = -Infinity; - let mostCommonPosition: string | undefined; - for (const [pos, value] of positionCounts) { - if (value > maxValue) { - maxValue = value; - mostCommonPosition = pos; + const posByEWA: Record = {}; + for (const ps of p.stats) { + if (ps.tid === tid || tid === undefined) { + const ewa = bySport({ + baseball: ps.war, + basketball: ps.ewa, + football: ps.av, + hockey: ps.ps, + }); + const pos = posBySeason[ps.season]; + if (pos !== undefined) { + //console.log(ps.pos, ps) + if (posByEWA[pos] === undefined) { + posByEWA[pos] = ewa; + } else { + posByEWA[pos] += ewa; + } + } } } - return mostCommonPosition; + return ( + maxBy(Object.entries(posByEWA), ([, ewa]) => ewa)?.[0] ?? + p.ratings.at(-1)?.pos ?? + "?" + ); }; // const posCounts = {}; @@ -74,7 +99,7 @@ export const getScore = (p: Player, tid: number) => { baseball: 40, basketball: 80, football: (() => { - const mostCommonPosition = getMostCommonPosition(p, tid); + const mostCommonPosition = getBestPos(p, tid); let threshold = getThreshold(mostCommonPosition); if (threshold > 80) { diff --git a/src/worker/util/processPlayersHallOfFame.ts b/src/worker/util/processPlayersHallOfFame.ts index 894143d11..e13466f8b 100644 --- a/src/worker/util/processPlayersHallOfFame.ts +++ b/src/worker/util/processPlayersHallOfFame.ts @@ -105,7 +105,7 @@ const processPlayersHallOfFame = < return { ...p, - bestPos: bestPos ?? "", + bestPos: bestPos ?? "?", bestStats, peakOvr, legacyTid, diff --git a/src/worker/views/playerStats.ts b/src/worker/views/playerStats.ts index f5a98afc3..98aa11350 100644 --- a/src/worker/views/playerStats.ts +++ b/src/worker/views/playerStats.ts @@ -7,13 +7,14 @@ import { PLAYER_STATS_TABLES, } from "../../common"; import { idb } from "../db"; -import { g, processPlayersHallOfFame } from "../util"; +import { g } from "../util"; import type { UpdateEvents, ViewInput, PlayerStatType, } from "../../common/types"; import addFirstNameShort from "../util/addFirstNameShort"; +import { getBestPos } from "../core/player/checkJerseyNumberRetirement"; const updatePlayers = async ( inputs: ViewInput<"playerStats">, @@ -210,8 +211,7 @@ const updatePlayers = async ( for (const p of players) { if (inputs.season === "career") { - const { bestPos } = processPlayersHallOfFame([p])[0]; - p.pos = bestPos; + p.pos = getBestPos(p, tid); } else if (Array.isArray(p.ratings) && p.ratings.length > 0) { p.pos = p.ratings.at(-1).pos; } else if (p.ratings.pos !== undefined) { diff --git a/src/worker/views/teamHistory.ts b/src/worker/views/teamHistory.ts index a3728de80..b244e07b1 100644 --- a/src/worker/views/teamHistory.ts +++ b/src/worker/views/teamHistory.ts @@ -6,7 +6,7 @@ import type { TeamSeason, Player, } from "../../common/types"; -import { getMostCommonPosition } from "../core/player/checkJerseyNumberRetirement"; +import { getBestPos } from "../core/player/checkJerseyNumberRetirement"; import { bySport } from "../../common"; import addFirstNameShort from "../util/addFirstNameShort"; import { groupByUnique } from "../../common/utils"; @@ -173,7 +173,7 @@ export const getHistory = async ( "awards", "retirableJerseyNumbers", ], - ratings: ["pos"], + ratings: ["pos", "season"], stats: ["season", "abbrev", ...stats], }); @@ -203,8 +203,9 @@ export const getHistory = async ( ).length; delete p.awards; - // Handle case where ratings don't exist - p.pos = p.ratings.length > 0 ? p.ratings.at(-1).pos : ""; + // undefined as 2nd argument because we have already filtered stats before getting here + p.pos = getBestPos(p, undefined); + delete p.ratings; delete p.stats; } @@ -259,7 +260,7 @@ const updateTeamHistory = async ( if (p) { firstName = p.firstName; lastName = p.lastName; - pos = getMostCommonPosition(p, inputs.tid); + pos = getBestPos(p, inputs.tid); for (const row of p.stats) { if (row.tid === inputs.tid && row.season > lastSeasonWithTeam) { lastSeasonWithTeam = row.season;