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.
Pokemon GO IV Calculator
index.js
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 };
package.json
{ "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://[email protected]/andromedado/pokemon-go-iv-calculator.git" }, "keywords": [ "pokemon", "pokemongo", "ivcalculator", "calculator" ], "author": "Shad Downey <[email protected]>", "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" } }
/support/grader.js
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 };
/support/levelUpData.js
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(); } };
/support/pokedex.js
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]; } };
How to Use Pokemon GO IV Calculator?
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' } */
Important Note
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.