Files
game-marathon/backend/app/services/points.py

97 lines
2.6 KiB
Python
Raw Normal View History

2025-12-15 03:22:29 +07:00
from app.models import Event, EventType
2025-12-14 02:38:35 +07:00
class PointsService:
"""Service for calculating points and penalties"""
STREAK_MULTIPLIERS = {
0: 0.0,
1: 0.0,
2: 0.1,
3: 0.2,
4: 0.3,
}
MAX_STREAK_MULTIPLIER = 0.4
DROP_PENALTIES = {
0: 0, # First drop is free
1: 10,
2: 25,
}
MAX_DROP_PENALTY = 50
2025-12-15 03:22:29 +07:00
# Event point multipliers
EVENT_MULTIPLIERS = {
EventType.GOLDEN_HOUR.value: 1.5,
EventType.DOUBLE_RISK.value: 0.5,
EventType.JACKPOT.value: 3.0,
2025-12-15 23:50:37 +07:00
# GAME_CHOICE uses 1.0 multiplier (default)
2025-12-15 03:22:29 +07:00
}
2025-12-14 02:38:35 +07:00
def calculate_completion_points(
self,
base_points: int,
2025-12-15 03:22:29 +07:00
current_streak: int,
event: Event | None = None,
) -> tuple[int, int, int]:
2025-12-14 02:38:35 +07:00
"""
Calculate points earned for completing a challenge.
Args:
base_points: Base points for the challenge
current_streak: Current streak before this completion
2025-12-15 03:22:29 +07:00
event: Active event (optional)
2025-12-14 02:38:35 +07:00
Returns:
2025-12-15 03:22:29 +07:00
Tuple of (total_points, streak_bonus, event_bonus)
2025-12-14 02:38:35 +07:00
"""
2025-12-15 03:22:29 +07:00
# Apply event multiplier first
event_multiplier = 1.0
if event:
event_multiplier = self.EVENT_MULTIPLIERS.get(event.type, 1.0)
adjusted_base = int(base_points * event_multiplier)
event_bonus = adjusted_base - base_points
# Then apply streak bonus
streak_multiplier = self.STREAK_MULTIPLIERS.get(
2025-12-14 02:38:35 +07:00
current_streak,
self.MAX_STREAK_MULTIPLIER
)
2025-12-15 03:22:29 +07:00
streak_bonus = int(adjusted_base * streak_multiplier)
2025-12-14 02:38:35 +07:00
2025-12-15 03:22:29 +07:00
total_points = adjusted_base + streak_bonus
return total_points, streak_bonus, event_bonus
def calculate_drop_penalty(
self,
consecutive_drops: int,
event: Event | None = None
) -> int:
2025-12-14 02:38:35 +07:00
"""
Calculate penalty for dropping a challenge.
Args:
consecutive_drops: Number of drops since last completion
2025-12-15 03:22:29 +07:00
event: Active event (optional)
2025-12-14 02:38:35 +07:00
Returns:
Penalty points to subtract
"""
2025-12-15 03:22:29 +07:00
# Double risk event = free drops
if event and event.type == EventType.DOUBLE_RISK.value:
return 0
2025-12-14 02:38:35 +07:00
return self.DROP_PENALTIES.get(
consecutive_drops,
self.MAX_DROP_PENALTY
)
2025-12-15 03:22:29 +07:00
def apply_event_multiplier(self, base_points: int, event: Event | None) -> int:
"""Apply event multiplier to points"""
if not event:
return base_points
multiplier = self.EVENT_MULTIPLIERS.get(event.type, 1.0)
return int(base_points * multiplier)