"""
Competitive Pokemon: damage roll simulation.
Demonstrates the 16-value damage range that makes
every KO threshold a probabilistic, not deterministic, fact.
"""
import random
from collections import Counter
def damage(base_power: int, attack: int, defense: int, level: int = 50) -> int:
"""Apply the core damage formula with a random roll in [85, 100]."""
roll = random.randint(85, 100)
raw = ((2 * level // 5 + 2) * base_power * attack // defense) // 50 + 2
return int(raw * roll / 100)
def roll_distribution(base_power: int, attack: int, defense: int,
trials: int = 100_000) -> dict[int, float]:
counts: Counter[int] = Counter(
damage(base_power, attack, defense) for _ in range(trials)
)
total = sum(counts.values())
return {v: round(c / total * 100, 2) for v, c in sorted(counts.items())}
def ko_probability(base_power: int, attack: int, defense: int,
target_hp: int, trials: int = 100_000) -> float:
"""P(one-hit KO) for given target_hp."""
kos = sum(
1 for _ in range(trials)
if damage(base_power, attack, defense) >= target_hp
)
return round(kos / trials * 100, 2)