44 lines
1.3 KiB
Python
44 lines
1.3 KiB
Python
"""比賽環境衰減模型(高海拔與高溫)。"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import math
|
||
|
||
|
||
def adjust_team_strength_for_environment(
|
||
base_strength: float,
|
||
venue_altitude: float,
|
||
venue_heat_index: float,
|
||
is_second_half: bool,
|
||
team_acclimatized: bool,
|
||
) -> float:
|
||
"""調整球隊能力值,反映環境壓力。
|
||
|
||
- 海拔 > 1500m 且球隊未適應,第二節時套用疲勞衰退。
|
||
- 熱指數(Heat Index)越高,衰退越明顯。
|
||
"""
|
||
|
||
if base_strength < 0:
|
||
raise ValueError('base_strength 必須大於等於 0')
|
||
|
||
adjusted = float(base_strength)
|
||
if not is_second_half:
|
||
return adjusted
|
||
|
||
altitude_penalty = 0.0
|
||
heat_penalty = 0.0
|
||
|
||
if not team_acclimatized and venue_altitude >= 1500:
|
||
# 以對數遞增,1500m 為轉折,3000m 接近上限。
|
||
altitude_factor = math.log1p((venue_altitude - 1500.0) / 300.0)
|
||
altitude_penalty = 0.025 + 0.045 * min(altitude_factor, 2.8)
|
||
|
||
# 熱指數高於 30,逐步加入疲勞因子,超過 38 非常明顯。
|
||
if venue_heat_index > 30:
|
||
heat_excess = min(max(venue_heat_index - 30.0, 0.0), 30.0)
|
||
heat_penalty = 0.0012 * heat_excess
|
||
|
||
total_penalty = altitude_penalty + heat_penalty
|
||
adjusted *= max(0.2, 1.0 - total_penalty)
|
||
return adjusted
|