• Check out the relaunch of our general collection, with classic designs and new ones by our very own Pissog!

Project Break My Team! 1v1 (Cycle 20 at Post #551)

Not sure if this counts under Rule 5 but posting anyways

Pumpkaboo-Super @ Choice Scarf
Ability: Pickup
EVs: 232 HP / 248 SpD
Calm Nature
IVs: 0 Atk / 18 Spe
- Trick
- Disable
- Synthesis


Ye this doesn't work cuz encore lulz

124+ SpA Primarina Moonblast vs. 232 HP / 248+ SpD Pumpkaboo-Super: 157-186 (49.5 - 58.6%) -- 98.8% chance to 2HKO

Very likely to activate sitrus, from where u disable and spam synthesis

252+ SpA Venusaur Sludge Bomb vs. 232 HP / 248+ SpD Pumpkaboo-Super: 139-165 (43.8 - 52%) -- 11.7% chance to 2HKO

88.3% to activate custap t3, where pumpkaboo just spams synthesis. Not sure if poison chance invalidates it but it's funny enough that I wanted to post it anyways

Take ur wildest guess who wins in the registeel matchup. Betcha won't get it. That's right! Iiiit's...

Clefairy! (FUUUU-)
 
Last edited:
Not sure if this counts under Rule 5 but posting anyways

Pumpkaboo-Super @ Choice Scarf
Ability: Pickup
EVs: 232 HP / 248 SpD
Calm Nature
IVs: 0 Atk
- Trick
- Disable
- Synthesis

124+ SpA Primarina Moonblast vs. 232 HP / 248+ SpD Pumpkaboo-Super: 157-186 (49.5 - 58.6%) -- 98.8% chance to 2HKO

Very likely to activate sitrus, from where u disable and spam synthesis

252+ SpA Venusaur Sludge Bomb vs. 232 HP / 248+ SpD Pumpkaboo-Super: 139-165 (43.8 - 52%) -- 11.7% chance to 2HKO

88.3% to activate custap t3, where pumpkaboo just spams synthesis. Not sure if poison chance invalidates it but it's funny enough that I wanted to post it anyways

Take ur wildest guess who wins in the registeel matchup. Betcha won't get it. That's right! Iiiit's...

Clefairy! (FUUUU-)
Encore
 
:garchomp: Garchomp @ Choice Band
Level: 100
Careful Nature
Ability: Rough Skin
EVs: 188 HP / 56 Atk / 252 SpD
- Earthquake

banded garchomp woohoo

56 Atk Choice Band Garchomp Earthquake vs. 200 HP / 176 Def Primarina: 220-259 (62.6 - 73.7%) -- guaranteed 2HKO
124+ SpA Primarina Moonblast vs. 188 HP / 252+ SpD Garchomp: 242-288 (59.9 - 71.2%) -- guaranteed 2HKO
56 Atk Choice Band Garchomp Earthquake vs. 68 HP / 92 Def Venusaur: 222-262 (69.8 - 82.3%) -- guaranteed 2HKO
252 SpA Venusaur Earth Power vs. 188 HP / 252+ SpD Garchomp: 66-78 (16.3 - 19.3%) -- possible 6HKO
252 SpA Overgrow Venusaur Frenzy Plant vs. 188 HP / 252+ SpD Garchomp: 246-289 (60.8 - 71.5%) -- guaranteed 2HKO
56 Atk Choice Band Garchomp Earthquake vs. 248 HP / 48 Def Registeel: 288-342 (79.3 - 94.2%) -- guaranteed 2HKO after Leftovers recovery
 
Last edited:
:garchomp: Garchomp @ Choice Band
Level: 100
Careful Nature
Ability: Rough Skin
EVs: 188 HP / 252 SpD
- Earthquake

banded garchomp woohoo

0 Atk Choice Band Garchomp Earthquake vs. 200 HP / 176 Def Primarina: 210-247 (59.8 - 70.3%) -- guaranteed 2HKO
124+ SpA Primarina Moonblast vs. 188 HP / 252+ SpD Garchomp: 242-288 (59.9 - 71.2%) -- guaranteed 2HKO
0 Atk Choice Band Garchomp Earthquake vs. 68 HP / 92 Def Venusaur: 211-250 (66.3 - 78.6%) -- guaranteed 2HKO
252 SpA Venusaur Earth Power vs. 188 HP / 252+ SpD Garchomp: 66-78 (16.3 - 19.3%) -- possible 6HKO
252 SpA Overgrow Venusaur Frenzy Plant vs. 188 HP / 252+ SpD Garchomp: 246-289 (60.8 - 71.5%) -- guaranteed 2HKO
0 Atk Choice Band Garchomp Earthquake vs. 248 HP / 48 Def Registeel: 276-326 (76 - 89.8%) -- guaranteed 2HKO after Leftovers recovery
You need some attack investment, this has only an 85.2% to 2HKO Primarina after Sitrus Berry.
 
Haunter @ Life Orb
Ability: Levitate
EVs: 184 SpA / 8 SpD
Modest Nature
IVs: 0 Atk
- Sludge Wave
- Taunt
- Endure

184+ SpA Life Orb Haunter Sludge Wave vs. 200 HP / 0 SpD Primarina: 343-406 (97.7 - 115.6%) -- 87.5% chance to OHKO

184+ SpA Life Orb Haunter Sludge Wave vs. 68 HP / 0 SpD Venusaur: 192-227 (60.3 - 71.3%) -- guaranteed 2HKO

252+ SpA Venusaur Frenzy Plant vs. 0 HP / 8 SpD Haunter: 178-210 (77 - 90.9%) -- guaranteed 2HKO
(I checked, only 12.5% chance to kill after lorb)

Gee I wonder, sherlock
 
:gengar:
Gengar @ Air Balloon
Ability: Cursed Body
EVs: 32 HP / 132 SpA / 252 SpD
Modest Nature
IVs: 0 Atk
- Uproar
- Sludge Wave
- Trick
- Nasty Plot

132+ SpA Gengar Sludge Wave vs. 68 HP / 0 SpD Venusaur: 157-186 (49.3 - 58.4%) -- 98% chance to 2HKO
252+ SpA Venusaur Sludge Bomb vs. 32 HP / 252 SpD Gengar: 31-37 (11.5 - 13.7%) -- possible 8HKO
252+ SpA Venusaur Earth Power vs. 32 HP / 252 SpD Gengar: 170-202 (63.1 - 75%) -- guaranteed 2HKO
After the first Sludge Wave, there's a 94% chance that Sitrus Berry will bring Primarina out of Torrent range.

132+ SpA Gengar Sludge Wave vs. 200 HP / 0 SpD Primarina: 276-326 (78.6 - 92.8%) -- guaranteed 2HKO
124+ SpA Primarina Hydro Cannon vs. 32 HP / 252 SpD Gengar: 228-268 (84.7 - 99.6%) -- guaranteed 2HKO
Use Trick to remove the leftovers.

+6 132+ SpA Gengar Uproar vs. +6 248 HP / 212+ SpD Registeel: 27-32 (7.4 - 8.8%) -- possibly the worst move ever
 
:pmd/Kyurem:
Kyurem @ Never-Melt Ice
Ability: Pressure
EVs: 252 HP / 204 SpA / 48 Spe
Modest Nature
IVs: 0 Atk
- Freeze-Dry
- Imprison
- Body Press
- Rest

204+ SpA Never-Melt Ice Kyurem Freeze-Dry vs. 68 HP / 0 SpD Venusaur: 290-344 (91.1 - 108.1%) -- 50% chance to OHKO

252+ SpA Venusaur Sludge Bomb vs. 252 HP / 0 SpD Kyurem: 147-174 (32.3 - 38.3%) -- 97.2% chance to 3HKO
252+ SpA Overgrow Venusaur Frenzy Plant vs. 252 HP / 0 SpD Kyurem: 183-216 (40.3 - 47.5%) -- guaranteed 3HKO

204+ SpA Never-Melt Ice Kyurem Freeze-Dry vs. 200 HP / 0 SpD Primarina: 258-306 (73.5 - 87.1%) -- guaranteed 2HKO (2 shots even after sitrus, barring moonhax, if you're wondering)

124+ SpA Primarina Moonblast vs. 252 HP / 0 SpD Kyurem: 332-392 (73.1 - 86.3%) -- guaranteed 2HKO (With the speed, icy wind doesn't slow him down enough)

Imprison turn one = auto win, regi ends up struggling to death unless you freeze it for an eternity
 
:pmd/kartana:
Getting lazy (Kartana) @ Choice Band
Ability: Beast Boost
EVs: 252 Atk
Adamant Nature
- Sacred Sword
- Psycho Cut
- Leaf Blade

252+ Atk Choice Band Kartana Psycho Cut vs. 68 HP / 92 Def Venusaur: 340-400 (106.9 - 125.7%) -- guaranteed OHKO

252+ SpA Venusaur Earth Power vs. 0 HP / 0 SpD Kartana: 216-255 (83.3 - 98.4%) -- guaranteed 2HKO

252+ Atk Choice Band Kartana Leaf Blade vs. 200 HP / 174 Def Primarina: 648-764 (184.6 - 217.6%) -- guaranteed OHKO

252+ Atk Choice Band Kartana Sacred Sword vs. 248 HP / 48 Def Registeel: 282-334 (77.6 - 92%) -- guaranteed 2HKO after Leftovers recovery

48 Def Registeel Body Press vs. 0 HP / 0 Def Kartana: 136-160 (52.5 - 61.7%) -- guaranteed 2HKO
(The only "interesting" one cause it ignores id)
 
Wow this cycle still hasn't ended, lemme make a break now that I'm back

Heatran @ Mental Herb
Level: 100
Modest Nature
Ability: Flash Fire
EVs: 216 HP / 4 Def / 56 SpA / 76 SpD / 124 Spe
- Sunny Day
- Solar Beam
- Eruption

Primarina has 438 HP including Sitrus Berry recovery
124+ SpA Primarina Icy Wind vs. 216 HP / 76 SpD Heatran: 13-15 (3.4 - 3.9%) -- possibly the worst move ever
124+ SpA Primarina Moonblast vs. 216 HP / 76 SpD Heatran: 33-39 (8.7 - 10.3%) -- possibly the worst move ever
124+ SpA Primarina Hydro Cannon vs. 216 HP / 76 SpD Heatran in Sun: 210-248 (55.7 - 65.7%) -- guaranteed 2HKO

56+ SpA Heatran Solar Beam vs. 200 HP / 0 SpD Primarina: 220-260 (62.6 - 74%) -- guaranteed 2HKO

Sooo I made a code in Python to find out my losing chance to Icy Wind + Moonblast + Hydro Cannon if they all hit is 929017 / 28311552, i.e. 0.03281406120017727

The tupleRollToDict function was bugged and did not account for duplicate damage values. FIXED
Losing chance 0.03278825817074515 -> 0.03281406120017727
Still it is better than 12.5%
Make code cleaner and easier to use. Added Gen 1 crit mechanics.
Slight optimization of pow()
'''
Prerequisites for StackableRolls:
'''

def hcf(*args):
"""
Calculate the highest common factor (HCF) of one or more integers.
Supports both individual integers and lists of integers.

Parameters:
*args: One or more integers or a single list of integers.

Returns:
int: The highest common factor of the provided integers.
If no arguments are provided, returns None.
If one argument is provided, returns its absolute value.
"""
# Handle case where a single list is passed
if len(args) == 1 and isinstance(args[0], (list, tuple)):
args = args[0] # Extract the list/tuple

if len(args) == 0:
return None # Return None for no input
elif len(args) == 1:
return abs(int(args[0])) # Return the absolute value for a single input
else:
result = abs(int(args[0]))
for num in args[1:]:
num = int(num)
while num:
result, num = num, result % num # Update result using Euclidean algorithm
if result == 1: # Early exit if HCF is 1
return 1
return result

def lcm(*args):
"""
Calculate the least common multiple (LCM) of one or more integers.
Supports both individual integers and lists of integers.

Parameters:
*args: One or more integers or a single list of integers.

Returns:
int: The least common multiple of the provided integers.
If no arguments are provided, returns None.
If one argument is provided, returns its absolute value.
"""
# Handle case where a single list is passed
if len(args) == 1 and isinstance(args[0], (list, tuple)):
args = args[0] # Extract the list/tuple

if len(args) == 0:
return None # Return None for no input
elif len(args) == 1:
return abs(int(args[0])) # Return the absolute value for a single input
else:
result = abs(int(args[0]))
for num in args[1:]:
num = int(num)
result = abs(result * num) // hcf(result, num) # LCM formula
return result

'''
Definition of the StackableRolls class:

Class attributes:
- roll: A dictionary storing all the possible values and their frequency
- fracCount: Stores the sum of frequency of all possible values

Class methods:
1. Constructors
- __init__(rollDict): Initializes an object of class StackableRolls with roll = rollDict

2. Mutators
- integer(): Sets values of the roll dictionary and fracCount to integers
- simplify(): Simplifies the roll values if possible
- scale_up(factor): Multiply the roll values by factor

3. Accessors
- smallerThan(value)
- largerThan(value)
- add(anotherRoll)
- multiply(anotherRoll)
- pow(pow_count)
'''

class StackableRolls:
def __init__(self, rollDict):
self.roll = {k: int(v) for k, v in rollDict.items()}
self.fracCount = sum(self.roll.values())

def sort(self, inplace=False):
"""
Sorts the roll dictionary by keys in ascending order.

Parameters:
- inplace (bool): If True, sort the current object. If False, return a new sorted StackableRolls object.

Returns:
- StackableRolls or None: A new StackableRolls object if inplace is False; otherwise, modifies the current object.
"""
sorted_roll = dict(sorted(self.roll.items(), key=lambda item: item[0]))

if inplace:
self.roll = sorted_roll
return self
else:
return StackableRolls(sorted_roll)

def integer(self, inplace=False):
if (inplace):
self.roll = {k: int(v) for k, v in self.roll.items()}
self.fracCount = int(self.fracCount)
return self
else:
new_roll_dict = {k: int(v) for k, v in self.roll.items()}
return StackableRolls(new_roll_dict)

def change_sign_of_keys(self, inplace=False):
if (inplace):
self.roll = {key * -1: value for key, value in self.roll.items()}
return self
else:
new_roll_dict = {key * -1: value for key, value in self.roll.items()}
return StackableRolls(new_roll_dict)


def change_sign_of_values(self, inplace=False):
if (inplace):
self.roll = {key: value * -1 for key, value in self.roll.items()}
return self
else:
new_roll_dict = {key: value * -1 for key, value in self.roll.items()}
return StackableRolls(new_roll_dict)

def simplify(self, setInteger=False):
'''
Simplifies the frequencies of the rolls by dividing them by their highest common factor (HCF).
'''
if (setInteger):
self.integer(inplace=True)
# Calculate the highest common factor (HCF) of the frequencies
div_factor = self.fracCount
for freq in self.roll.values():
div_factor = hcf(div_factor, freq)
if div_factor == 1:
return # Early exit if HCF is 1

# Divide each frequency by the HCF
for value in self.roll:
self.roll[value] //= div_factor # Use in-place division for clarity

# Update the total fractional count
self.fracCount //= div_factor

if (setInteger):
self.integer(inplace=True)


def scale_up(self, factor, setInteger=False):
'''
Only changes frequency
'''
# Too obvious
for x in self.roll:
self.roll[x] *= factor
self.fracCount *= factor
if (setInteger):
self.integer(inplace=True)
return

def dropZeros(self, setInteger=False):
'''
Removes entries with zero frequency
'''
# Create dictionary with correct values
resultDict = {}
for x in self.roll:
if (x != 0):
resultDict[x] = self.roll[x]

# Wrapup
result = StackableRolls(resultDict)
if (setInteger):
result.integer(inplace=True)
return result

def smallerThan(self, value, includeEqual=False, setInteger=False):
'''
Picks and keeps values smaller than a threshold
'''
# See above
resultDict = {}
for x in self.roll:
if (x < value):
resultDict[x] = self.roll[x]
elif ((x == value) and includeEqual):
resultDict[x] = self.roll[x]

result = StackableRolls(resultDict)
if (setInteger):
result.integer(inplace=True)
return result

def largerThan(self, value, includeEqual=False, setInteger=False):
'''
Picks and keeps values larger than a threshold
'''
# See above
resultDict = {}
for x in self.roll:
if (x > value):
resultDict[x] = self.roll[x]
elif ((x == value) and includeEqual):
resultDict[x] = self.roll[x]

result = StackableRolls(resultDict)
if (setInteger):
result.integer(inplace=True)
return result

def add(self, anotherRoll, setInteger=False):
"""
Combines two StackableRolls objects representing simultaneous events.

Parameters:
- anotherRoll (StackableRolls): The StackableRolls object to be added to the current instance.

Returns:
- StackableRolls: A new StackableRolls object that contains the combined frequencies of values
from both rolls. If either roll has a frequency count of zero, the other roll
is returned unchanged.

Notes:
- This method ensures that all values present in either of the original rolls are included in
the resulting roll. Frequencies for matching values are summed.

Example:
>>> roll1 = StackableRolls({10: 3, 20: 2})
>>> roll2 = StackableRolls({10: 1, 30: 4})
>>> combined_roll = roll1.add(roll2)
>>> print(combined_roll)
# Output: StackableRolls({10: 4, 20: 2, 30: 4})
"""

# Check for empty rolls
if self.fracCount == 0:
return anotherRoll
elif anotherRoll.fracCount == 0:
return self

# Create a dictionary with the combined frequencies
resultDict = self.roll.copy()
for value, freq in anotherRoll.roll.items():
resultDict[value] = resultDict.get(value, 0) + freq

# Wrap up the result
result = StackableRolls(resultDict)
if (setInteger):
result.integer(inplace=True)
return result

def multiply(self, anotherRoll, to_simplify=True, setInteger=False):
"""
Combines two StackableRolls objects representing sequential events.

Parameters:
- anotherRoll (StackableRolls): The StackableRolls object to be multiplied with the current instance.
- to_simplify (bool): Optional. If True (default), the resulting roll will be simplified by reducing
frequencies to their lowest terms.

Returns:
- StackableRolls: A new StackableRolls object that represents the sum of all possible outcomes
from rolling the values of both rolls sequentially.

Notes:
- The resulting roll includes values calculated by adding each value from the first roll
to each value from the second roll, weighted by their respective frequencies.
If to_simplify is True, the resulting roll will be simplified after multiplication.

Example:
>>> roll1 = StackableRolls({1: 2, 2: 3}) # 2 occurrences of 1, 3 occurrences of 2
>>> roll2 = StackableRolls({1: 1, 3: 4}) # 1 occurrence of 1, 4 occurrences of 3
>>> product_roll = roll1.multiply(roll2)
>>> print(product_roll)
# Output: StackableRolls({2: 2, 3: 3, 4: 8, 5: 12})
# Explanation:
# - 2 occurs 2 times (2 occurence of 1 from roll1 * 1 occurence of 1 from roll2)
# - 3 occurs 3 times (3 occurence of 2 from roll1 * 1 occurence of 1 from roll2)
# - 4 occurs 8 times (2 occurence of 1 from roll1 * 4 occurence of 3 from roll2)
# - 5 occurs 12 times (3 occurence of 2 from roll1 * 4 occurence of 3 from roll2)
"""
# Initialize
if (to_simplify):
self.simplify()
anotherRoll.simplify()
resultDict = {}

# Creating dictionary with correct values
self_items = list(self.roll.items())
another_items = list(anotherRoll.roll.items())

for (i, count_i) in self_items:
for (j, count_j) in another_items:
if i+j in resultDict:
resultDict[i+j] += count_i * count_j
else:
resultDict[i+j] = count_i * count_j

# Wrapup
result = StackableRolls(resultDict)
if (setInteger):
result.integer(inplace=True)
if (to_simplify):
result.simplify()
result.roll = dict(sorted(result.roll.items()))
return result

def pow(self, pow_count, acceptFloat=False, setInteger=False):
'''
Raises the current StackableRolls object to the power of pow_count by
multiplying it by itself pow_count times.

Parameters:
- pow_count (int or float): The exponent to which the current StackableRolls
object should be raised. Must be a non-negative integer if acceptFloat
is False.
- acceptFloat (bool): Optional. If True, allows pow_count to be a float.
If False (default), pow_count must be an integer.
- setInteger (bool): Optional. If True, ensures that the frequencies in
the resulting StackableRolls object are integers.

Returns:
- StackableRolls: A new StackableRolls object that represents the current
object raised to the power of pow_count. If pow_count is negative or
not a valid value, returns None.

Notes:
- The method uses exponentiation by squaring to efficiently compute the
power, which reduces the number of multiplications required.
- If pow_count is a float and acceptFloat is False, the method will
return None without performing any calculations.
- If pow_count is less than 0, the method will also return None.

Example:
>>> roll = StackableRolls({1: 2, 2: 3})
>>> result = roll.pow(3)
>>> print(result)
# Output: StackableRolls object representing the roll raised to the power of 3
'''
if (isinstance(pow_count, float) and (pow_count != float(int(pow_count))) and not acceptFloat):
return
if (pow_count < 0):
return
result = StackableRolls({0: 1}) # The default roll
temp = self
while (pow_count != 0):
if (pow_count % 2 == 1):
result = result.multiply(temp)
pow_count -= 1
temp = temp.multiply(temp)
pow_count /= 2
if (setInteger):
result.integer(inplace=True)
return result

def weightedAdd(StackableRollsList, weightingList, setInteger=False):
"""
Combines a list of StackableRolls objects with corresponding weights.

Parameters:
- StackableRollsList (list): A list of StackableRolls objects to be combined.
- weightingList (list): A list of weights corresponding to each StackableRolls object.
- setInteger (bool): If True, ensures that the frequencies in the result are integers.

Returns:
- StackableRolls: A new StackableRolls object that represents the weighted sum of the input rolls.
"""
# Check for equal length of lists
if len(StackableRollsList) != len(weightingList):
raise ValueError("StackableRollsList and weightingList must be the same length.")

# Simplify the weightingList by dividing by the HCF
weighting_hcf = hcf(weightingList)
weightingList = [w // weighting_hcf for w in weightingList]

# Scale StackableRolls according to their fractional counts and weights
fracCountList = [roll.fracCount for roll in StackableRollsList]
fracCountlcm = lcm(fracCountList)

for roll, weight in zip(StackableRollsList, weightingList):
scale_factor = fracCountlcm // roll.fracCount
roll.scale_up(scale_factor)
roll.scale_up(weight)

# Combine the adjusted rolls
result = StackableRollsList[0]
for roll in StackableRollsList[1:]:
result = result.add(roll)

if setInteger:
result.integer()
result.simplify()
return result

'''
Functions required to plug the StackableRolls class to needs for damage calculation and win chance evaluation
'''
def PokemonCritChanceOddsList(critStage, gen=9, baseSpeed=100):
"""
Calculate the odds of landing a critical hit based on the crit stage, Pokémon generation,
and base speed.

Parameters:
critStage (int): The critical hit stage, which affects the chance of landing a critical hit.
- Values 0-7 represent different crit stages.
- -1 indicates no crit chance (results in always missing).
gen (int): The generation of the Pokémon game. Default is 9.
- Generation 1 has unique crit calculations.
baseSpeed (int): The base speed of the Pokémon, used for critical hit calculations in Generation 1 only.
Default is 100, but can be ignored for other generations.

Returns:
list: A list containing two values:
- The chance of not landing a critical hit.
- The chance of landing a critical hit.

If the generation is invalid (less than 1 or greater than 9), returns None.
If critStage is invalid (less than -1 or greater than 7), returns [0, 1].

Notes:
- For Generation 1:
- Crit stages 4-7 correspond to battle stadium crit chances.
- Crit stages 2-3 and 6-7 correspond to focus energy crit chances.
- If critStage is not found or if an invalid generation is provided, the function returns None.
- Avoid using generation 0, as it will not work.

Example:
>>> PokemonCritChanceOddsList(3, gen=1, baseSpeed=120)
[x, y] # where x is the non-crit chance and y is the crit chance
"""

# Check for invalid generation
if gen < 1 or gen > 9:
return None

if gen == 1:
base_odds = 256
crit_chance = 0

# Calculate critical hit chance based on critStage
if critStage == 0:
crit_chance = (baseSpeed // 2)
elif critStage == 1:
crit_chance = 8 * (baseSpeed // 2)
elif critStage == 2:
crit_chance = (baseSpeed // 8)
elif critStage == 3:
crit_chance = 4 * (baseSpeed // 4)
elif critStage == 4:
crit_chance = (baseSpeed + 76) // 4
elif critStage == 5:
crit_chance = 8 * ((baseSpeed + 76) // 4)
elif critStage == 6:
crit_chance = ((baseSpeed + 236) // 4) * 2
elif critStage == 7:
crit_chance = 255
elif critStage == -1:
crit_chance = 0

# Cap crit_chance at 255
crit_chance = min(crit_chance, 255)

return [base_odds - crit_chance, crit_chance]

# Data for crit chances and base odds based on generation
gen_data = {
2: ([17, 1, 1, 85, 1], [256, 8, 4, 256, 2]),
(3, 5): ([1, 1, 1, 1, 1], [16, 8, 4, 3, 2]),
6: ([1, 1, 1, 1, 1], [16, 8, 2, 1, 1]),
(7, 9): ([1, 1, 1, 1, 1], [24, 8, 2, 1, 1])
}

# Determine crit chances and base odds based on generation
for key, value in gen_data.items():
if isinstance(key, tuple):
# Check if generation falls within the tuple range
if key[0] <= gen <= key[1]:
crit_chances, base_odds = value
break
elif key == gen:
# Exact match for generation
crit_chances, base_odds = value
break
else:
# Return if generation data is not found
return None

# Calculate the chances of not landing a critical hit
not_crit_chances = [b - c for b, c in zip(base_odds, crit_chances)]
critStage = int(critStage)

# Handle special case for critStage -1 (always crit)
if critStage == -1:
return [1, 0]

# Validate critStage range
if critStage < 0 or critStage > 4:
return [0, 1]

# Return the calculated chances for the given crit stage
return [not_crit_chances[critStage], crit_chances[critStage]]

def tupleRollToDict(tupleString, bracket='auto'):
"""
Convert a string representation of a tuple (or list) of integers into a dictionary
where each integer is a key and its count as the value.

Parameters:
tupleString (str): A string representation of a tuple or list (e.g., "(1, 2, 3)").
It can also be a string formatted with different types of brackets.
bracket (str): Optional. Specifies the type of brackets used in the input string.
Options are '(', '[', '{', or 'auto' to determine based on the first character.
Default is 'auto'.

Returns:
dict: A dictionary where each unique integer in the input string is a key,
and the value is the count of occurrences of that integer.
Returns an empty dictionary if the input string is improperly formatted
or does not start and end with matching brackets.

Example:
>>> tupleRollToDict("(1, 2, 2, 3)")
{1: 1, 2: 2, 3: 1}

>>> tupleRollToDict("[4, 4, 5]")
{4: 2, 5: 1}

>>> tupleRollToDict("{6, 7, 6}")
{6: 2, 7: 1}

>>> tupleRollToDict("Invalid input")
{}
"""
tupleString = tupleString.strip() # Strip leading and trailing whitespace
brackets = {'(': '()', '[': '[]', '{': '{}',
'auto': '()'}.get(tupleString[0], '()') if bracket == 'auto' else bracket

# Validation
if not (tupleString.startswith(brackets[0]) and tupleString.endswith(brackets[1])):
return {}

# Extracting and converting to dictionary
entryList = tupleString.lstrip(brackets[0]).rstrip(brackets[1]).split(",")
count_dict = {}
for x in entryList:
num = int(x.strip())
count_dict[num] = count_dict.get(num, 0) + 1 # Increment count

return count_dict

def addAccuracyToRoll(roll, ufrac, lfrac=100):
"""
Adjusts a roll to account for accuracy, combining it with a miss chance.

Parameters:
- roll (StackableRolls): The initial roll object representing the damage values.
- ufrac (int): The upper part of the accuracy fraction (numerator).
Represents the chance to hit.
- lfrac (int): The lower part of the accuracy fraction (denominator).
Represents the total possible outcomes.

Returns:
- StackableRolls: A new StackableRolls object that combines the original roll
with a miss chance based on the accuracy parameters.
If ufrac is greater than or equal to lfrac, returns the original roll.
If ufrac is less than or equal to 0, returns a roll that always misses.

Notes:
- The accuracy is determined by the ratio of ufrac to lfrac.
If the accuracy is 100% (ufrac = lfrac), the original roll is returned unchanged.
- If the accuracy is less than 100%, the function combines the original roll with a
miss chance (represented by a roll of {0: 1}) using weighted addition.

Example:
>>> roll = StackableRolls({10: 3, 20: 2})
>>> adjusted_roll = addAccuracyToRoll(roll, 80, 100)
>>> print(adjusted_roll)
# This would output a new StackableRolls object that accounts for an 80% chance to hit.
"""
if (ufrac >= lfrac):
return roll
elif (ufrac <= 0):
return StackableRolls({0:1})
else:
return StackableRolls.weightedAdd([roll, StackableRolls({0:1})], [ufrac, lfrac - ufrac])

def createRollWithCrit(non_crit, crit, critStage=0, accuracy_ufrac=100, accuracy_lfrac=100, gen=9, baseSpeed=100):
"""
Automatically detects the type of input for non_crit and crit,
and returns a StackableRolls object combining the rolls of critical hits
and non-critical hits, factoring accuracy.

Parameters:
- non_crit: Required. The roll when it is not a critical hit.
Supported input types:
StackableRolls, tuple / list / set, or its string equivalent
dictionary, with keys being the damage values and values being the frequency
- crit: Required. The roll when it is a critical hit.
Supported input types: See non_crit
- critStage (int): Optional. Critical hit stage. Default is 0.
- accuracy_ufrac (int): Optional. Upper part of fraction (Numerator) for accuracy. Default is 100.
- accuracy_lfrac (int): Optional. Lower part of fraction (Denominator) for accuracy. Default is 100.
- gen (int): Optional. Generation of the Pokémon game. Default is 9. Note that gen 1 is not tested.
- baseSpeed (int): Optional. Base speed of the Pokémon. Used for critical hit chance calculation for Gen 1.

Output:
- (StackableRolls): The damage roll for a single hit considering the possibility of critical hits and misses.
"""

# Helper function to convert input to StackableRolls
def to_stackable_rolls(data):
if isinstance(data, StackableRolls):
return data # Return as is if already a StackableRolls object
elif isinstance(data, dict):
return StackableRolls(data)
elif isinstance(data, (tuple, list, set)):
return StackableRolls(tupleRollToDict(str(data)))
elif isinstance(data, str):
return StackableRolls(tupleRollToDict(data))
else:
return StackableRolls({0: 1}) # Default case

# Convert inputs to StackableRolls
non_crit_roll = to_stackable_rolls(non_crit)
crit_roll = to_stackable_rolls(crit)

# Calculate critical hit odds
crit_odds = PokemonCritChanceOddsList(critStage, gen, baseSpeed)

# Combine rolls with critical hit calculations
combined_roll = StackableRolls.weightedAdd([non_crit_roll, crit_roll], crit_odds)

# Remove zeros due to extreme crit stages
combined_roll.dropZeros()

# Add accuracy to the combined roll
return addAccuracyToRoll(combined_roll, accuracy_ufrac, accuracy_lfrac).sort(inplace=True)

#Return ko chance in float
def koChance(HP, TheStackableRoll):
if (isinstance(HP, int)):
return 1 - TheStackableRoll.smallerThan(HP).fracCount / TheStackableRoll.fracCount
elif (isinstance(HP, (list, tuple, set))):
result = []
for x in HP:
result.append(1 - TheStackableRoll.smallerThan(HP).fracCount / TheStackableRoll.fracCount)
return result
elif (isinstance(HP, dict)):
result = {}
for x in HP.keys():
temp = 1 - TheStackableRoll.smallerThan(HP).fracCount / TheStackableRoll.fracCount
if (temp in result):
result[temp] += HP[x]
else:
result[temp] = HP[x]
return result
else:
return

#Print ko chance as fraction
def fracKOChance(HP, damageValues, printAsFrac=False):
'''
The chance a pokemon is KOed with the given HP and damage values provided.

Parameters:
- HP (int): Required. The HP of the pokemon.
- damageValues (StackableRolls): Required. The possible damage values and their corresponding frequencies.
- printAsFrac (bool): Optional. If true, print out the resultant fraction.

Output: ufrac, lfrac
- ufrac (int): The numerator of the chance to KO
- lfrac (int): The denominator of the chance to KO
'''
lfrac = int(damageValues.fracCount - damageValues.smallerThan(HP).fracCount)
ufrac = int(damageValues.fracCount)
x = hcf(lfrac, ufrac)
lfrac = lfrac // x
ufrac = ufrac // x
if (printAsFrac):
print(lfrac, "/", ufrac)
return ufrac, lfrac

def koChanceWithRecovery(initialHP, maxHP, recoveryPerTurn, damageRolls, startingTurn=1, maxTurns=10, isFrac=False, returnPostRecovery='auto'):
"""
Calculate the chance a Pokémon is KOed at different turns with variable recovery.
It is assumed all values of initialHP are greater than 0.

Parameters:
- initialHP (int or StackableRolls): The initial HP of the Pokémon.
- maxHP (int): The maximum HP of the Pokémon.
- recoveryPerTurn (int or list of int): HP gained from recovery per turn.
- damageRolls (StackableRolls or list of StackableRolls): Possible damage values and their frequencies.
- startingTurn (int): The turn KO chance begins to be displayed.
- maxTurns (int): The maximum turn to calculate the KO chance.
- isFrac (bool): Returns KO chance as fraction using list instead of float.
- returnPostRecovery: Determines whether post recovery KO chances should also be returned.

Returns:
- dict: Dictionary/ies where keys are turn numbers and values are the KO chance for that turn before (and after) recovery.
"""

# Initialize currentHP
currentHP = StackableRolls({initialHP: 1}) if not isinstance(initialHP, StackableRolls) else initialHP

# Prepare recoveryPerTurn as a list
recoveryPerTurn = [recoveryPerTurn] if isinstance(recoveryPerTurn, int) else recoveryPerTurn
recovery_length = len(recoveryPerTurn)

# Prepare damageRolls as a list
damageRolls = [damageRolls] if isinstance(damageRolls, StackableRolls) else damageRolls
damage_length = len(damageRolls)

ko_chances_pre_recovery = {}
ko_chances_post_recovery = {}
terminating_turn = 0

for turn in range(startingTurn, startingTurn + maxTurns):
# Determine damage for the current turn
damageRoll = damageRolls[min(turn - 1, damage_length - 1)]
currentHP = currentHP.multiply(damageRoll.change_sign_of_keys())
total_occurrences = currentHP.fracCount

# Filter occurrences with HP > 0
currentHP = currentHP.largerThan(0)
survive_occurrences_pre_recovery = currentHP.fracCount

# Determine recovery for the current turn
recoveryAmount = recoveryPerTurn[min(turn - 1, recovery_length - 1)]
recovery_this_turn = StackableRolls({recoveryAmount: 1})
currentHP = currentHP.multiply(recovery_this_turn, to_simplify=False)
survive_occurrences_post_recovery = currentHP.fracCount

# Fix HP values exceeding maximum HP
if maxHP not in currentHP.roll:
currentHP.roll[maxHP] = 0

# Accumulate occurrences into maxHP and prepare for deletion
for hp in list(currentHP.roll.keys()):
if hp > maxHP:
currentHP.roll[maxHP] += currentHP.roll[hp]
del currentHP.roll[hp]

# Append results
if isFrac:
hcf_pre_recovery = hcf(survive_occurrences_pre_recovery, total_occurrences)
ko_chances_pre_recovery[turn] = ((total_occurrences - survive_occurrences_pre_recovery) // hcf_pre_recovery, total_occurrences // hcf_pre_recovery)
hcf_post_recovery = hcf(survive_occurrences_post_recovery, total_occurrences)
ko_chances_post_recovery[turn] = ((total_occurrences - survive_occurrences_post_recovery) // hcf_post_recovery, total_occurrences // hcf_post_recovery)
else:
ko_chances_pre_recovery[turn] = 1 - survive_occurrences_pre_recovery / total_occurrences
ko_chances_post_recovery[turn] = 1 - survive_occurrences_post_recovery / total_occurrences

# Terminate if already KOed
if survive_occurrences_post_recovery == 0:
terminating_turn = turn
break

# Determine return type
return_type = 'pre_recovery' if returnPostRecovery in [False, 'auto'] else 'both' if returnPostRecovery == 'auto' and any(r < 0 for r in recoveryPerTurn[:terminating_turn]) else returnPostRecovery

return (ko_chances_pre_recovery, ko_chances_post_recovery) if return_type == 'both' else ko_chances_pre_recovery if return_type == 'pre_recovery' else ko_chances_post_recovery

'''

Instructions:
1. Copy paste your damage value, like (1, 2, 3, 4) etc.
- Then feed it to createRollWithCrit and store it in a variable

2. Calculate the possible damage range by multiplying the damage rolls
- So for example you use Move 1 three times and Move 2 two times, and the damage roll for the two moves are my_damage_roll_1 and my_damage_roll_2 respectively
- Then you do the following to save the damage range into a variable:
- totalDamageRoll = (my_damage_roll_1.pow(3)).multiply(my_damage_roll_2.pow(2))
-
- Advanced:
- StackableRolls.weightedAdd is used for summing up distinct possibilities for rolls
- multiply is used for combining sequential damage rolls

3. Get the koChance
- If you want to get a decimal number:
- koChance(HP_of_the_mon, totalDamageRoll)
- If you want to get the fraction:
- fracKOChance(HP_of_the_mon, totalDamageRoll, True)

WARNING:
- The KO chance calculated assumes no recovery
- It is totally possible that a pokemon has negative HP in intermediate calculations but the end result becomes positive HP and hence is considered not KOed if there is recovery
- The proper way to calculate KO chance with recovery is to initialize a roll with initial HP, then multiply with negative of the damage roll, then select values larger then 0, then multiply with the recovery, then iterate.

'''


# Example calculation
nc = '(13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15)'
c = '[19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 23, 23]'
icyWind = createRollWithCrit(nc, c, critStage=0, accuracy_ufrac=95, gen=9)
nc = ' (33, 34, 34, 34, 35, 35, 36, 36, 36, 37, 37, 37, 38, 38, 39, 39)'
c = {50, 51, 51, 52, 52, 53, 54, 54, 55, 55, 56, 57, 57, 58, 58, 59}
moonblast = createRollWithCrit(nc, c, 0)
nc = (210, 212, 216, 218, 218, 222, 224, 228, 230, 234, 234, 236, 240, 242, 246, 248)
c = [314, 318, 320, 326, 330, 332, 336, 342, 344, 348, 350, 356, 360, 362, 366, 372]
hydroCannon = createRollWithCrit(nc, c, accuracy_ufrac=9, accuracy_lfrac=10)
totalDamageRoll = icyWind.multiply(moonblast.multiply(hydroCannon))
fracKOChance(377, totalDamageRoll, True)
252+ SpA Venusaur Earth Power vs. 216 HP / 76 SpD Heatran: 316-376 (83.8 - 99.7%) -- guaranteed 2HKO

56+ SpA Heatran Eruption (150 BP) vs. 68 HP / 0 SpD Venusaur: 468-552 (147.1 - 173.5%) -- guaranteed OHKO
Registeel has 385 HP including one turn of Leftovers recovery, Heatran at 377 HP
48 Def Registeel Body Press vs. 216 HP / 4 Def Heatran: 160-190 (42.4 - 50.3%) -- 12.5% chance to OHKO

56+ SpA Heatran Eruption (150 BP) vs. 248 HP / 212+ SpD Registeel: 258-306 (71 - 84.2%) -- guaranteed 2HKO after Leftovers recovery
56+ SpA Heatran Eruption (150 BP) vs. +2 248 HP / 212+ SpD Registeel: 132-156 (36.3 - 42.9%) -- 94.3% chance to 3HKO after Leftovers recovery
After losing 190 HP to max roll Body Press, At 187 HP Heatran's Eruption is at 74 BP
56+ SpA Heatran Eruption (74 BP) vs. 248 HP / 212+ SpD Registeel: 128-152 (35.2 - 41.8%) -- 78% chance to 3HKO after Leftovers recovery
 
Last edited:
:volcanion:
Volcanion @ Choice Band
Level: 100
Adamant Nature
Ability: Water Absorb
EVs: 112 HP / 144 Atk / 252 SpD
- Flare Blitz

144+ Atk Choice Band Volcanion Flare Blitz vs. 68 HP / 92 Def Venusaur: 552-650 (173.5 - 204.4%) -- guaranteed OHKO
252+ SpA Overgrow Venusaur Frenzy Plant vs. 112 HP / 252 SpD Volcanion: 285-336 (86.6 - 102.1%) -- 12.5% chance to OHKO
144+ Atk Choice Band Volcanion Flare Blitz vs. 200 HP / 176 Def Primarina: 135-160 (38.4 - 45.5%) -- guaranteed 3HKO
124+ SpA Primarina Moonblast vs. 112 HP / 252 SpD Volcanion: 64-76 (19.4 - 23.1%) -- possible 5HKO
144+ Atk Choice Band Volcanion Flare Blitz vs. 248 HP / 48 Def Registeel: 356-422 (98 - 116.2%) -- 87.5% chance to OHKO
48 Def Registeel Body Press vs. 112 HP / 0 Def Volcanion: 73-86 (22.1 - 26.1%) -- 7% chance to 4HKO
Fixed

Volcanion @ Assault Vest
Level: 100
Adamant Nature
Ability: Water Absorb
EVs: 252 HP / 172 Atk / 84 SpD
- Flare Blitz

172+ Atk Volcanion Flare Blitz vs. 68 HP / 92 Def Venusaur: 374-444 (117.6 - 139.6%) -- guaranteed OHKO

Note that it's SS (Not ADV), Flare Blitz does 33% recoil, not 1/3 recoil
318*0.33=104.94, and this value is rounded half up according to the move description
So Flare Blitz recoil is 105 damage
Volcanion originally has 364 HP, after Flare Blitz recoil it is at 259 HP, so I will set Volcanion HP to 259 for the following calc

252+ SpA Overgrow Venusaur Frenzy Plant vs. 252 HP / 84 SpD Assault Vest Volcanion: 223-264 (61.2 - 72.5%) -- 12.5% chance to OHKO
172+ Atk Volcanion Flare Blitz vs. 200 HP / 176 Def Primarina: 93-110 (26.4 - 31.3%) -- guaranteed 4HKO

124+ SpA Primarina Icy Wind vs. 252 HP / 84 SpD Assault Vest Volcanion: 9-11 (2.4 - 3%) -- possibly the worst move ever

Assume Volcanion got the max rolls,Volcanion will lose 111 HP by using three Flare Blitzes
And assume Volcanion further loses 11 HP to Icy Wind
Volcanion is at 242 HP for the following calc

124+ SpA Primarina Moonblast vs. 252 HP / 84 SpD Assault Vest Volcanion: 51-60 (14 - 16.4%) -- guaranteed 5HKO
https://cantsay.github.io/resources/ko-chance-calculator/

172+ Atk Volcanion Flare Blitz vs. 248 HP / 48 Def Registeel: 246-290 (67.7 - 79.8%) -- guaranteed 2HKO after Leftovers recovery
172+ Atk Volcanion Flare Blitz vs. +2 248 HP / 48 Def Registeel: 122-146 (33.6 - 40.2%) -- 38.6% chance to 3HKO after Leftovers recovery

The calc above linked shows the chance for ko is 88.3%
No EVs to spare
 
Last edited:
:shedinja:
Shedinja @ Spell Tag
Level: 88
Lonely Nature
Ability: Wonder Guard
EVs: 252 Atk
- Shadow Claw
- Swords Dance

You're immune to all of their attacks. Shadow Claw has a 96% chance of getting at least one crit in 24 tries.

+6 Lvl 88 252+ Atk Spell Tag Shedinja Shadow Claw vs. 248 HP / 48 Def Registeel on a critical hit: 370-436 (101.9 - 120.1%) -- guaranteed OHKO
Imma improve this Shedinja break to the lowest level possible while ensuring it always works

Always works (Shedinja) @ Choice Scarf
Ability: Wonder Guard
Level: 46
Shiny: Yes
EVs: 64 Atk / 244 Spe
Jolly Nature
- Dig
- Shadow Claw
- Swords Dance
- Trick

Attack to KO Registeel after 24 Shadow Claws and 4 Digs after both sides reaching +6, and KO Primarina after 24 Shadow Claws and a Struggle after Sitrus Berry recovery. Speed to outspeed Registeel after Scarf so you have an easier time to lock Registeel into Amnesia.
+6 Lvl 46 64 Atk Shedinja Shadow Claw vs. 68 HP / 92 Def Venusaur: 70-84 (22 - 26.4%) -- 9.7% chance to 4HKO

To guarantee this always works, it is recommended that you give your opponent Scarf turn 1, use Swords Dance to reach +6, and then it depends on what move your opponent is using.
Earth Power / Sludge Bomb: EZ, spam Shadow Claw
Endure:
- Spam Shadow Claw, but remember to take the Choice Scarf back when you see the Venusaur Endure PP reaches 1 so they don't Struggle.
- After taking the Choice Scarf back, use any move you want to.
Frenzy Plant: Check how many PP your opponent has.
- If your opponent has 5 PP when you reach +6, use 5 Shadow Claws.
- If your opponent has 4 PP when you reach +6, use 3 Shadow Claw, then click Trick twice, then click Shadow Claw. Refer to the instructions above after you see their move after they received the Choice Scarf again.
Lvl 46 64 Atk Shedinja Shadow Claw vs. 200 HP / 176 Def Primarina: 18-22 (5.1 - 6.2%) -- possibly the worst move ever
Lvl 46 64 Atk Shedinja Struggle vs. 200 HP / 176 Def Primarina: 9-11 (2.5 - 3.1%) -- possibly the worst move ever

Spam Shadow Claw. If you fail to crit and get too many min rolls, Struggle should finish Primarina.

Primarina has 351 HP
Sitrus Berry gives Primarina floor(351/4) = floor(87.75) = 87 HP
351 + 87 = 438

18 * 24 + 9 = 432 + 9 = 441 > 438
Trick at turn 1

The fate awaiting Registeel if it clicks Body Press / Amnesia t1:
Click 3 SD, spam Shadow Claw
+6 Lvl 46 64 Atk Shedinja Shadow Claw vs. 248 HP / 48 Def Registeel: 46-55 (12.6 - 15.1%) -- possible 7HKO
That is a guaranteed 8HKO

Calcs for a smarter Registeel:
+6 Lvl 46 64 Atk Shedinja Shadow Claw vs. +6 248 HP / 48 Def Registeel: 12-15 (3.3 - 4.1%) -- possibly the worst move ever
+6 Lvl 46 64 Atk Shedinja Dig vs. +6 248 HP / 48 Def Registeel: 20-24 (5.5 - 6.6%) -- possibly the worst move ever

Disclaimer: This might not be the optimal strategy, but it works

Wait for Registeel to use up their Rest PP if it clicks Rest t1, spam Swords Dance while waiting
Click Trick when Rest reaches 1 PP, then click Trick again, then spam Shadow Claw,
and only click Trick twice again after Shadow Claw reaches 2 PP (If they did not click Iron Defense they are dead by now). Then use the remaining Shadow Claw and Dig PP.
If they used Iron Defense, they will receive 22 turns of Shadow Claw damage before receiving Leftovers recovery for one turn, afterwards they will receive 2 turns of Shadow Claw damage and 7 turns of Dig damage before they can do Struggle damage on Shedinja.

Registeel has 363 HP
Registeel receives floor(363/16) = floor(22.6875) = 22 HP for every turn it is holding Leftovers
Total HP Registeel has: 363+22 = 385 HP

Total damage from 24 Shadow Claws and 7 Digs (Min. roll) = 12 * 24 + 20 * 7 = 428 > 385
Click SD 4 times to reach +6, click dig 9 times, click Trick twice.
You:
Dig (7/16)
Shadow Claw (24/24)
Swords Dance (28/32)
Trick (14/16)
They:
Iron Defense (0/24)
Body Press (16/16)
Rest (16/16)
Amnesia (32/32)

If they click Amnesia, attack them, they will die (They don't stand a chance even at full HP)
Click dig 3 times, click SD 8 times, click Trick twice.
You:
Dig (4/16)
Shadow Claw (24/24)
Swords Dance (20/32)
Trick (12/16)
They:
Iron Defense (0/24)
Body Press (0/16)
Rest (16/16)
Amnesia (32/32)
- If they click Amnesia after using up BPress PP, attack them, they will die (They don't stand a chance even at full HP)
- If they click Rest after using up BPress PP, click SD 16 times, then click Trick twice.
You:
Dig (4/16)
Shadow Claw (24/24)
Swords Dance (4/32)
Trick (10/16)
They:
Iron Defense (0/24)
Body Press (0/16)
Rest (0/16)
Amnesia (32/32)
Then spam Shadow Claw 24 times, Dig 4 times, and they die even if they are full HP.
If they click Rest after using up ID PP, click SD 16 times, then click Trick twice.
You:
Dig (7/16)
Shadow Claw (24/24)
Swords Dance (12/32)
Trick (12/16)
They:
Iron Defense (0/24)
Body Press (16/16)
Rest (0/16)
Amnesia (32/32)
- If they clicked Amnesia, then spam Shadow Claw 24 times, Dig 4 times, and they die even if they are full HP.
- If they clicked Body Press, then you need to spam Trick until they click Amnesia to proceed, or until your Trick reached 3 PP and they still did not click Amnesia. If that happened, Then click SD 4 times, and Trick twice, and their only move available is Amnesia. Spam Shadow Claw 24 times, Dig 4 times, and they die even if they are full HP.
You:
Dig (7/16)
Shadow Claw (24/24)
Swords Dance (12/32)
Trick (3/16)
They:
Iron Defense (0/24)
Body Press (5/16)
Rest (0/16)
Amnesia (32/32)
Registeel has 363 HP
Total damage from 24 Shadow Claws and 4 Digs = 12 * 24 + 20 * 4 = 368
 
Imma improve this Shedinja break to the lowest level possible while ensuring it always works

Always works (Shedinja) @ Choice Scarf
Ability: Wonder Guard
Level: 46
Shiny: Yes
EVs: 64 Atk / 244 Spe
Jolly Nature
- Dig
- Shadow Claw
- Swords Dance
- Trick

Attack to KO Registeel after 24 Shadow Claws and 4 Digs after both sides reaching +6, and KO Primarina after 24 Shadow Claws and a Struggle after Sitrus Berry recovery. Speed to outspeed Registeel after Scarf so you have an easier time to lock Registeel into Amnesia.
+6 Lvl 46 64 Atk Shedinja Shadow Claw vs. 68 HP / 92 Def Venusaur: 70-84 (22 - 26.4%) -- 9.7% chance to 4HKO

To guarantee this always works, it is recommended that you give your opponent Scarf turn 1, use Swords Dance to reach +6, and then it depends on what move your opponent is using.
Earth Power / Sludge Bomb: EZ, spam Shadow Claw
Endure:
- Spam Shadow Claw, but remember to take the Choice Scarf back when you see the Venusaur Endure PP reaches 1 so they don't Struggle.
- After taking the Choice Scarf back, use any move you want to.
Frenzy Plant: Check how many PP your opponent has.
- If your opponent has 5 PP when you reach +6, use 5 Shadow Claws.
- If your opponent has 4 PP when you reach +6, use 3 Shadow Claw, then click Trick twice, then click Shadow Claw. Refer to the instructions above after you see their move after they received the Choice Scarf again.
Lvl 46 64 Atk Shedinja Shadow Claw vs. 200 HP / 176 Def Primarina: 18-22 (5.1 - 6.2%) -- possibly the worst move ever
Lvl 46 64 Atk Shedinja Struggle vs. 200 HP / 176 Def Primarina: 9-11 (2.5 - 3.1%) -- possibly the worst move ever

Spam Shadow Claw. If you fail to crit and get too many min rolls, Struggle should finish Primarina.

Primarina has 351 HP
Sitrus Berry gives Primarina floor(351/4) = floor(87.75) = 87 HP
351 + 87 = 438

18 * 24 + 9 = 432 + 9 = 441 > 438
Trick at turn 1

The fate awaiting Registeel if it clicks Body Press / Amnesia t1:
Click 3 SD, spam Shadow Claw
+6 Lvl 46 64 Atk Shedinja Shadow Claw vs. 248 HP / 48 Def Registeel: 46-55 (12.6 - 15.1%) -- possible 7HKO
That is a guaranteed 8HKO

Calcs for a smarter Registeel:
+6 Lvl 46 64 Atk Shedinja Shadow Claw vs. +6 248 HP / 48 Def Registeel: 12-15 (3.3 - 4.1%) -- possibly the worst move ever
+6 Lvl 46 64 Atk Shedinja Dig vs. +6 248 HP / 48 Def Registeel: 20-24 (5.5 - 6.6%) -- possibly the worst move ever

Disclaimer: This might not be the optimal strategy, but it works

Wait for Registeel to use up their Rest PP if it clicks Rest t1, spam Swords Dance while waiting
Click Trick when Rest reaches 1 PP, then click Trick again, then spam Shadow Claw,
and only click Trick twice again after Shadow Claw reaches 2 PP (If they did not click Iron Defense they are dead by now). Then use the remaining Shadow Claw and Dig PP.
If they used Iron Defense, they will receive 22 turns of Shadow Claw damage before receiving Leftovers recovery for one turn, afterwards they will receive 2 turns of Shadow Claw damage and 7 turns of Dig damage before they can do Struggle damage on Shedinja.

Registeel has 363 HP
Registeel receives floor(363/16) = floor(22.6875) = 22 HP for every turn it is holding Leftovers
Total HP Registeel has: 363+22 = 385 HP

Total damage from 24 Shadow Claws and 7 Digs (Min. roll) = 12 * 24 + 20 * 7 = 428 > 385
Click SD 4 times to reach +6, click dig 9 times, click Trick twice.
You:
Dig (7/16)
Shadow Claw (24/24)
Swords Dance (28/32)
Trick (14/16)
They:
Iron Defense (0/24)
Body Press (16/16)
Rest (16/16)
Amnesia (32/32)

If they click Amnesia, attack them, they will die (They don't stand a chance even at full HP)
Click dig 3 times, click SD 8 times, click Trick twice.
You:
Dig (4/16)
Shadow Claw (24/24)
Swords Dance (20/32)
Trick (12/16)
They:
Iron Defense (0/24)
Body Press (0/16)
Rest (16/16)
Amnesia (32/32)
- If they click Amnesia after using up BPress PP, attack them, they will die (They don't stand a chance even at full HP)
- If they click Rest after using up BPress PP, click SD 16 times, then click Trick twice.
You:
Dig (4/16)
Shadow Claw (24/24)
Swords Dance (4/32)
Trick (10/16)
They:
Iron Defense (0/24)
Body Press (0/16)
Rest (0/16)
Amnesia (32/32)
Then spam Shadow Claw 24 times, Dig 4 times, and they die even if they are full HP.
If they click Rest after using up ID PP, click SD 16 times, then click Trick twice.
You:
Dig (7/16)
Shadow Claw (24/24)
Swords Dance (12/32)
Trick (12/16)
They:
Iron Defense (0/24)
Body Press (16/16)
Rest (0/16)
Amnesia (32/32)
- If they clicked Amnesia, then spam Shadow Claw 24 times, Dig 4 times, and they die even if they are full HP.
- If they clicked Body Press, then you need to spam Trick until they click Amnesia to proceed, or until your Trick reached 3 PP and they still did not click Amnesia. If that happened, Then click SD 4 times, and Trick twice, and their only move available is Amnesia. Spam Shadow Claw 24 times, Dig 4 times, and they die even if they are full HP.
You:
Dig (7/16)
Shadow Claw (24/24)
Swords Dance (12/32)
Trick (3/16)
They:
Iron Defense (0/24)
Body Press (5/16)
Rest (0/16)
Amnesia (32/32)
Registeel has 363 HP
Total damage from 24 Shadow Claws and 4 Digs = 12 * 24 + 20 * 4 = 368
I think that can work, but at some point you need to take the scarf back, since you're not immune to struggle. However, it's not the lowest possible level:

:shedinja:
Always works (Shedinja) @ Sticky Barb
Ability: Wonder Guard
Level: 20
EVs: 1 HP
Serious Nature
- Scratch
- Gust
- Shadow Sneak
- Trick

With optimal use, each Rest heals 7 turns of Sticky Barb damage, so Registeel will die on turn 120, conveniently the same turn it runs out of PP, so it doesn't get to struggle.
Shadow Sneak means you can't be encored into Trick.
In theory this set works at level 1, but you can't have a Shedinja with Shadow Sneak under level 20.
 
I think that can work, but at some point you need to take the scarf back, since you're not immune to struggle.
Yes then give them the Scarf back again
However, it's not the lowest possible level:
:shedinja:
Always works (Shedinja) @ Sticky Barb
Ability: Wonder Guard
Level: 20
EVs: 1 HP
Serious Nature
- Scratch
- Gust
- Shadow Sneak
- Trick

With optimal use, each Rest heals 7 turns of Sticky Barb damage, so Registeel will die on turn 120, conveniently the same turn it runs out of PP, so it doesn't get to struggle.
Shadow Sneak means you can't be encored into Trick.
In theory this set works at level 1, but you can't have a Shedinja with Shadow Sneak under level 20.
Shadow Sneak and Scratch are contact moves, so replace Scratch with Spite to drain their Rest pp, and Shadow Sneak with Ally Switch / Endure / Protect so you don't die to Sticky Barb, and this should work
 
Last edited:
Yes then give them the Scarf back again

Shadow Sneak and Scratch are contact moves, so replace Scratch with Spite to drain their Rest pp, and Shadow Sneak with Ally Switch / Endure / Protect so you don't die to Sticky Barb, and this should work
Contact moves only steal Sticky Barb if you're not holding an item, and none of the opponents can remove your item (and you'll never eat the berries since you'll never be under 100% health), so you'll never take damage from it.
Spite also works, but like Shadow Sneak it's incompatible with Pokemon Go, so you're still stuck at level 20 minimum.
 
Now this is the lowest level possible for Shedinja:

:shedinja:
Shedinja @ Sticky Barb
Ability: Wonder Guard
Level: 12
EVs: 1 HP
Serious Nature
- Scratch
- Gust
- Endure
- Trick

Against Registeel:
Turn 1: Trick
Turns 2-8: Endure
Turns 9-120: Scratch/Gust
Turn 121: Endure

With optimal play, the first Rest heals 8 turns of Sticky Barb damage, and each subsequent Rest heals 7 turns of damage, so Registeel runs out of PP on turn 120 but doesn't faint until turn 121. By using Scratch or Gust on turn 120 and then Endure on turn 121, you guarantee that you survive the Struggle and win the match.
 
:pmd/Togekiss:
Baking Savior (Togekiss) @ Choice Specs
Ability: Serene Grace
EVs: 252 SpA / 84 SpD / 172 Spe
Modest Nature
IVs: 0 Atk
- Air Slash
- Trick
- Solar Beam
- Seismic Toss
After all of the Shedinja optimization, (we really have too much time for this wtf) I present, egg

252+ SpA Choice Specs Togekiss Air Slash vs. 68 HP / 0 SpD Venusaur: 380-450 (119.4 - 141.5%) -- guaranteed OHKO

252+ SpA Venusaur Sludge Bomb vs. 0 HP / 84 SpD Togekiss: 222-264 (71.3 - 84.8%) -- guaranteed 2HKO

252+ SpA Choice Specs Togekiss Solar Beam vs. 200 HP / 0 SpD Primarina: 358-422 (101.9 - 120.2%) -- guaranteed OHKO

124+ SpA Primarina Hydro Cannon vs. 0 HP / 84 SpD Togekiss: 196-232 (63 - 74.5%) -- guaranteed 2HKO
Icy wind can't slow you down enough

Seismic Toss 4HKOs and you just turn one trick
 
:pmd/Moltres-galar:
Shiny Galarian (Moltres) @ Life Orb
Ability: Flame Body
EVs: 252 Atk / 252 SpD / 4 Spe
Adamant Nature
- Substitute
- Flare Blitz
- Roost
- Brave Bird
Just about 3 months in the making (took me like half an hour)

252+ Atk Life Orb Moltres Flare Blitz vs. 68 HP / 92 Def Venusaur: 486-577 (152.8 - 181.4%) -- guaranteed OHKO

252 SpA Venusaur Sludge Bomb vs. 0 HP / 252 SpD Moltres: 109-129 (33.9 - 40.1%) -- guaranteed 3HKO

(LO + recoil doesnt let this kill w/o a crit)

252+ Atk Life Orb Moltres Brave Bird vs. 200 HP / 176 Def Primarina: 242-286 (68.9 - 81.4%) -- guaranteed 2HKO

124+ SpA Primarina Moonblast vs. 0 HP / 252 SpD Moltres: 66-78 (20.5 - 24.2%) -- guaranteed 5HKO

(Sub turn one, unless they encore or crit turn one then you win)

252+ Atk Life Orb Moltres Flare Blitz vs. 248 HP / 48 Def Registeel: 320-377 (88.1 - 103.8%) -- 25% chance to OHKO

What do I even say at this point

(What does norse have to do with this)
 
:dracozolt:
Dracozolt @ Assault Vest
Ability: Hustle
EVs: 252 Atk / 116 SpD / 140 Spe
Adamant Nature
- Bolt Beak

252+ Atk Hustle Dracozolt Bolt Beak (170 BP) vs. 68 HP / 92 Def Venusaur: 199-235 (62.5 - 73.8%) -- guaranteed 2HKO
252 SpA Venusaur Earth Power vs. 0 HP / 116 SpD Assault Vest Dracozolt: 126-150 (39.2 - 46.7%) -- guaranteed 3HKO

252+ Atk Hustle Dracozolt Bolt Beak (170 BP) vs. 200 HP / 176 Def Primarina: 788-930 (224.5 - 264.9%) -- guaranteed OHKO

252+ Atk Hustle Dracozolt Bolt Beak (170 BP) vs. 248 HP / 48 Def Registeel: 258-304 (71 - 83.7%) -- guaranteed 2HKO after Leftovers recovery
252+ Atk Hustle Dracozolt Bolt Beak (170 BP) vs. +2 248 HP / 48 Def Registeel: 129-153 (35.5 - 42.1%) -- 86.3% chance to 3HKO after Leftovers recovery

:ninetales:
Ninetales @ Choice Specs
Ability: Drought
EVs: 44 HP / 200 SpA / 252 SpD / 12 Spe
Modest Nature
IVs: 0 Atk
- Heat Wave
- Solar Beam


200+ SpA Choice Specs Ninetales Heat Wave vs. 68 HP / 0 SpD Venusaur in Sun: 528-624 (166 - 196.2%) -- guaranteed OHKO
252 SpA Venusaur Earth Power vs. 32 HP / 252 SpD Ninetales: 130-154 (44 - 52.2%) -- 13.3% chance to 2HKO

200+ SpA Choice Specs Ninetales Solar Beam vs. 200 HP / 0 SpD Primarina: 262-310 (74.6 - 88.3%) -- guaranteed 2HKO
124+ SpA Primarina Moonblast vs. 32 HP / 252 SpD Ninetales: 60-71 (20.3 - 24%) -- guaranteed 5HKO
124+ SpA Primarina Hydro Cannon vs. 32 HP / 252 SpD Ninetales in Sun: 186-222 (63 - 75.2%) -- guaranteed 2HKO

200+ SpA Choice Specs Ninetales Heat Wave vs. 248 HP / 212+ SpD Registeel in Sun: 296-350 (81.5 - 96.4%) -- guaranteed 2HKO after Leftovers recovery
 
Last edited:
Cycle 19 ends in 2 weeks maybe

Walking Wake @ Booster Energy
Ability: Protosynthesis
Tera Type: Water
EVs: 88 HP / 192 SpA / 28 SpD / 200 Spe
Timid Nature
IVs: 0 Atk
- Snarl
- Hydro Pump
- Draco Meteor
- Flamethrower

Metagross @ Choice Band
Ability: Clear Body
Tera Type: Steel
EVs: 240 HP / 220 Atk / 48 SpD
Adamant Nature
- Heavy Slam
- Psychic Fangs
- Trick
- Earthquake

Sylveon @ Custap Berry
Ability: Pixilate
Tera Type: Fairy
EVs: 80 HP / 200 Def / 228 SpA
Modest Nature
- Hyper Beam
- Hyper Voice
- Fake Tears
- Endure

I'll do the google forms stuff later unless someone else wants to do it first
 
Cycle 19 ends in 2 weeks maybe

Walking Wake @ Booster Energy
Ability: Protosynthesis
Tera Type: Water
EVs: 88 HP / 192 SpA / 28 SpD / 200 Spe
Timid Nature
IVs: 0 Atk
- Snarl
- Hydro Pump
- Draco Meteor
- Flamethrower

Metagross @ Choice Band
Ability: Clear Body
Tera Type: Steel
EVs: 240 HP / 220 Atk / 48 SpD
Adamant Nature
- Heavy Slam
- Psychic Fangs
- Trick
- Earthquake

Sylveon @ Custap Berry
Ability: Pixilate
Tera Type: Fairy
EVs: 80 HP / 200 Def / 228 SpA
Modest Nature
- Hyper Beam
- Hyper Voice
- Fake Tears
- Endure

I'll do the google forms stuff later unless someone else wants to do it first
Ninetales-Alola @ Leftovers
Ability: Snow Warning
Tera Type: Ice
EVs: 216 HP / 40 Def / 252 Spe
Timid Nature
IVs: 0 Atk
- Protect
- Encore
- Disable
- Moonblast

192 SpA Protosynthesis Walking Wake Flamethrower vs. 216 HP / 0 SpD Ninetales-Alola: 238-282 (69.7 - 82.6%) -- guaranteed 2HKO after Leftovers recovery ninetales 2hko with moonblast
228+ SpA Pixilate Sylveon Hyper Beam vs. 216 HP / 0 SpD Ninetales-Alola: 282-333 (82.6 - 97.6%) -- guaranteed 2HKO after Leftovers recovery protect t1 encore t2 protect t3 disable t4 encore t5
if hyper voice protect t1 encore t2 protect t3 disable t4 encore t5
if fake tears or endure encore and win
metagross protect t1 disable t2 and win
 
Dondozo @ Choice Band
Ability: Unaware
Tera Type: Water
EVs: 252 HP / 172 Atk / 20 Def / 64 SpD
Adamant Nature
- Outrage
- Heavy Slam
- Earthquake
- Wave Crash
192 SpA Protosynthesis Walking Wake Draco Meteor vs. 252 HP / 64 SpD Dondozo: 333-393 (66 - 77.9%) -- guaranteed 2HKO
172+ Atk Choice Band Dondozo Outrage vs. 88 HP / 0 Def Walking Wake: 362-428 (100.2 - 118.5%) -- guaranteed OHKO
228+ SpA Pixilate Sylveon Hyper Beam vs. 252 HP / 64 SpD Dondozo: 364-430 (72.2 - 85.3%) -- guaranteed 2HKO
172+ Atk Choice Band Dondozo Heavy Slam (120 BP) vs. 80 HP / 200 Def Sylveon: 366-432 (104.2 - 123%) -- guaranteed OHKO
220+ Atk Choice Band Metagross Psychic Fangs vs. 252 HP / 0 Def Dondozo: 204-241 (40.4 - 47.8%) -- guaranteed 3HKO
172+ Atk Choice Band Dondozo Earthquake vs. 240 HP / 0 Def Metagross: 224-264 (62 - 73.1%) -- guaranteed 2HKO
Ninetales-Alola @ Leftovers
Ability: Snow Warning
Tera Type: Ice
EVs: 216 HP / 40 Def / 252 Spe
Timid Nature
IVs: 0 Atk
- Protect
- Encore
- Disable
- Moonblast

192 SpA Protosynthesis Walking Wake Flamethrower vs. 216 HP / 0 SpD Ninetales-Alola: 238-282 (69.7 - 82.6%) -- guaranteed 2HKO after Leftovers recovery ninetales 2hko with moonblast
228+ SpA Pixilate Sylveon Hyper Beam vs. 216 HP / 0 SpD Ninetales-Alola: 282-333 (82.6 - 97.6%) -- guaranteed 2HKO after Leftovers recovery protect t1 encore t2 protect t3 disable t4 encore t5
if hyper voice protect t1 encore t2 protect t3 disable t4 encore t5
if fake tears or endure encore and win
metagross protect t1 disable t2 and win
 
Back
Top