Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- let {calculate, Pokemon, Move} = require("@smogon/calc");
- let karateChop = new Move(6, "Karate Chop");
- let wingAttack = new Move(6, "Wing Attack");
- let karateChopCrit = new Move(6, "Karate Chop", {isCrit: true});
- let wingAttackCrit = new Move(6, "Wing Attack", {isCrit: true});
- function randomInt(min, max) {
- return Math.floor(Math.random() * (max - min + 1)) + min;
- }
- function d(x) {
- return Math.floor(x * 4096) / 4096;
- }
- function r(x) {
- return Math.round(x * 4096) / 4096;
- }
- function tryHawluchaCatch(hp, maxHp) {
- const catchRate = 100;
- let x = Math.min(255, d(r(d(r(r(3 * maxHp - 2 * hp) * catchRate) / (3 * maxHp)))));
- let y;
- if (x === 0) {
- y = 0;
- } else {
- y = Math.floor(r(65536 / r(Math.pow(r(255 / x), 3 / 16))));
- }
- let chance = Math.pow(y / 65536, 4);
- return Math.random() <= chance;
- }
- function generateHawlucha(level) {
- let hpIv = randomInt(0, 31);
- let atkIv = randomInt(0, 31);
- let defIv = randomInt(0, 31);
- let nature = randomInt(0, 24);
- let natureName = "Serious";
- switch (nature) {
- case 1: natureName = "Lonely"; break;
- case 2: natureName = "Brave"; break;
- case 3: natureName = "Adamant"; break;
- case 4: natureName = "Naughty"; break;
- case 5: natureName = "Bold"; break;
- case 7: natureName = "Relaxed"; break;
- case 8: natureName = "Impish"; break;
- case 9: natureName = "Lax"; break;
- case 10: natureName = "Timid"; break;
- case 11: natureName = "Hasty"; break;
- case 15: natureName = "Modest"; break;
- case 16: natureName = "Mild"; break;
- case 20: natureName = "Calm"; break;
- case 21: natureName = "Gentle"; break;
- }
- let pokemon = new Pokemon(6, "Hawlucha", {
- ivs: {hp: hpIv, atk: atkIv, def: defIv, spa: 0, spd: 0, spe: 0},
- nature: natureName,
- level: level,
- });
- return {
- maxHp: pokemon.rawStats.hp,
- hp: pokemon.rawStats.hp,
- pokemon: pokemon,
- hasKingsRock: randomInt(0, 19) === 0,
- };
- }
- function simulateEncounter(useAerialAce, hp, atk, def, level) {
- let ballsLeft = 3;
- let hawlucha = generateHawlucha(level);
- let _hawlucha = hawlucha.pokemon;
- // if (hawlucha.hasKingsRock) {
- // console.log("Hawlucha has King's Rock.");
- // }
- let _farfetchd = new Pokemon(6, "Farfetch'd", {
- ivs: {hp: hp, atk: atk, def: def, spa: 0, spd: 0, spe: 0},
- evs: {hp: 2, atk: 4, def: 3, spa: 3, spd: 1, spe: 9},
- nature: "Jolly",
- level: 18,
- });
- let farfetchd = {
- maxHp: _farfetchd.rawStats.hp,
- hp: _farfetchd.rawStats.hp,
- pokemon: _farfetchd,
- }
- for (let turn = 1;; ++turn) {
- // console.log("");
- // console.log("Turn " + turn);
- let hawluchaMove = randomInt(0, 3);
- let damageRolls = null;
- let tryBallThrow = !(useAerialAce && hawlucha.maxHp * 0.8 <= hawlucha.hp && farfetchd.maxHp === farfetchd.hp);
- if (tryBallThrow) {
- let catchSuccess = tryHawluchaCatch(hawlucha.hp, hawlucha.maxHp);
- --ballsLeft;
- if (!catchSuccess) {
- // console.log("Failed catch: " + ballsLeft + " balls left.");
- if (ballsLeft === 0) {
- return {
- success: false,
- turn: turn,
- result: "out of balls",
- };
- }
- } else {
- // console.log("Succeeded catch: " + ballsLeft + " balls left.");
- return {
- success: true,
- turn: turn,
- };
- }
- }
- if (level === 19) {
- switch (hawluchaMove) {
- case 0: { // Karate Chop
- let crit = randomInt(0, 7) === 0;
- damageRolls = calculate(6, _hawlucha, _farfetchd, crit ? karateChopCrit : karateChop).damage;
- break;
- }
- case 1:
- case 3: { // Aerial Ace, Wing Attack
- let crit = randomInt(0, 15) === 0;
- damageRolls = calculate(6, _hawlucha, _farfetchd, crit ? wingAttackCrit : wingAttack).damage;
- break;
- }
- case 2: { // Roost
- // console.log("Hawlucha used Roost.");
- hawlucha.hp = Math.min(hawlucha.maxHp, hawlucha.hp + Math.floor(hawlucha.maxHp / 2));
- break;
- }
- }
- } else {
- switch (hawluchaMove) {
- case 0:
- case 2: { // Aerial Ace, Wing Attack
- let crit = randomInt(0, 15) === 0;
- damageRolls = calculate(6, _hawlucha, _farfetchd, crit ? wingAttackCrit : wingAttack).damage;
- break;
- }
- case 1: { // Roost
- // console.log("Hawlucha used Roost.");
- hawlucha.hp = Math.min(hawlucha.maxHp, hawlucha.hp + Math.floor(hawlucha.maxHp / 2));
- break;
- }
- case 3: // Encore, do nothing
- // console.log("Hawlucha used Encore.");
- break;
- }
- }
- if (damageRolls !== null) {
- let damage = damageRolls[randomInt(0, 15)];
- // console.log("Farfetch'd took " + damage + " damage.");
- farfetchd.hp -= damage;
- // console.log("Farfetch'd has " + farfetchd.hp + " HP.");
- if (farfetchd.hp <= 0) {
- return {
- success: false,
- turn: turn,
- result: "farfetchd fainted",
- };
- }
- }
- if (!tryBallThrow) {
- // console.log("Farfetch'd used Aerial Ace");
- if (hawlucha.hasKingsRock && damageRolls !== null && randomInt(0, 9) === 0) {
- // console.log("Farfetch'd flinched");
- continue;
- }
- let crit = randomInt(0, 15) === 0;
- damageRolls = calculate(6, _farfetchd, _hawlucha, crit ? wingAttackCrit : wingAttack).damage;
- let damage = damageRolls[randomInt(0, 15)];
- hawlucha.hp -= damage;
- // console.log("Hawlucha has " + hawlucha.hp + " left (damage taken: " + damage + ").");
- if (hawlucha.hp <= 0) {
- // Should almost never happen, can happen with lowest Defense & HP & crit and is at best a 5 / 16 range.
- return {
- success: false,
- turn: turn,
- result: "hawlucha fainted",
- };
- }
- }
- }
- }
- for (let level = 19; level <= 20; ++level) {
- for (let iv = 0; iv <=1; ++iv) {
- for (let ae = 0; ae <= 1; ++ae) {
- let successCounter = 0;
- let successTurns = 0;
- let ivs = iv === 0 ? 0 : 31;
- for (let i = 0; i < 1000000; ++i) {
- let result = simulateEncounter(!!ae, ivs, ivs, ivs, level);
- if (result.success) {
- ++successCounter;
- successTurns += result.turn;
- }
- }
- console.log("");
- console.log("Level: " + level);
- console.log("IVs: " + ivs);
- console.log("Aerial Ace: " + ae.toString());
- console.log((successCounter / 10000).toFixed(2));
- console.log("Turns: " + (successTurns / successCounter).toFixed(2));
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment