diff --git a/.vscode/settings.json b/.vscode/settings.json index 7c8a532cb..ec47aeb32 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -19,6 +19,7 @@ "betakrieg", "BINORMAL", "Binormals", + "bkni", "BKRL", "BKRTS", "BKRTSMANIFEST", @@ -87,6 +88,7 @@ "loddist", "lods", "lossrate", + "malum", "mantlets", "metallicness", "minitelrose", @@ -136,6 +138,7 @@ "Specularity", "SSAO", "startcase", + "statkit", "statsfull", "steamapps", "Stringifying", diff --git a/docs/technical/bkni.md b/docs/technical/bkni.md index 2f7b6f507..78383ad9a 100644 --- a/docs/technical/bkni.md +++ b/docs/technical/bkni.md @@ -5,9 +5,9 @@ > [!CAUTION] > This is a working draft and is incomplete. Do not implement. -## Why BkPM over WN8? +## Why BkNI over WN8? -BkPM addresses a lot of issues with WN8: +BkNI addresses a lot of issues with WN8: - WN8 incorporates win rate into the metric; a metric like this must be a correlate of win rate, not a dependent - The weights and biases are not dynamic and their formulation is not transparent diff --git a/src/app/tools/player-stats/[id]/page.tsx b/src/app/tools/player-stats/[id]/page.tsx new file mode 100644 index 000000000..6a4478676 --- /dev/null +++ b/src/app/tools/player-stats/[id]/page.tsx @@ -0,0 +1,71 @@ +import { Flex, Heading, Text } from '@radix-ui/themes'; +import PageWrapper from '../../../../components/PageWrapper'; +import { getAccountInfo } from '../../../../core/blitz/getAccountInfo'; +import { getClanAccountInfo } from '../../../../core/blitz/getClanAccountInfo'; +import { idToRegion } from '../../../../core/blitz/idToRegion'; +import getBkniPercentile from '../../../../core/statistics/getBkniPercentile'; +import strings from '../../../../lang/en-US.json'; + +export default async function Page({ params }: { params: { id: string } }) { + const id = parseInt(params.id); + const region = idToRegion(id); + const accountInfo = await getAccountInfo(region, id); + const clanAccountInfo = await getClanAccountInfo(region, id, ['clan']); + const bkniRaw = Math.random() * 2 - 1; + const bkniFraction = Math.random(); + const bkniMetric = Math.round(bkniFraction * 200); + const bkniPercentile = getBkniPercentile(bkniMetric); + + return ( + + + {accountInfo.nickname} + {clanAccountInfo?.clan && ( + [{clanAccountInfo.clan.tag}] + )} + + + + + + + + + + + {bkniMetric} + + + {strings.common.bkni_percentile[bkniPercentile]} + + + + + ); +} diff --git a/src/app/tools/player-stats/page.tsx b/src/app/tools/player-stats/page.tsx new file mode 100644 index 000000000..2ad419791 --- /dev/null +++ b/src/app/tools/player-stats/page.tsx @@ -0,0 +1,110 @@ +'use client'; + +import { ArrowDownIcon, MagnifyingGlassIcon } from '@radix-ui/react-icons'; +import { Button, Card, Flex, Text, TextField } from '@radix-ui/themes'; +import { useRef, useState } from 'react'; +import { Link } from '../../../components/Link'; +import PageWrapper from '../../../components/PageWrapper'; +import { UNLOCALIZED_REGION_NAMES_SHORT } from '../../../constants/regions'; +import searchPlayersAcrossRegions, { + AccountListWithServer, +} from '../../../core/blitz/searchPlayersAcrossRegions'; + +export default function Page() { + const input = useRef(null); + const [showSearch, setShowSearch] = useState(false); + const [searching, setSearching] = useState(false); + const [searchResults, setSearchResults] = useState([]); + + async function search() { + if (!input.current) return; + + setSearchResults(await searchPlayersAcrossRegions(input.current.value, 9)); + setSearching(false); + } + + return ( + + + + Look up a player to get started + + + + { + if (!input.current) return; + + const sanitized = input.current.value.trim(); + + if (sanitized.length > 0) { + setShowSearch(true); + setSearching(true); + search(); + } else { + setShowSearch(false); + } + }} + > + + + + + {showSearch && ( + + {searching && ( + + Searching... + + )} + + {!searching && searchResults.length === 0 && ( + + No players found + + )} + + {!searching && searchResults.length > 0 && ( + + {searchResults.map((player) => ( + + + + ))} + + )} + + )} + + + + ); +} diff --git a/src/constants/tools.tsx b/src/constants/tools.tsx index a5f1cff41..1808df49a 100644 --- a/src/constants/tools.tsx +++ b/src/constants/tools.tsx @@ -31,9 +31,9 @@ export const TOOLS: Tool[] = [ significant: true, }, { - id: 'statistics', - title: 'Statistics', - description: 'Player statistics', + id: 'player-stats', + title: 'Player stats', + description: 'Periodical player statistics', pageDescription: 'Periodical player statistics and tanks played in World of Tanks Blitz', image: '8gJGkKP', diff --git a/src/core/statistics/getBkniPercentile.ts b/src/core/statistics/getBkniPercentile.ts new file mode 100644 index 000000000..1989b2606 --- /dev/null +++ b/src/core/statistics/getBkniPercentile.ts @@ -0,0 +1,46 @@ +/** + * (10) 0 - 10: super malum + * (10) 10 - 20: malum + * (20) 20 - 40: very bad + * (20) 40 - 60: bad + * (20) 60 - 80: below average + * (40) 80 - 120: average + * (20) 120 - 140: above average + * (20) 140 - 160: good + * (20) 160 - 180: very good + * (10) 180 - 190: unicum + * (10) 190 - 200: super unicum + */ + +export enum BkniPercentile { + SuperMalum, + Malum, + VeryBad, + Bad, + BelowAverage, + Average, + AboveAverage, + Good, + VeryGood, + Unicum, + SuperUnicum, +} + +const BKNI_PERCENTILES = [ + { min: 0, percentile: BkniPercentile.SuperMalum }, + { min: 10, percentile: BkniPercentile.Malum }, + { min: 20, percentile: BkniPercentile.VeryBad }, + { min: 40, percentile: BkniPercentile.Bad }, + { min: 60, percentile: BkniPercentile.BelowAverage }, + { min: 80, percentile: BkniPercentile.Average }, + { min: 120, percentile: BkniPercentile.AboveAverage }, + { min: 140, percentile: BkniPercentile.Good }, + { min: 160, percentile: BkniPercentile.VeryGood }, + { min: 180, percentile: BkniPercentile.Unicum }, + { min: 190, percentile: BkniPercentile.SuperUnicum }, +]; + +export default function getBkniPercentile(wn8: number) { + const lastIndex = BKNI_PERCENTILES.findLastIndex(({ min }) => min <= wn8); + return BKNI_PERCENTILES[lastIndex === -1 ? 0 : lastIndex].percentile; +} diff --git a/src/lang/en-US.json b/src/lang/en-US.json index bd88ee6da..5730a1157 100644 --- a/src/lang/en-US.json +++ b/src/lang/en-US.json @@ -13,6 +13,20 @@ "9": "Super unicum" }, + "bkni_percentile": { + "0": "Super malum", + "1": "Malum", + "2": "Very bad", + "3": "Bad", + "4": "Below average", + "5": "Average", + "6": "Above average", + "7": "Good", + "8": "Very good", + "9": "Unicum", + "10": "Super unicum" + }, + "nations": { "ussr": "U.S.S.R.", "germany": "Germany",