grade pokemon for leagues (broken)

This commit is contained in:
Jeff Colombo 2019-01-07 18:02:58 -05:00
parent 06125d165a
commit 2a610fad28
4 changed files with 108 additions and 89 deletions

View File

@ -1,9 +1,25 @@
import * as fs from 'fs'; import * as fs from 'fs';
import * as Pokemon from 'pokemongo-json-pokedex/output/pokemon.json'; import Pokemon from 'pokemongo-json-pokedex/output/pokemon.json';
import { IPokemon, IStats, League } from 'src/ts/models/Pokemon'; import { IPokemon, IStats, League, Grade } from './src/ts/models/Pokemon';
const GREAT_LEAGUE_CP = 1500; interface ICpAndTotalFound {
const ULTRA_LEAGUE_CP = 2500; [ key : number ] : Array<IStats>;
}
interface IStatsDistribution {
great : ICpAndTotalFound;
ultra : ICpAndTotalFound;
}
interface IMaxCpByLeague {
great : number;
ultra : number;
}
const outPath = './dist/db/';
const maxCpByLeague : IMaxCpByLeague = {
great: 1500,
ultra: 2500
};
const cpMultipliers : Array<number> = JSON.parse(fs.readFileSync('src/db/cpMultipliers.json', 'utf8')); const cpMultipliers : Array<number> = JSON.parse(fs.readFileSync('src/db/cpMultipliers.json', 'utf8'));
const getClosestCpMultiplierIndex = (value : number) => { const getClosestCpMultiplierIndex = (value : number) => {
@ -30,65 +46,94 @@ Pokemon.forEach((mon) => {
}, },
}; };
const combinedStatsDistribution : IStatsDistribution = {
great: {},
ultra: {},
};
for (let ivHp = 15; ivHp >= 0; ivHp--) { for (let ivHp = 15; ivHp >= 0; ivHp--) {
for (let ivAtk = 15; ivAtk >= 0; ivAtk--) { for (let ivAtk = 15; ivAtk >= 0; ivAtk--) {
for (let ivDef = 15; ivDef >= 0; ivDef--) { for (let ivDef = 15; ivDef >= 0; ivDef--) {
let pokemonWithIvs : IStats; let pokemonWithIvs : IStats;
const cpMultiplier = (baseAtk + ivAtk) * Math.sqrt(baseDef + ivDef) * Math.sqrt(baseHp + ivHp); const cpMultiplier = (baseAtk + ivAtk) * Math.sqrt(baseDef + ivDef) * Math.sqrt(baseHp + ivHp);
const maxGreatLeagueLevelMultiplierIndex = getClosestCpMultiplierIndex(Math.sqrt((GREAT_LEAGUE_CP * 10) / cpMultiplier)); Object.keys(maxCpByLeague).forEach((key) => {
const maxGreatLeagueLevelMultiplier = cpMultipliers[maxGreatLeagueLevelMultiplierIndex]; const league = key as League;
const maxGreatLeagueCp = ~~((cpMultiplier * Math.pow(maxGreatLeagueLevelMultiplier, 2)) / 10); const maxCp = maxCpByLeague[league];
const maxGreatLeagueLevel = (maxGreatLeagueLevelMultiplierIndex + 2) / 2; const maxLeagueLevelMultiplierIndex = getClosestCpMultiplierIndex(Math.sqrt((maxCp * 10) / cpMultiplier));
const maxLeagueLevelMultiplier = cpMultipliers[maxLeagueLevelMultiplierIndex];
const maxLeagueCp = ~~((cpMultiplier * Math.pow(maxLeagueLevelMultiplier, 2)) / 10);
const maxLeagueLevel = (maxLeagueLevelMultiplierIndex + 2) / 2;
pokemonWithIvs = { pokemonWithIvs = {
cp: maxGreatLeagueCp, cp: maxLeagueCp,
level: maxGreatLeagueLevel, level: maxLeagueLevel,
ivHp: ivHp, ivHp: ivHp,
ivAtk: ivAtk, ivAtk: ivAtk,
ivDef: ivDef, ivDef: ivDef,
hp: ~~((baseHp + ivHp) * maxGreatLeagueLevelMultiplier), hp: ~~((baseHp + ivHp) * maxLeagueLevelMultiplier),
atk: ~~((baseAtk + ivAtk) * maxGreatLeagueLevelMultiplier), atk: ~~((baseAtk + ivAtk) * maxLeagueLevelMultiplier),
def: ~~((baseDef + ivDef) * maxGreatLeagueLevelMultiplier), def: ~~((baseDef + ivDef) * maxLeagueLevelMultiplier),
total: 0 total: 0,
speciesGrade: Grade.F,
metaGrade: Grade.F,
}; };
pokemonWithIvs.total = pokemonWithIvs.hp + pokemonWithIvs.atk + pokemonWithIvs.def; pokemonWithIvs.total = pokemonWithIvs.hp + pokemonWithIvs.atk + pokemonWithIvs.def;
stats.pvp.great.push(pokemonWithIvs); stats.pvp[league].push(pokemonWithIvs);
const maxUltraLeagueLevelMultiplierIndex = getClosestCpMultiplierIndex(Math.sqrt((ULTRA_LEAGUE_CP * 10) / cpMultiplier)); const combinedStats = maxLeagueCp + pokemonWithIvs.total;
const maxUltraLeagueLevelMultiplier = cpMultipliers[maxUltraLeagueLevelMultiplierIndex]; combinedStatsDistribution[league][combinedStats] = combinedStatsDistribution[league][combinedStats] || [];
const maxUltraLeagueCp = ~~((cpMultiplier * Math.pow(maxUltraLeagueLevelMultiplier, 2)) / 10); combinedStatsDistribution[league][combinedStats].push(pokemonWithIvs);
const maxUltraLeagueLevel = (maxUltraLeagueLevelMultiplierIndex + 2) / 2; });
pokemonWithIvs = {
cp: maxUltraLeagueCp,
level: maxUltraLeagueLevel,
ivHp: ivHp,
ivAtk: ivAtk,
ivDef: ivDef,
hp: ~~((baseHp + ivHp) * maxUltraLeagueLevelMultiplier),
atk: ~~((baseAtk + ivAtk) * maxUltraLeagueLevelMultiplier),
def: ~~((baseDef + ivDef) * maxUltraLeagueLevelMultiplier),
total: 0
};
pokemonWithIvs.total = pokemonWithIvs.hp + pokemonWithIvs.atk + pokemonWithIvs.def;
stats.pvp.ultra.push(pokemonWithIvs);
} }
} }
} }
Object.keys(stats.pvp).forEach((league) => { // process the pokemon stats for league-worthiness
const keys = league as League; Object.keys(stats.pvp).forEach((key) => {
stats.pvp[keys].sort((a, b) => { const league = key as League;
if (a.cp === b.cp) { stats.pvp[league].sort((a, b) => {
return a.cp > b.cp ? 0 : 1; if (a.total === b.total) {
}
return a.total > b.total ? 0 : 1; return a.total > b.total ? 0 : 1;
}); }
return a.level > b.level ? 0 : 1;
}); });
fs.writeFile('./dist/db/' + mon.name + '.json', JSON.stringify(stats), (err) => { const orderedCombinedStats = Object.keys(combinedStatsDistribution[league]).map(cpTotal => parseInt(cpTotal)).sort();
const offset = orderedCombinedStats[orderedCombinedStats.length - 1];
const max = orderedCombinedStats[1] - offset; // index 0 is always `Grade.S`
for (let index = orderedCombinedStats.length - 1; index >= 0; index--) {
const combinedStats = orderedCombinedStats[index];
const percent = (combinedStats - offset) / max;
// remove all `Grade.F` stats (to save space in the DB)
if (percent < 0.6) {
delete combinedStatsDistribution[league][combinedStats];
continue;
}
combinedStatsDistribution[league][combinedStats].forEach((pokemonStats) => {
if (index === 0) {
pokemonStats.speciesGrade = Grade.S;
} else {
if (percent >= 0.9) {
pokemonStats.speciesGrade = Grade.A;
} else if (percent >= 0.8) {
pokemonStats.speciesGrade = Grade.B;
} else if (percent >= 0.7) {
pokemonStats.speciesGrade = Grade.C;
} else if (percent >= 0.6) {
pokemonStats.speciesGrade = Grade.D;
}
}
});
}
});
fs.mkdir(outPath, {recursive: true}, () => {
fs.writeFile(outPath + mon.id + '.json', JSON.stringify(stats), (err) => {
if(err) { if(err) {
return console.log(mon.name, err); return console.log(mon.name, err);
} }
console.log(mon.name); console.log(mon.name);
}); });
});
}); });

View File

@ -1,3 +1,12 @@
export enum Grade {
'S',
'A',
'B',
'C',
'D',
'F',
}
export interface IBaseStats { export interface IBaseStats {
baseAttack : number; baseAttack : number;
baseDefense : number; baseDefense : number;
@ -25,4 +34,6 @@ export interface IStats {
atk : number; atk : number;
def : number; def : number;
total : number; total : number;
speciesGrade : Grade;
metaGrade : Grade;
} }

View File

@ -1,39 +0,0 @@
// for use with https://github.com/pokemongo-dev-contrib/pokemongo-json-pokedex
import { IBaseStats } from 'src/ts/models/Pokemon';
declare module "pokemongo-json-pokedex/output/pokemon.json" {
interface IMove {
name : string;
id : string;
legacy : boolean;
}
interface IFamily {
id : string;
name : string;
}
interface IType {
id : string;
name : string;
}
interface IForme {
id : string;
name : string;
}
interface IPokemon {
dex : number;
name : string;
cinematicMoves : Array<IMove>;
quickMoves : Array<IMove>;
family : IFamily;
stats : IBaseStats;
types : Array<IType>;
forms : Array<IForme>
}
const pokemon : Array<IPokemon>;
export = pokemon;
}

View File

@ -4,6 +4,8 @@
"strict": true, "strict": true,
"noUnusedLocals": false, "noUnusedLocals": false,
"allowJs": true, "allowJs": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"outDir": "./dist", "outDir": "./dist",
"sourceMap": true, "sourceMap": true,
"module": "commonjs", "module": "commonjs",
@ -12,7 +14,7 @@
"baseUrl": ".", "baseUrl": ".",
"traceResolution": false, "traceResolution": false,
"paths": { "paths": {
"pokemongo-json-pokedex/output/pokemon.json": ["./src/ts/models/pokemon.json.d.ts"] "src": ["./src"]
}, },
"plugins": [{ "plugins": [{
"name": "tslint-language-service", "name": "tslint-language-service",