paper-dynasty-card-creation/custom_cards/will_baserunning_strat.py
2025-11-14 09:51:04 -06:00

118 lines
3.4 KiB
Python

"""
Calculate proper Stratomatic baserunning ratings for Will the Thrill.
"""
# Will the Thrill profile:
# - Above average speed (not elite, but good)
# - Good contact hitter (high BABIP)
# - Takes extra bases well
# - Not a huge stolen base threat but capable
# STEALING RATINGS
# Based on profile: decent speed, not aggressive basestealer
# Assume ~15 SB / ~5 CS per season (75% success rate)
# That's moderate attempt rate, decent success
steal_low = 7 # Decent success floor (0-20 scale)
steal_high = 11 # Good success ceiling (0-20 scale)
steal_auto = False # Not aggressive enough for auto-attempts
steal_jump = 0.33 # 12 out of 36 chances for good jump (converts to "4-6")
print("="*70)
print("WILL THE THRILL - CORRECTED STRATOMATIC BASERUNNING")
print("="*70)
print()
print("STEALING:")
print(f" steal_low: {steal_low}")
print(f" steal_high: {steal_high}")
print(f" steal_auto: {steal_auto}")
print(f" steal_jump: {steal_jump} (converts to Strat notation)")
print()
print(" Interpretation:")
print(f" - Success range: {steal_low}-{steal_high} on 2d10")
print(f" - Auto-attempt: {'Yes' if steal_auto else 'No'}")
print(f" - Good jump: {int(steal_jump * 36)}/36 chances")
print()
# HIT-AND-RUN RATING
# Based on BABIP calculation from stats
# High contact, low strikeouts = good hit-and-run
# AVG .285-.300, low K rate = high BABIP
# Calculate BABIP for Will
# From preview: 37 hits, ~1.5 HR, ~14 K per 108 chances
# BABIP = (H - HR) / (AB - K - HR)
# AB ≈ 90 (108 - 18 BB/HBP)
# BABIP ≈ (37 - 1.5) / (90 - 14 - 1.5) ≈ 35.5 / 74.5 ≈ 0.476 (very high!)
babip = 0.476
if babip >= 0.35:
hit_run = 'A'
elif babip >= 0.30:
hit_run = 'B'
elif babip >= 0.25:
hit_run = 'C'
else:
hit_run = 'D'
print("HIT-AND-RUN:")
print(f" Rating: {hit_run}")
print(f" BABIP: {babip:.3f}")
print(f" (Grade A = .350+, B = .300-.349, C = .250-.299, D = <.250)")
print()
# RUNNING RATING
# Based on extra base taken percentage
# Formula: max(min(round(6 + (10 * (XBT% / 80))), 17), 8)
# Good baserunner, takes extra bases well
xbt_pct = 52.0 # 52% extra base taken (from archetype)
running = max(min(round(6 + (10 * (xbt_pct / 80))), 17), 8)
print("RUNNING:")
print(f" Rating: {running}")
print(f" XBT%: {xbt_pct}%")
print(f" (Scale: 8-17, where 8=slow, 12=average, 17=elite)")
print()
print("="*70)
print("SUMMARY - CORRECT STRATOMATIC FORMAT")
print("="*70)
print()
print("Batting Card Fields:")
print(f" steal_low: {steal_low}")
print(f" steal_high: {steal_high}")
print(f" steal_auto: {1 if steal_auto else 0} (stored as integer in DB)")
print(f" steal_jump: {steal_jump}")
print(f" hit_and_run: '{hit_run}'")
print(f" running: {running}")
print()
print("Database payload:")
print("{")
print(f" 'steal_low': {steal_low},")
print(f" 'steal_high': {steal_high},")
print(f" 'steal_auto': {1 if steal_auto else 0},")
print(f" 'steal_jump': {steal_jump},")
print(f" 'hit_and_run': '{hit_run}',")
print(f" 'running': {running}")
print("}")
print()
print("="*70)
# Show comparison to what I generated before
print()
print("COMPARISON:")
print("-"*70)
print("WRONG (my previous output):")
print(" Steal Range: 6-7")
print(" Jump: 6/10")
print(" Running: 6/10")
print(" Hit-and-Run: 8/10")
print()
print("CORRECT (Stratomatic format):")
print(f" Steal Range: {steal_low}-{steal_high}")
print(f" Jump: {steal_jump} (out of 1.0)")
print(f" Running: {running} (out of 17)")
print(f" Hit-and-Run: {hit_run} (letter grade)")
print("="*70)