#!/usr/bin/env python3
# ======================================================
#  IDOL LEAGUE  –  두 팀 비교 시뮬 (wRC+·WAR + 순위 포인트)
#  * 20–80 스케일 → 시즌 비율 변환
#  * PA=650, jitter ±20 %
#  * 상위 6명 포인트(10·7·5·3·2·1)로 팀 승패 판단
# ======================================================

import random
from collections import Counter

# ───────────────  로스터  ───────────────
# team, player, Contact, Gap, HR_Power, Eye
RAW = [
    # === aespa ===
    ("aespa","카리나",75,65,80,60), ("aespa","지젤",50,55,65,55),
    ("aespa","윈터",70,75,50,75),   ("aespa","닝닝",70,65,60,70),

    # === IVE ===
    ("IVE","안유진",70,60,70,65), ("IVE","가을",60,65,55,45),
    ("IVE","레이",55,55,60,55),   ("IVE","장원영",80,55,70,50),
    ("IVE","리즈",65,50,60,70),   ("IVE","이서",60,55,65,55),

    # === NewJeans ===
    ("NewJeans","민지",70,70,65,45), ("NewJeans","하니",65,75,65,60),
    ("NewJeans","다니엘",55,65,55,55), ("NewJeans","해린",75,75,60,50),
    ("NewJeans","혜인",50,60,55,55),

    # === LE SSERAFIM ===
    ("LE SSERAFIM","김채원",60,75,60,70), ("LE SSERAFIM","사쿠라",55,55,65,50),
    ("LE SSERAFIM","허윤진",60,55,55,65), ("LE SSERAFIM","카즈하",65,75,70,45),
    ("LE SSERAFIM","홍은채",65,65,60,40),

    # === (G)I-dle ===
    ("i-dle","미연",75,60,65,70), ("i-dle","민니",65,55,65,70),
    ("i-dle","소연",45,55,50,75), ("i-dle","우기",65,65,60,65),
    ("i-dle","슈화",60,55,65,60),

    # === fromis_9 ===
    ("fromis_9","송하영",55,75,60,70), ("fromis_9","박지원",70,55,50,80),
    ("fromis_9","이채영",70,60,70,55), ("fromis_9","이나경",75,60,60,60),
    ("fromis_9","백지헌",65,55,80,40),

    # === ITZY ===
    ("ITZY","유나",75,70,80,55), ("ITZY","예지",65,75,60,65),
    ("ITZY","리아",60,45,60,70), ("ITZY","채령",45,75,65,60),
    ("ITZY","류진",60,70,60,60),

    # === NMIXX ===
    ("NMIXX","릴리",55,55,55,80), ("NMIXX","해원",60,65,50,70),
    ("NMIXX","설윤",80,60,65,65), ("NMIXX","배이",60,55,65,55),
    ("NMIXX","지우",70,70,55,60), ("NMIXX","규진",60,75,60,55),

    # === KISS OF LIFE ===
    ("KISS OF LIFE","쥴리",50,70,70,65), ("KISS OF LIFE","벨",70,65,65,70),
    ("KISS OF LIFE","나띠",60,75,75,65), ("KISS OF LIFE","하늘",65,60,60,65),

    # === ILLIT ===
    ("ILLIT","윤아",55,60,55,60), ("ILLIT","민주",75,60,60,65),
    ("ILLIT","모카",60,65,55,55), ("ILLIT","원희",65,60,55,55),
    ("ILLIT","이로하",60,75,60,50),

    # === STAYC ===
    ("STAYC","수민",50,60,50,50), ("STAYC","시은",45,50,60,65),
    ("STAYC","아이사",60,65,75,55), ("STAYC","세은",65,50,55,50),
    ("STAYC","윤",65,60,60,60), ("STAYC","재이",65,55,65,50),

    # === Hearts2Hearts ===
    ("Hearts2Hearts","이안",75,65,50,55), ("Hearts2Hearts","지우",60,70,70,55),
    ("Hearts2Hearts","스텔라",50,55,60,65), ("Hearts2Hearts","유하",65,70,55,65),
    ("Hearts2Hearts","주은",45,70,50,55),

    # === KiiiKiii ===
    ("KiiiKiii","이솔",65,60,60,55), ("KiiiKiii","수이",60,70,60,55),
    ("KiiiKiii","지유",55,55,55,70), ("KiiiKiii","하음",65,65,60,60),
    ("KiiiKiii","키야",55,70,65,55),

    # === H1-KEY ===
    ("H1-KEY","서이",70,65,65,65), ("H1-KEY","리이나",70,60,70,60),
    ("H1-KEY","휘서",60,70,60,70), ("H1-KEY","옐",60,55,85,55),

    # === BABYMONSTER ===
    ("BABYMONSTER","루카",50,75,65,50), ("BABYMONSTER","라미",45,60,60,70),
    ("BABYMONSTER","로라",65,60,60,65), ("BABYMONSTER","아현",70,70,65,75),
    ("BABYMONSTER","아사",65,70,65,55), ("BABYMONSTER","파리타",60,55,75,60),

    # === FIFTY FIFTY ===
    ("FIFTY FIFTY","키나",55,55,55,60), ("FIFTY FIFTY","문샤넬",60,50,50,75),
    ("FIFTY FIFTY","예원",55,55,55,65), ("FIFTY FIFTY","하나",65,75,65,55),

    # === MEOVV ===
    ("MEOVV","수인",60,70,65,55), ("MEOVV","가원",40,60,65,70),
    ("MEOVV","안나",75,65,60,55), ("MEOVV","나린",60,65,60,60),
    ("MEOVV","엘라",60,60,55,55),

    # === tripleS ===
    ("tripleS","김채연",60,55,75,55),
    ("tripleS","김유연",70,35,60,40), ("tripleS","김나경",65,65,60,60),
    ("tripleS","신위",70,55,65,60), ("tripleS","이지우",65,65,70,65),

    # === Kep1er ===
    ("Kep1er","최유진",55,60,60,60), ("Kep1er","샤오팅",65,70,65,50),
    ("Kep1er","김채현",60,65,60,70), ("Kep1er","김다연",55,75,55,55),
    ("Kep1er","휴닝바히에",50,55,60,55),

    # === QWER ===
    ("QWER","마젠타",50,40,60,35), ("QWER","쵸단",65,50,65,45),
    ("QWER","시연",55,55,60,70),    ("QWER","히나",55,45,60,40),

    # === RESCENE ===
    ("RESCENE","원이",65,55,60,60), ("RESCENE","리브",60,60,60,55),
    ("RESCENE","미나미",50,65,55,70), ("RESCENE","메이",60,55,55,55),
    ("RESCENE","제나",60,55,65,55),

    # === LIGHTSUM ===
    ("LIGHTSUM","상아",55,55,55,55), ("LIGHTSUM","초원",55,60,80,75),
    ("LIGHTSUM","나영",60,65,60,70), ("LIGHTSUM","히나",60,50,50,45),
    ("LIGHTSUM","주현",55,70,60,60), ("LIGHTSUM","유정",55,55,55,55),

    # === izna ===
    ("izna","코코",60,70,60,50), ("izna","마이",50,55,55,50),
    ("izna","윤지윤",55,55,60,60), ("izna","유사랑",65,65,60,55),
    ("izna","방지민",60,65,60,55), ("izna","정세비",65,65,70,55),

    # === OH MY GIRL ===
    ("OHMYGIRL","효정",50,55,60,60), ("OHMYGIRL","미미",40,70,55,55),
    ("OHMYGIRL","유아",65,75,50,55), ("OHMYGIRL","승희",50,60,55,60),
    ("OHMYGIRL","아린",65,55,70,55),

    # === ARTMS ===
    ("ARTMS","진솔",55,60,60,50), ("ARTMS","하슬",50,50,50,65),
    ("ARTMS","김립",55,60,60,60), ("ARTMS","희진",70,65,60,55),
    ("ARTMS","최리",60,60,55,50),

    # === PURPLE KISS ===
    ("PURPLEKISS","고은",55,50,50,65), ("PURPLEKISS","도시",50,65,55,45),
    ("PURPLEKISS","유키",55,60,50,45), ("PURPLEKISS","채인",55,60,55,60),

    # === EVERGLOW ===
    ("EVERGLOW","EU",55,60,60,45), ("EVERGLOW","시현",60,55,60,60),
    ("EVERGLOW","미아",55,60,60,60), ("EVERGLOW","아이샤",55,55,60,45),
    ("EVERGLOW","이런",70,55,55,50),

    # === Dreamcatcher ===
    ("Dreamcatcher","지유",65,55,60,55), ("Dreamcatcher","수아",50,65,60,50),
    ("Dreamcatcher","시연",50,50,50,70), ("Dreamcatcher","유현",50,50,50,65),
    ("Dreamcatcher","다미",45,60,60,45),

    # === Weeekly ===
    ("Weeekly","수진",50,55,50,55), ("Weeekly","소은",55,50,50,60),
    ("Weeekly","재희",65,50,50,45), ("Weeekly","지한",65,60,55,65),
    ("Weeekly","조아",55,50,50,45),

    # === BDC ===
    ("BDC","이현",65,65,65,65), ("BDC","쿠미",60,60,60,50),
    ("BDC","미아",55,60,55,60), ("BDC","베니",45,70,60,50),
]

# ───────────────  함수 영역  ───────────────
def lin_map(x,x0=20,x1=80,y0=0,y1=1):
    return y0 + (x-x0)*(y1-y0)/(x1-x0)

def jitter(val,pct=0.3):
    return val * random.uniform(1-pct, 1+pct)

def sim_season(rows, pa=650, seed=None):
    if seed is not None: random.seed(seed)
    out=[]
    for team,pl,c,g,h,e in rows:
        # 비율 계산
        avg = jitter(lin_map(c,y0=.200,y1=.330))
        bb  = jitter(lin_map(e,y0=.04 ,y1=.15))
        hr  = jitter(lin_map(h,y0=.005,y1=.06))
        db  = jitter(lin_map(g,y0=.03 ,y1=.09))
        tp  = jitter(lin_map(g,y0=.002,y1=.010))

        BB=int(bb*pa); AB=pa-BB
        HR=int(hr*AB); DB=int(db*AB); TP=int(tp*AB)
        H = int(avg*AB); S=max(0,H-DB-TP-HR)
        TB=S + 2*DB + 3*TP + 4*HR
        OBP=(H+BB)/pa; SLG=TB/AB

        wRC=int(((1.2*(H+BB)/pa)/.330 + (0.8*TB/AB)/.370 - 1)*100)
        WAR=round((wRC-100)/10*pa/650,1)

        out.append((team,pl,round(H/AB,3),round(OBP,3),
                    round(SLG,3),wRC,WAR))
    return sorted(out,key=lambda x:x[5],reverse=True)

# ───────────────  인터페이스  ───────────────
TEAMS=sorted({t for t,_,*__ in RAW})
print("가능 팀:",", ".join(TEAMS))
t1=input("첫 번째 팀: ").strip()
t2=input("두 번째 팀: ").strip()
if t1 not in TEAMS or t2 not in TEAMS or t1==t2:
    raise ValueError("팀 이름을 확인하세요!")

rows=[r for r in RAW if r[0] in (t1,t2)]
res = sim_season(rows, seed=None)

# ───────────────  출력  ───────────────
POINT = [25,18,15,12,10,8,6,4,2,1]                 # 순위 포인트
score = Counter({t1:0, t2:0})

# ① 플레이어별 포인트 매핑 ---------------------------------
pts_map = {row[1]: 0 for row in res}        # 기본 0
for idx, (_, pl, *_) in enumerate(res[:len(POINT)]):
    pts_map[pl] = POINT[idx]                # 상위 6명만 부여
    score[res[idx][0]] += POINT[idx]

# ② 트랙 레코드(기준 랩) & 랩 타임 계산 ----------------------
leader_war = res[0][6]

#   ▸ “WAR 6 = 1:28.000” 을 기준으로,
#     WAR 1 증가마다 1.5초 빨라지도록(원하면 조정)
BASE_RECORD_SEC = 88.000 - (leader_war - 6.0)*1.5
if BASE_RECORD_SEC < 70:            # 너무 비현실적이면 하한선
    BASE_RECORD_SEC = 70.000

SCALE = 1.0                         # 1 WAR 차이 → 1.000초

def as_time(sec: float) -> str:     # 90.123 → "1:30.123"
    m, s = divmod(sec, 60)
    return f"{int(m)}:{s:06.3f}"

print("\nTeam       Player       LAP      Δ      PTS")
print("-"*54)

for team, pl, avg, obp, slg, wrc, war in res:
    gap_sec   = (leader_war - war) * SCALE
    lap_time  = BASE_RECORD_SEC + gap_sec
    delta_str = "   ---" if gap_sec == 0 else f"+{gap_sec:6.3f}"
    print(f"{team:10} {pl:12} {as_time(lap_time):>7} {delta_str}  {pts_map[pl]:>3}")

# ③ 팀 합계 출력 -------------------------------------------
print("\n팀 포인트:")
print(f"{t1}: {score[t1]} 점")
print(f"{t2}: {score[t2]} 점")
winner = "무승부" if score[t1]==score[t2] else (t1 if score[t1]>score[t2] else t2)
print("→ 승리 팀:", winner)

Embed on website

To embed this project on your website, copy the following code and paste it into your website's HTML: