From 1d593a91a63392b09167f8a84af7de4cdb5fb4a1 Mon Sep 17 00:00:00 2001 From: Cal Corum Date: Wed, 8 Apr 2026 07:31:51 -0500 Subject: [PATCH] feat: add RARITY_LADDER, rarity_is_downgrade, and next_rarity helpers (#59) Closes #59 Co-Authored-By: Claude Sonnet 4.6 --- rarity_thresholds.py | 53 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/rarity_thresholds.py b/rarity_thresholds.py index ed0982d..f1c49c6 100644 --- a/rarity_thresholds.py +++ b/rarity_thresholds.py @@ -144,3 +144,56 @@ def get_batter_thresholds(season: int) -> BatterRarityThresholds: return BATTER_THRESHOLDS_2025 else: return BATTER_THRESHOLDS_2024 + + +# Ordered from least to most prestigious. Used for ladder comparisons (T4 +# rarity upgrade, downgrade guard). Do not change the order. +RARITY_LADDER: list[int] = [ + 5, + 4, + 3, + 2, + 1, + 99, +] # Common → Bronze → Silver → Gold → Diamond → HoF + + +def rarity_is_downgrade(current_rarity_id: int, new_rarity_id: int) -> bool: + """Return True if new_rarity_id is a less prestigious tier than current_rarity_id. + + Uses the RARITY_LADDER ordering. Unknown IDs are treated as position 0 + (worst), so an unknown current rarity will never trigger a downgrade guard. + """ + try: + current_pos = RARITY_LADDER.index(current_rarity_id) + except ValueError: + return False + try: + new_pos = RARITY_LADDER.index(new_rarity_id) + except ValueError: + return False + return current_pos > new_pos + + +def next_rarity(current_rarity_id: int) -> int | None: + """Return the next more-prestigious rarity ID, or None if already at HoF. + + Uses the RARITY_LADDER ordering. Returns None when current_rarity_id is + Hall of Fame (99) — the T4 rarity upgrade is a no-op at the top tier. + Returns None for any unrecognised rarity ID. + + Examples: + next_rarity(5) → 4 (Common → Bronze) + next_rarity(4) → 3 (Bronze → Silver) + next_rarity(3) → 2 (Silver → Gold) + next_rarity(2) → 1 (Gold → Diamond) + next_rarity(1) → 99 (Diamond → HoF) + next_rarity(99) → None (HoF: already at max) + """ + try: + pos = RARITY_LADDER.index(current_rarity_id) + except ValueError: + return None + if pos == len(RARITY_LADDER) - 1: + return None # Already at HoF + return RARITY_LADDER[pos + 1]