Generation 1 (Pokémon Red, Blue, and Yellow) uses a unique and notoriously complex catching algorithm that differs significantly from later games. Unlike modern titles where catch chance is a smooth curve, Gen 1 relies on distinct "check stages" and fixed integer math.
The Logic Stages:
The Master Ball Check: If a Master Ball is used, the catch is guaranteed immediately.
The Status Check: The game generates a random number. If the Pokémon has a status, it checks against the status value (25 for Sleep/Freeze, 12 for others). If the random number is lower, the Pokémon is caught regardless of HP or Ball type.
The Catch Rate Check: The game checks the species' base catch rate against the ball modifier. If this check fails, the ball misses or breaks immediately.
The HP Factor: If the species check passes, the game calculates an HP factor (f) based on the current HP ratio. A final random check is performed against this value.
Common Gen 1 Catch Rates
Pokémon
Base Catch Rate
Mewtwo / Zapdos / Articuno / Moltres
3
Snorlax
25
Starter Pokémon (Charmander, etc.)
45
Pikachu
190
Caterpie / Magikarp / Pidgey
255
Example Calculation
If you are trying to catch a Mewtwo (Catch Rate 3) at 1 HP out of 250 with an Ultra Ball while it is Asleep:
Status Chance: ~9.7% (25/256 chance to catch instantly).
HP Chance: If the status check fails, the calculation for Mewtwo with an Ultra Ball at low HP is extremely low (less than 1%), making the status condition the most important factor in Gen 1.
function calculateGen1Catch() {
var catchRate = parseFloat(document.getElementById('catchRate').value);
var ballVal = parseFloat(document.getElementById('ballType').value);
var maxHP = parseFloat(document.getElementById('maxHP').value);
var currHP = parseFloat(document.getElementById('currHP').value);
var statusVal = parseFloat(document.getElementById('statusEffect').value);
// Validate inputs
if (isNaN(catchRate) || isNaN(maxHP) || isNaN(currHP) || currHP <= 0 || maxHP maxHP) {
currHP = maxHP;
}
// Result element
var resultArea = document.getElementById('resultArea');
var catchPercentage = document.getElementById('catchPercentage');
var shakeDesc = document.getElementById('shakeDesc');
// Logic for Master Ball
if (ballVal === 0) {
catchPercentage.innerHTML = "100%";
shakeDesc.innerHTML = "The Master Ball never fails!";
resultArea.style.display = "block";
return;
}
// Gen 1 Algorithm Simulation
// Step 1: Status Probability
var probStatus = statusVal / 256;
// Step 2: Probability of passing the Catch Rate check
// In Gen 1: R2 < CatchRate. BUT, the ball affects this.
// Poke/Safari: check against catchRate. Great: check against catchRate (but logic is slightly different).
// Simplified effective Gen 1 logic for a probability estimate:
var modifiedCatchRate = catchRate;
if (ballVal === 200) modifiedCatchRate = Math.min(255, catchRate + 0); // Great Ball doesn't actually buff the rate check, it buffs the HP check
if (ballVal === 150) modifiedCatchRate = Math.min(255, catchRate + 0);
// The "Catch Rate" check in Gen 1 is actually: If Rnd(0,255) < CatchRate
var probRateCheck = catchRate / 256;
// Step 3: The HP factor (f)
// f = (MaxHP * 255) / (CurrHP / BallFactor)
// BallFactors: Poke=12, Great=8, Ultra=12.
// Wait, Ultra Ball is notoriously bugged/worse than Great Ball in Gen 1 for many species.
var ballFactor = 12;
if (ballVal === 200) ballFactor = 8;
if (ballVal === 150) ballFactor = 12;
var hpDivisor = Math.floor(currHP / ballFactor);
if (hpDivisor 255) f = 255;
var probHPCheck = (f + 1) / 256;
// Combined Probability:
// P = P(Status) + [1 – P(Status)] * P(RateCheck) * P(HPCheck)
var finalProb = probStatus + (1 – probStatus) * (probRateCheck * probHPCheck);
var displayPct = (finalProb * 100).toFixed(2);
if (displayPct > 100) displayPct = 100;
catchPercentage.innerHTML = displayPct + "%";
// Qualitative description
if (displayPct > 75) {
shakeDesc.innerHTML = "Excellent odds! You'll likely catch it in 1-2 shakes.";
} else if (displayPct > 30) {
shakeDesc.innerHTML = "Good chance. Keep those balls flying!";
} else if (displayPct > 10) {
shakeDesc.innerHTML = "Tough catch. Expect the ball to break often.";
} else {
shakeDesc.innerHTML = "Very difficult! Status conditions are your only hope here.";
}
resultArea.style.display = "block";
}