
In this tutorial, you will learn how to make a Pokemon GO IV Calculator in JavaScript. Basically, this tool can be used to get the IVs of the Pokemon. It means that now you can easily find out if your Pokemon can be the best.
You can even improve this Pokemon GO IV Calculator by adding features like PvP Team Builder for planning your PvP teams in all leagues. Also, get familiar with PvP Strategy and why lower IVs can be better.
The full source code of the Pokemon GO IV Calculator is given below. You can easily copy/paste or download it on your computer and try it yourself.
const _ = require('underscore');
const pokedex = require('./support/pokedex');
const levelUpData = require('./support/levelUpData');
const grader = require('./support/grader');
function testHP(hp, iv, levelData, pokemon) {
return hp == parseInt(Math.floor((pokemon.stamina + iv) * levelData.cpScalar), 10);
}
function testCP(cp, attackIV, defenseIV, staminaIV, levelData, pokemon) {
const attackFactor = pokemon.attack + attackIV;
const defenseFactor = Math.pow(pokemon.defense + defenseIV, 0.5)
const staminaFactor = Math.pow((pokemon.stamina + staminaIV), 0.5);
const scalarFactor = Math.pow(levelData.cpScalar, 2);
return cp == parseInt(attackFactor * defenseFactor * staminaFactor * scalarFactor / 10, 10);
}
function determinePerfection(ivs) {
const perfection = (ivs.attackIV + ivs.defenseIV + ivs.staminaIV) / 45
return Math.floor(perfection * 100) / 100;
}
/**
* Evaluate a given pokemon
* @param {string|number} Pokemon Query (e.g. "2" or "Ivysaur")
* @param {number} CP
* @param {number} HP
* @param {number} dustCost Dust cost of upgrading pokemon
* @param {bool} neverUpgraded If you've never powered it up, fewer potential levels
*/function evaluate (pokemonQuery, cp, hp, dustCost, neverUpgraded) {
const pokemon = pokedex.pokemonByName(pokemonQuery) || pokedex.pokemonById(pokemonQuery);
if (!pokemon) {
return {error : `Could not find pokemon: ${pokemonQuery}`};
}
var potentialIVs = determinePossibleIVs(pokemon, cp, hp, dustCost, neverUpgraded);
_.each(potentialIVs, function (possibility) {
possibility.perfection = determinePerfection(possibility);
});
potentialIVs.sort(function (a, b) {
if (a.perfection == b.perfection) {
return 0;
}
return a.perfection > b.perfection ? 1 : -1;
})
var pokeSnapshot = {
grade : grader.grade(_.map(potentialIVs, determinePerfection)),
ivs : potentialIVs
};
return pokeSnapshot;
}
function determinePossibleIVs (pokemon, cp, hp, dust, neverUpgraded) {
var potentialLevels = levelUpData.levelsByDust(dust);
potentialLevels.sort(function (a, b) {
return a.level > b.level ? 1 : -1;//no dupes
});
if (neverUpgraded) {
potentialLevels = _.filter(potentialLevels, function (data) {
return data.level % 2 === 0;
});
}
var staminaIV, attackIV, defenseIV;
var potentialHPIVs = [];
var levelIndex;
var levelData;
for (levelIndex = 0; levelIndex < potentialLevels.length; levelIndex++) {
levelData = potentialLevels[levelIndex];
for (staminaIV = 0; staminaIV <= 15; staminaIV++) {
if (testHP(hp, staminaIV, levelData, pokemon)) {
potentialHPIVs.push({
levelData,
iv : staminaIV
});
}
}
}
var hpIVIndex;
var potentialIVs = [];
for (hpIVIndex = 0; hpIVIndex < potentialHPIVs.length; hpIVIndex++) {
staminaIV = potentialHPIVs[hpIVIndex].iv;
levelData = potentialHPIVs[hpIVIndex].levelData;
for (attackIV = 0; attackIV <= 15; attackIV++) {
for (defenseIV = 0; defenseIV <= 15; defenseIV++) {
if (testCP(cp, attackIV, defenseIV, staminaIV, levelData, pokemon)) {
potentialIVs.push({
attackIV, defenseIV, staminaIV,
level : levelData.level
})
}
}
}
}
return potentialIVs;
}
/**
* Determine possible IVs for a given pokemon
* @param {string|number} Pokemon Query (e.g. "2" or "Ivysaur")
* @param {number} CP
* @param {number} HP
* @param {number} dustCost Dust cost of upgrading pokemon
* @param {bool} neverUpgraded If you've never powered it up, fewer potential levels
*/function possibleIVs (pokemonQuery, cp, hp, dust, neverUpgraded) {
const pokemon = pokedex.pokemonByName(pokemonQuery) || pokedex.pokemonById(pokemonQuery);
if (!pokemon) {
return {error:`Could not find pokemon: ${pokemonQuery}`};
}
const ivs = determinePossibleIVs(pokemon, cp, hp, dustCost, neverUpgraded);
if (!ivs.length) {
return {error: `Could not find any IVs matching given information`};
}
return {ivs};
}
module.exports = {
evaluate,
possibleIVs
};
{
"name": "pokemon-go-iv-calculator",
"version": "0.3.2",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/andromedado/pokemon-go-iv-calculator.git"
},
"keywords": [
"pokemon",
"pokemongo",
"ivcalculator",
"calculator"
],
"author": "Shad Downey <shad.downey@gmail.com>",
"license": "ISC",
"bugs": {
"url": "https://github.com/andromedado/pokemon-go-iv-calculator/issues"
},
"homepage": "https://github.com/andromedado/pokemon-go-iv-calculator#readme",
"dependencies": {
"underscore": "^1.8.3"
}
}const _ = require('underscore');
const letterGrades = [
{ letter : 'A', min : 0.9, mid : 0.93, plus : 0.95 },
{ letter : 'B', min : 0.8, mid : 0.83, plus : 0.87 },
{ letter : 'C', min : 0.7, mid : 0.73, plus : 0.77 },
{ letter : 'D', min : 0.6, mid : 0.62, plus : 0.67 },
{ letter : 'F', min : 0 },
];
function grade(value) {
var letter;
var modifier;
var idx;
var grade;
for (idx = 0; idx < letterGrades.length; idx++) {
grade = letterGrades[idx];
if (value >= grade.min) {
letter = grade.letter;
if (value < grade.mid) {
modifier = '-';
} else if (value >= grade.plus) {
modifier = '+';
}
break;
}
}
const finalGrade = {
letter: letter,
preciseLetter : letter + (modifier || '')
};
return finalGrade;
}
function determineGrade(values) {
if (values && !_.isArray(values)) {
values = [values];
}
if (!values || !values.length) {
return 'Unknown';
}
values.sort();
const minGrade = grade(values[0]);
const maxGrade = grade(values[values.length - 1]);
const averageValue = _.reduce(values, function (memo, val) {return memo + val;}, 0) / values.length;
const averageGrade = grade(averageValue);
if (values.length === 1 || minGrade.preciseLetter === maxGrade.preciseLetter) {
return {
minGrade, maxGrade, averageGrade,
explanation : `${minGrade.preciseLetter} (${Math.floor(averageValue * 1000) / 10}%)`
};
}
if (averageGrade.letter === minGrade.letter && averageGrade.letter === maxGrade.letter) {
return {
minGrade, maxGrade, averageGrade,
explanation : `Solid ${averageGrade.preciseLetter} (${Math.floor(averageValue * 1000) / 10}%)`
};
}
return {
minGrade, maxGrade, averageGrade,
explanation : `Between ${maxGrade.preciseLetter} - ${minGrade.preciseLetter}`
}
}
module.exports = {
grade : determineGrade
};var _ = require('underscore');
var levels = [
{
"level": 1,
"dust": 200,
"candy": 1,
"cpScalar": 0.094
},
{
"level": 2,
"dust": 200,
"candy": 1,
"cpScalar": 0.1351374
},
{
"level": 3,
"dust": 200,
"candy": 1,
"cpScalar": 0.1663979
},
{
"level": 4,
"dust": 200,
"candy": 1,
"cpScalar": 0.1926509
},
{
"level": 5,
"dust": 400,
"candy": 1,
"cpScalar": 0.2157325
},
{
"level": 6,
"dust": 400,
"candy": 1,
"cpScalar": 0.2365727
},
{
"level": 7,
"dust": 400,
"candy": 1,
"cpScalar": 0.2557201
},
{
"level": 8,
"dust": 400,
"candy": 1,
"cpScalar": 0.2735304
},
{
"level": 9,
"dust": 600,
"candy": 1,
"cpScalar": 0.2902499
},
{
"level": 10,
"dust": 600,
"candy": 1,
"cpScalar": 0.3060574
},
{
"level": 11,
"dust": 600,
"candy": 1,
"cpScalar": 0.3210876
},
{
"level": 12,
"dust": 600,
"candy": 1,
"cpScalar": 0.335445
},
{
"level": 13,
"dust": 800,
"candy": 1,
"cpScalar": 0.3492127
},
{
"level": 14,
"dust": 800,
"candy": 1,
"cpScalar": 0.3624578
},
{
"level": 15,
"dust": 800,
"candy": 1,
"cpScalar": 0.3752356
},
{
"level": 16,
"dust": 800,
"candy": 1,
"cpScalar": 0.3875924
},
{
"level": 17,
"dust": 1000,
"candy": 1,
"cpScalar": 0.3995673
},
{
"level": 18,
"dust": 1000,
"candy": 1,
"cpScalar": 0.4111936
},
{
"level": 19,
"dust": 1000,
"candy": 1,
"cpScalar": 0.4225
},
{
"level": 20,
"dust": 1000,
"candy": 1,
"cpScalar": 0.4335117
},
{
"level": 21,
"dust": 1300,
"candy": 2,
"cpScalar": 0.4431076
},
{
"level": 22,
"dust": 1300,
"candy": 2,
"cpScalar": 0.45306
},
{
"level": 23,
"dust": 1300,
"candy": 2,
"cpScalar": 0.4627984
},
{
"level": 24,
"dust": 1300,
"candy": 2,
"cpScalar": 0.4723361
},
{
"level": 25,
"dust": 1600,
"candy": 2,
"cpScalar": 0.481685
},
{
"level": 26,
"dust": 1600,
"candy": 2,
"cpScalar": 0.4908558
},
{
"level": 27,
"dust": 1600,
"candy": 2,
"cpScalar": 0.4998584
},
{
"level": 28,
"dust": 1600,
"candy": 2,
"cpScalar": 0.5087018
},
{
"level": 29,
"dust": 1900,
"candy": 2,
"cpScalar": 0.517394
},
{
"level": 30,
"dust": 1900,
"candy": 2,
"cpScalar": 0.5259425
},
{
"level": 31,
"dust": 1900,
"candy": 2,
"cpScalar": 0.5343543
},
{
"level": 32,
"dust": 1900,
"candy": 2,
"cpScalar": 0.5426358
},
{
"level": 33,
"dust": 2200,
"candy": 2,
"cpScalar": 0.5507927
},
{
"level": 34,
"dust": 2200,
"candy": 2,
"cpScalar": 0.5588306
},
{
"level": 35,
"dust": 2200,
"candy": 2,
"cpScalar": 0.5667545
},
{
"level": 36,
"dust": 2200,
"candy": 2,
"cpScalar": 0.5745692
},
{
"level": 37,
"dust": 2500,
"candy": 2,
"cpScalar": 0.5822789
},
{
"level": 38,
"dust": 2500,
"candy": 2,
"cpScalar": 0.5898879
},
{
"level": 39,
"dust": 2500,
"candy": 2,
"cpScalar": 0.5974
},
{
"level": 40,
"dust": 2500,
"candy": 2,
"cpScalar": 0.6048188
},
{
"level": 41,
"dust": 3000,
"candy": 3,
"cpScalar": 0.6121573
},
{
"level": 42,
"dust": 3000,
"candy": 3,
"cpScalar": 0.6194041
},
{
"level": 43,
"dust": 3000,
"candy": 3,
"cpScalar": 0.6265671
},
{
"level": 44,
"dust": 3000,
"candy": 3,
"cpScalar": 0.6336492
},
{
"level": 45,
"dust": 3500,
"candy": 3,
"cpScalar": 0.640653
},
{
"level": 46,
"dust": 3500,
"candy": 3,
"cpScalar": 0.647581
},
{
"level": 47,
"dust": 3500,
"candy": 3,
"cpScalar": 0.6544356
},
{
"level": 48,
"dust": 3500,
"candy": 3,
"cpScalar": 0.6612193
},
{
"level": 49,
"dust": 4000,
"candy": 3,
"cpScalar": 0.667934
},
{
"level": 50,
"dust": 4000,
"candy": 3,
"cpScalar": 0.6745819
},
{
"level": 51,
"dust": 4000,
"candy": 4,
"cpScalar": 0.6811649
},
{
"level": 52,
"dust": 4000,
"candy": 4,
"cpScalar": 0.6876849
},
{
"level": 53,
"dust": 4500,
"candy": 4,
"cpScalar": 0.6941437
},
{
"level": 54,
"dust": 4500,
"candy": 4,
"cpScalar": 0.7005429
},
{
"level": 55,
"dust": 4500,
"candy": 4,
"cpScalar": 0.7068842
},
{
"level": 56,
"dust": 4500,
"candy": 4,
"cpScalar": 0.7131691
},
{
"level": 57,
"dust": 5000,
"candy": 4,
"cpScalar": 0.7193991
},
{
"level": 58,
"dust": 5000,
"candy": 4,
"cpScalar": 0.7255756
},
{
"level": 59,
"dust": 5000,
"candy": 4,
"cpScalar": 0.7317
},
{
"level": 60,
"dust": 5000,
"candy": 4,
"cpScalar": 0.734741
},
{
"level": 61,
"dust": 6000,
"candy": 6,
"cpScalar": 0.7377695
},
{
"level": 62,
"dust": 6000,
"candy": 6,
"cpScalar": 0.7407856
},
{
"level": 63,
"dust": 6000,
"candy": 6,
"cpScalar": 0.7437894
},
{
"level": 64,
"dust": 6000,
"candy": 6,
"cpScalar": 0.7467812
},
{
"level": 65,
"dust": 7000,
"candy": 8,
"cpScalar": 0.749761
},
{
"level": 66,
"dust": 7000,
"candy": 8,
"cpScalar": 0.7527291
},
{
"level": 67,
"dust": 7000,
"candy": 8,
"cpScalar": 0.7556855
},
{
"level": 68,
"dust": 7000,
"candy": 8,
"cpScalar": 0.7586304
},
{
"level": 69,
"dust": 8000,
"candy": 10,
"cpScalar": 0.7615638
},
{
"level": 70,
"dust": 8000,
"candy": 10,
"cpScalar": 0.7644861
},
{
"level": 71,
"dust": 8000,
"candy": 10,
"cpScalar": 0.7673972
},
{
"level": 72,
"dust": 8000,
"candy": 10,
"cpScalar": 0.7702973
},
{
"level": 73,
"dust": 9000,
"candy": 12,
"cpScalar": 0.7731865
},
{
"level": 74,
"dust": 9000,
"candy": 12,
"cpScalar": 0.776065
},
{
"level": 75,
"dust": 9000,
"candy": 12,
"cpScalar": 0.7789328
},
{
"level": 76,
"dust": 9000,
"candy": 12,
"cpScalar": 0.7817901
},
{
"level": 77,
"dust": 10000,
"candy": 15,
"cpScalar": 0.784637
},
{
"level": 78,
"dust": 10000,
"candy": 15,
"cpScalar": 0.7874736
},
{
"level": 79,
"dust": 10000,
"candy": 15,
"cpScalar": 0.7903
},
{
"level": 80,
"dust": 10000,
"candy": 15,
"cpScalar": 0.7931164
}
];
var lookup = {
byLevel : {},
byDust : {},
byCandy : {}
};
_.each(levels, function (data) {
lookup.byLevel[data.level] = data;
lookup.byDust[data.dust] = lookup.byDust[data.dust] || [];
lookup.byDust[data.dust].push(data);
lookup.byCandy[data.candy] = lookup.byCandy[data.candy] || [];
lookup.byCandy[data.candy].push(data);
});
module.exports = {
allLevels : function () {
return levels.slice();
},
levelsByDust : function (dust) {
dust = parseInt(dust, 10);
return lookup.byDust[dust].slice();
},
levelsByCandy : function (candy) {
candy = parseInt(candy, 10);
return lookup.byCandy[candy].slice();
}
};var _ = require('underscore');
var pokemon = [
{
"id": 1,
"name": "Bulbasaur",
"stamina": 90,
"attack": 126,
"defense": 126
},
{
"id": 2,
"name": "Ivysaur",
"stamina": 120,
"attack": 156,
"defense": 158
},
{
"id": 3,
"name": "Venusaur",
"stamina": 160,
"attack": 198,
"defense": 200
},
{
"id": 4,
"name": "Charmander",
"stamina": 78,
"attack": 128,
"defense": 108
},
{
"id": 5,
"name": "Charmeleon",
"stamina": 116,
"attack": 160,
"defense": 140
},
{
"id": 6,
"name": "Charizard",
"stamina": 156,
"attack": 212,
"defense": 182
},
{
"id": 7,
"name": "Squirtle",
"stamina": 88,
"attack": 112,
"defense": 142
},
{
"id": 8,
"name": "Wartortle",
"stamina": 118,
"attack": 144,
"defense": 176
},
{
"id": 9,
"name": "Blastoise",
"stamina": 158,
"attack": 186,
"defense": 222
},
{
"id": 10,
"name": "Caterpie",
"stamina": 90,
"attack": 62,
"defense": 66
},
{
"id": 11,
"name": "Metapod",
"stamina": 100,
"attack": 56,
"defense": 86
},
{
"id": 12,
"name": "Butterfree",
"stamina": 120,
"attack": 144,
"defense": 144
},
{
"id": 13,
"name": "Weedle",
"stamina": 80,
"attack": 68,
"defense": 64
},
{
"id": 14,
"name": "Kakuna",
"stamina": 90,
"attack": 62,
"defense": 82
},
{
"id": 15,
"name": "Beedrill",
"stamina": 130,
"attack": 144,
"defense": 130
},
{
"id": 16,
"name": "Pidgey",
"stamina": 80,
"attack": 94,
"defense": 90
},
{
"id": 17,
"name": "Pidgeotto",
"stamina": 126,
"attack": 126,
"defense": 122
},
{
"id": 18,
"name": "Pidgeot",
"stamina": 166,
"attack": 170,
"defense": 166
},
{
"id": 19,
"name": "Rattata",
"stamina": 60,
"attack": 92,
"defense": 86
},
{
"id": 20,
"name": "Raticate",
"stamina": 110,
"attack": 146,
"defense": 150
},
{
"id": 21,
"name": "Spearow",
"stamina": 80,
"attack": 102,
"defense": 78
},
{
"id": 22,
"name": "Fearow",
"stamina": 130,
"attack": 168,
"defense": 146
},
{
"id": 23,
"name": "Ekans",
"stamina": 70,
"attack": 112,
"defense": 112
},
{
"id": 24,
"name": "Arbok",
"stamina": 120,
"attack": 166,
"defense": 166
},
{
"id": 25,
"name": "Pikachu",
"stamina": 70,
"attack": 124,
"defense": 108
},
{
"id": 26,
"name": "Raichu",
"stamina": 120,
"attack": 200,
"defense": 154
},
{
"id": 27,
"name": "Sandshrew",
"stamina": 100,
"attack": 90,
"defense": 114
},
{
"id": 28,
"name": "Sandslash",
"stamina": 150,
"attack": 150,
"defense": 172
},
{
"id": 29,
"name": "Nidoran_female",
"stamina": 110,
"attack": 100,
"defense": 104
},
{
"id": 30,
"name": "Nidorina",
"stamina": 140,
"attack": 132,
"defense": 136
},
{
"id": 31,
"name": "Nidoqueen",
"stamina": 180,
"attack": 184,
"defense": 190
},
{
"id": 32,
"name": "Nidoran_male",
"stamina": 92,
"attack": 110,
"defense": 94
},
{
"id": 33,
"name": "Nidorino",
"stamina": 122,
"attack": 142,
"defense": 128
},
{
"id": 34,
"name": "Nidoking",
"stamina": 162,
"attack": 204,
"defense": 170
},
{
"id": 35,
"name": "Clefairy",
"stamina": 140,
"attack": 116,
"defense": 124
},
{
"id": 36,
"name": "Clefable",
"stamina": 190,
"attack": 178,
"defense": 178
},
{
"id": 37,
"name": "Vulpix",
"stamina": 76,
"attack": 106,
"defense": 118
},
{
"id": 38,
"name": "Ninetales",
"stamina": 146,
"attack": 176,
"defense": 194
},
{
"id": 39,
"name": "Jigglypuff",
"stamina": 230,
"attack": 98,
"defense": 54
},
{
"id": 40,
"name": "Wigglytuff",
"stamina": 280,
"attack": 168,
"defense": 108
},
{
"id": 41,
"name": "Zubat",
"stamina": 80,
"attack": 88,
"defense": 90
},
{
"id": 42,
"name": "Golbat",
"stamina": 150,
"attack": 164,
"defense": 164
},
{
"id": 43,
"name": "Oddish",
"stamina": 90,
"attack": 134,
"defense": 130
},
{
"id": 44,
"name": "Gloom",
"stamina": 120,
"attack": 162,
"defense": 158
},
{
"id": 45,
"name": "Vileplume",
"stamina": 150,
"attack": 202,
"defense": 190
},
{
"id": 46,
"name": "Paras",
"stamina": 70,
"attack": 122,
"defense": 120
},
{
"id": 47,
"name": "Parasect",
"stamina": 120,
"attack": 162,
"defense": 170
},
{
"id": 48,
"name": "Venonat",
"stamina": 120,
"attack": 108,
"defense": 118
},
{
"id": 49,
"name": "Venomoth",
"stamina": 140,
"attack": 172,
"defense": 154
},
{
"id": 50,
"name": "Diglett",
"stamina": 20,
"attack": 108,
"defense": 86
},
{
"id": 51,
"name": "Dugtrio",
"stamina": 70,
"attack": 148,
"defense": 140
},
{
"id": 52,
"name": "Meowth",
"stamina": 80,
"attack": 104,
"defense": 94
},
{
"id": 53,
"name": "Persian",
"stamina": 130,
"attack": 156,
"defense": 146
},
{
"id": 54,
"name": "Psyduck",
"stamina": 100,
"attack": 132,
"defense": 112
},
{
"id": 55,
"name": "Golduck",
"stamina": 160,
"attack": 194,
"defense": 176
},
{
"id": 56,
"name": "Mankey",
"stamina": 80,
"attack": 122,
"defense": 96
},
{
"id": 57,
"name": "Primeape",
"stamina": 130,
"attack": 178,
"defense": 150
},
{
"id": 58,
"name": "Growlithe",
"stamina": 110,
"attack": 156,
"defense": 110
},
{
"id": 59,
"name": "Arcanine",
"stamina": 180,
"attack": 230,
"defense": 180
},
{
"id": 60,
"name": "Poliwag",
"stamina": 80,
"attack": 108,
"defense": 98
},
{
"id": 61,
"name": "Poliwhirl",
"stamina": 130,
"attack": 132,
"defense": 132
},
{
"id": 62,
"name": "Poliwrath",
"stamina": 180,
"attack": 180,
"defense": 202
},
{
"id": 63,
"name": "Abra",
"stamina": 50,
"attack": 110,
"defense": 76
},
{
"id": 64,
"name": "Kadabra",
"stamina": 80,
"attack": 150,
"defense": 112
},
{
"id": 65,
"name": "Alakazam",
"stamina": 110,
"attack": 186,
"defense": 152
},
{
"id": 66,
"name": "Machop",
"stamina": 140,
"attack": 118,
"defense": 96
},
{
"id": 67,
"name": "Machoke",
"stamina": 160,
"attack": 154,
"defense": 144
},
{
"id": 68,
"name": "Machamp",
"stamina": 180,
"attack": 198,
"defense": 180
},
{
"id": 69,
"name": "Bellsprout",
"stamina": 100,
"attack": 158,
"defense": 78
},
{
"id": 70,
"name": "Weepinbell",
"stamina": 130,
"attack": 190,
"defense": 110
},
{
"id": 71,
"name": "Victreebel",
"stamina": 160,
"attack": 222,
"defense": 152
},
{
"id": 72,
"name": "Tentacool",
"stamina": 80,
"attack": 106,
"defense": 136
},
{
"id": 73,
"name": "Tentacruel",
"stamina": 160,
"attack": 170,
"defense": 196
},
{
"id": 74,
"name": "Geodude",
"stamina": 80,
"attack": 106,
"defense": 118
},
{
"id": 75,
"name": "Graveler",
"stamina": 110,
"attack": 142,
"defense": 156
},
{
"id": 76,
"name": "Golem",
"stamina": 160,
"attack": 176,
"defense": 198
},
{
"id": 77,
"name": "Ponyta",
"stamina": 100,
"attack": 168,
"defense": 138
},
{
"id": 78,
"name": "Rapidash",
"stamina": 130,
"attack": 200,
"defense": 170
},
{
"id": 79,
"name": "Slowpoke",
"stamina": 180,
"attack": 110,
"defense": 110
},
{
"id": 80,
"name": "Slowbro",
"stamina": 190,
"attack": 184,
"defense": 198
},
{
"id": 81,
"name": "Magnemite",
"stamina": 50,
"attack": 128,
"defense": 138
},
{
"id": 82,
"name": "Magneton",
"stamina": 100,
"attack": 186,
"defense": 180
},
{
"id": 83,
"name": "Farfetchd",
"stamina": 104,
"attack": 138,
"defense": 132
},
{
"id": 84,
"name": "Doduo",
"stamina": 70,
"attack": 126,
"defense": 96
},
{
"id": 85,
"name": "Dodrio",
"stamina": 120,
"attack": 182,
"defense": 150
},
{
"id": 86,
"name": "Seel",
"stamina": 130,
"attack": 104,
"defense": 138
},
{
"id": 87,
"name": "Dewgong",
"stamina": 180,
"attack": 156,
"defense": 192
},
{
"id": 88,
"name": "Grimer",
"stamina": 160,
"attack": 124,
"defense": 110
},
{
"id": 89,
"name": "Muk",
"stamina": 210,
"attack": 180,
"defense": 188
},
{
"id": 90,
"name": "Shellder",
"stamina": 60,
"attack": 120,
"defense": 112
},
{
"id": 91,
"name": "Cloyster",
"stamina": 100,
"attack": 196,
"defense": 196
},
{
"id": 92,
"name": "Gastly",
"stamina": 60,
"attack": 136,
"defense": 82
},
{
"id": 93,
"name": "Haunter",
"stamina": 90,
"attack": 172,
"defense": 118
},
{
"id": 94,
"name": "Gengar",
"stamina": 120,
"attack": 204,
"defense": 156
},
{
"id": 95,
"name": "Onix",
"stamina": 70,
"attack": 90,
"defense": 186
},
{
"id": 96,
"name": "Drowzee",
"stamina": 120,
"attack": 104,
"defense": 140
},
{
"id": 97,
"name": "Hypno",
"stamina": 170,
"attack": 162,
"defense": 196
},
{
"id": 98,
"name": "Krabby",
"stamina": 60,
"attack": 116,
"defense": 110
},
{
"id": 99,
"name": "Kingler",
"stamina": 110,
"attack": 178,
"defense": 168
},
{
"id": 100,
"name": "Voltorb",
"stamina": 80,
"attack": 102,
"defense": 124
},
{
"id": 101,
"name": "Electrode",
"stamina": 120,
"attack": 150,
"defense": 174
},
{
"id": 102,
"name": "Exeggcute",
"stamina": 120,
"attack": 110,
"defense": 132
},
{
"id": 103,
"name": "Exeggutor",
"stamina": 190,
"attack": 232,
"defense": 164
},
{
"id": 104,
"name": "Cubone",
"stamina": 100,
"attack": 102,
"defense": 150
},
{
"id": 105,
"name": "Marowak",
"stamina": 120,
"attack": 140,
"defense": 202
},
{
"id": 106,
"name": "Hitmonlee",
"stamina": 100,
"attack": 148,
"defense": 172
},
{
"id": 107,
"name": "Hitmonchan",
"stamina": 100,
"attack": 138,
"defense": 204
},
{
"id": 108,
"name": "Lickitung",
"stamina": 180,
"attack": 126,
"defense": 160
},
{
"id": 109,
"name": "Koffing",
"stamina": 80,
"attack": 136,
"defense": 142
},
{
"id": 110,
"name": "Weezing",
"stamina": 130,
"attack": 190,
"defense": 198
},
{
"id": 111,
"name": "Rhyhorn",
"stamina": 160,
"attack": 110,
"defense": 116
},
{
"id": 112,
"name": "Rhydon",
"stamina": 210,
"attack": 166,
"defense": 160
},
{
"id": 113,
"name": "Chansey",
"stamina": 500,
"attack": 40,
"defense": 60
},
{
"id": 114,
"name": "Tangela",
"stamina": 130,
"attack": 164,
"defense": 152
},
{
"id": 115,
"name": "Kangaskhan",
"stamina": 210,
"attack": 142,
"defense": 178
},
{
"id": 116,
"name": "Horsea",
"stamina": 60,
"attack": 122,
"defense": 100
},
{
"id": 117,
"name": "Seadra",
"stamina": 110,
"attack": 176,
"defense": 150
},
{
"id": 118,
"name": "Goldeen",
"stamina": 90,
"attack": 112,
"defense": 126
},
{
"id": 119,
"name": "Seaking",
"stamina": 160,
"attack": 172,
"defense": 160
},
{
"id": 120,
"name": "Staryu",
"stamina": 60,
"attack": 130,
"defense": 128
},
{
"id": 121,
"name": "Starmie",
"stamina": 120,
"attack": 194,
"defense": 192
},
{
"id": 122,
"name": "Mr_mime",
"stamina": 80,
"attack": 154,
"defense": 196
},
{
"id": 123,
"name": "Scyther",
"stamina": 140,
"attack": 176,
"defense": 180
},
{
"id": 124,
"name": "Jynx",
"stamina": 130,
"attack": 172,
"defense": 134
},
{
"id": 125,
"name": "Electabuzz",
"stamina": 130,
"attack": 198,
"defense": 160
},
{
"id": 126,
"name": "Magmar",
"stamina": 130,
"attack": 214,
"defense": 158
},
{
"id": 127,
"name": "Pinsir",
"stamina": 130,
"attack": 184,
"defense": 186
},
{
"id": 128,
"name": "Tauros",
"stamina": 150,
"attack": 148,
"defense": 184
},
{
"id": 129,
"name": "Magikarp",
"stamina": 40,
"attack": 42,
"defense": 84
},
{
"id": 130,
"name": "Gyarados",
"stamina": 190,
"attack": 192,
"defense": 196
},
{
"id": 131,
"name": "Lapras",
"stamina": 260,
"attack": 186,
"defense": 190
},
{
"id": 132,
"name": "Ditto",
"stamina": 96,
"attack": 110,
"defense": 110
},
{
"id": 133,
"name": "Eevee",
"stamina": 110,
"attack": 114,
"defense": 128
},
{
"id": 134,
"name": "Vaporeon",
"stamina": 260,
"attack": 186,
"defense": 168
},
{
"id": 135,
"name": "Jolteon",
"stamina": 130,
"attack": 192,
"defense": 174
},
{
"id": 136,
"name": "Flareon",
"stamina": 130,
"attack": 238,
"defense": 178
},
{
"id": 137,
"name": "Porygon",
"stamina": 130,
"attack": 156,
"defense": 158
},
{
"id": 138,
"name": "Omanyte",
"stamina": 70,
"attack": 132,
"defense": 160
},
{
"id": 139,
"name": "Omastar",
"stamina": 140,
"attack": 180,
"defense": 202
},
{
"id": 140,
"name": "Kabuto",
"stamina": 60,
"attack": 148,
"defense": 142
},
{
"id": 141,
"name": "Kabutops",
"stamina": 120,
"attack": 190,
"defense": 190
},
{
"id": 142,
"name": "Aerodactyl",
"stamina": 160,
"attack": 182,
"defense": 162
},
{
"id": 143,
"name": "Snorlax",
"stamina": 320,
"attack": 180,
"defense": 180
},
{
"id": 144,
"name": "Articuno",
"stamina": 180,
"attack": 198,
"defense": 242
},
{
"id": 145,
"name": "Zapdos",
"stamina": 180,
"attack": 232,
"defense": 194
},
{
"id": 146,
"name": "Moltres",
"stamina": 180,
"attack": 242,
"defense": 194
},
{
"id": 147,
"name": "Dratini",
"stamina": 82,
"attack": 128,
"defense": 110
},
{
"id": 148,
"name": "Dragonair",
"stamina": 122,
"attack": 170,
"defense": 152
},
{
"id": 149,
"name": "Dragonite",
"stamina": 182,
"attack": 250,
"defense": 212
},
{
"id": 150,
"name": "Mewtwo",
"stamina": 212,
"attack": 284,
"defense": 202
},
{
"id": 151,
"name": "Mew",
"stamina": 200,
"attack": 220,
"defense": 220
}
];
const boundsOfInterest = [0, 100, 200];
function boundKeyForValue(value) {
var key;
var idx;
var boundValue;
var upperValue;
for (idx = 0; idx < boundsOfInterest.length; idx++) {
boundValue = boundsOfInterest[idx];
upperValue = boundsOfInterest[idx + 1];
if (!upperValue) {
//We've reached the end
return boundValue + '+';
}
if (value >= boundValue && value < upperValue) {
return boundValue + '-' + upperValue;
}
}
return key;
}
const boundKeys = _.map(boundsOfInterest, boundKeyForValue);
var lookup = {
byId : {},
byName : {},
byStamina : {},
byAttack : {},
byDefense : {},
};
[
'byStamina',
'byAttack',
'byDefense'
].forEach(function (name) {
var dict = {
all : {}
};
boundKeys.forEach(function (key) {
dict[key] = [];
});
lookup[name] = dict;
});
_.each(pokemon, function (pokeData) {
lookup.byId[pokeData.id] = pokeData;
lookup.byName[pokeData.name.toLowerCase()] = pokeData;
lookup.byStamina.all[pokeData.stamina] = lookup.byStamina.all[pokeData.stamina] || [];
lookup.byStamina.all[pokeData.stamina].push(pokeData);
lookup.byStamina[boundKeyForValue(pokeData.stamina)].push(pokeData);
lookup.byAttack.all[pokeData.attack] = lookup.byAttack.all[pokeData.attack] || [];
lookup.byAttack.all[pokeData.attack].push(pokeData);
lookup.byAttack[boundKeyForValue(pokeData.attack)].push(pokeData);
lookup.byDefense.all[pokeData.defense] = lookup.byDefense.all[pokeData.defense] || [];
lookup.byDefense.all[pokeData.defense].push(pokeData);
lookup.byDefense[boundKeyForValue(pokeData.defense)].push(pokeData);
});
module.exports = {
pokemonByName : function (name) {
return lookup.byName[(name + '').toLowerCase()];
},
pokemonById : function (id) {
var pokeId = parseInt(id, 10);
return lookup.byId[pokeId];
}
};const ivCalculator = require('pokemon-go-iv-calculator');
//Ivysaur with CP 608, HP of 69, and dust-upgrade-cost of 1600
const result = ivCalculator.evaluate('Ivysaur', 608, 59, 1600);
/**
Gives:
{ grade:
{ minGrade: { letter: 'F', preciseLetter: 'F' },
maxGrade: { letter: 'D', preciseLetter: 'D' },
averageGrade: { letter: 'F', preciseLetter: 'F' },
explanation: 'Between D - F' },
ivs:
[ { attackIV: 15,
defenseIV: 11,
staminaIV: 0,
level: 27,
perfection: 0.57 },
{ attackIV: 14,
defenseIV: 13,
staminaIV: 0,
level: 27,
perfection: 0.6 },
{ attackIV: 13,
defenseIV: 15,
staminaIV: 0,
level: 27,
perfection: 0.62 } ] }
*/
const niceTry = ivCalculator.evaluate('ivysaurus', 608, 59, 1600)
/**
Gives
{ error: 'Could not find pokemon: ivysaurus' }
*/Pokemon can be any case (upper/lower/mixed), OR you can use pokedex id (e.g. Ivysaur == 2)
There’s an optional fifth argument: Boolean : neverUpgraded. If you’ve never upgraded the pokemon, pass true. This reduces the possible levels the pokemon could be at.
Google Chrome has dominated web browsing for over a decade with 71.77% global market share.…
Perplexity just made its AI-powered browser, Comet, completely free for everyone on October 2, 2025.…
You've probably heard about ChatGPT Atlas, OpenAI's new AI-powered browser that launched on October 21,…
Perplexity Comet became free for everyone on October 2, 2025, bringing research-focused AI browsing to…
ChatGPT Atlas launched on October 21, 2025, but it's only available on macOS. If you're…
Two AI browsers just entered the ring in October 2025, and they're both fighting for…