Change points balance
This commit is contained in:
@@ -182,7 +182,7 @@ async def spin_wheel(marathon_id: int, current_user: CurrentUser, db: DbSession)
|
|||||||
await db.refresh(assignment)
|
await db.refresh(assignment)
|
||||||
|
|
||||||
# Calculate drop penalty (considers active event for double_risk)
|
# Calculate drop penalty (considers active event for double_risk)
|
||||||
drop_penalty = points_service.calculate_drop_penalty(participant.drop_count, active_event)
|
drop_penalty = points_service.calculate_drop_penalty(participant.drop_count, challenge.points, active_event)
|
||||||
|
|
||||||
# Get challenges count (avoid lazy loading in async context)
|
# Get challenges count (avoid lazy loading in async context)
|
||||||
challenges_count = 0
|
challenges_count = 0
|
||||||
@@ -238,7 +238,7 @@ async def get_current_assignment(marathon_id: int, current_user: CurrentUser, db
|
|||||||
|
|
||||||
# Calculate drop penalty (considers active event for double_risk)
|
# Calculate drop penalty (considers active event for double_risk)
|
||||||
active_event = await event_service.get_active_event(db, marathon_id)
|
active_event = await event_service.get_active_event(db, marathon_id)
|
||||||
drop_penalty = points_service.calculate_drop_penalty(participant.drop_count, active_event)
|
drop_penalty = points_service.calculate_drop_penalty(participant.drop_count, challenge.points, active_event)
|
||||||
|
|
||||||
return AssignmentResponse(
|
return AssignmentResponse(
|
||||||
id=assignment.id,
|
id=assignment.id,
|
||||||
@@ -496,7 +496,7 @@ async def drop_assignment(assignment_id: int, current_user: CurrentUser, db: DbS
|
|||||||
active_event = await event_service.get_active_event(db, marathon_id)
|
active_event = await event_service.get_active_event(db, marathon_id)
|
||||||
|
|
||||||
# Calculate penalty (0 if double_risk event is active)
|
# Calculate penalty (0 if double_risk event is active)
|
||||||
penalty = points_service.calculate_drop_penalty(participant.drop_count, active_event)
|
penalty = points_service.calculate_drop_penalty(participant.drop_count, assignment.challenge.points, active_event)
|
||||||
|
|
||||||
# Update assignment
|
# Update assignment
|
||||||
assignment.status = AssignmentStatus.DROPPED.value
|
assignment.status = AssignmentStatus.DROPPED.value
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ class GPTService:
|
|||||||
- description: что нужно сделать на русском (1-2 предложения)
|
- description: что нужно сделать на русском (1-2 предложения)
|
||||||
- type: один из [completion, no_death, speedrun, collection, achievement, challenge_run]
|
- type: один из [completion, no_death, speedrun, collection, achievement, challenge_run]
|
||||||
- difficulty: easy/medium/hard
|
- difficulty: easy/medium/hard
|
||||||
- points: очки (easy: 30-50, medium: 60-100, hard: 120-200)
|
- points: очки (easy: 20-40, medium: 45-75, hard: 90-150)
|
||||||
- estimated_time: примерное время в минутах
|
- estimated_time: примерное время в минутах
|
||||||
- proof_type: screenshot/video/steam (что лучше подойдёт для проверки)
|
- proof_type: screenshot/video/steam (что лучше подойдёт для проверки)
|
||||||
- proof_hint: что должно быть на скриншоте/видео для подтверждения на русском
|
- proof_hint: что должно быть на скриншоте/видео для подтверждения на русском
|
||||||
@@ -77,10 +77,17 @@ class GPTService:
|
|||||||
if proof_type not in ["screenshot", "video", "steam"]:
|
if proof_type not in ["screenshot", "video", "steam"]:
|
||||||
proof_type = "screenshot"
|
proof_type = "screenshot"
|
||||||
|
|
||||||
# Validate points
|
# Validate points based on difficulty
|
||||||
points = ch.get("points", 50)
|
points = ch.get("points", 30)
|
||||||
if not isinstance(points, int) or points < 1:
|
if not isinstance(points, int) or points < 1:
|
||||||
points = 50
|
points = 30
|
||||||
|
# Clamp points to expected ranges
|
||||||
|
if difficulty == "easy":
|
||||||
|
points = max(20, min(40, points))
|
||||||
|
elif difficulty == "medium":
|
||||||
|
points = max(45, min(75, points))
|
||||||
|
elif difficulty == "hard":
|
||||||
|
points = max(90, min(150, points))
|
||||||
|
|
||||||
challenges.append(ChallengeGenerated(
|
challenges.append(ChallengeGenerated(
|
||||||
title=ch.get("title", "Unnamed Challenge")[:100],
|
title=ch.get("title", "Unnamed Challenge")[:100],
|
||||||
|
|||||||
@@ -13,12 +13,12 @@ class PointsService:
|
|||||||
}
|
}
|
||||||
MAX_STREAK_MULTIPLIER = 0.4
|
MAX_STREAK_MULTIPLIER = 0.4
|
||||||
|
|
||||||
DROP_PENALTIES = {
|
# Drop penalty as percentage of challenge points
|
||||||
0: 0, # First drop is free
|
DROP_PENALTY_PERCENTAGES = {
|
||||||
1: 10,
|
0: 0.5, # 1st drop: 50%
|
||||||
2: 25,
|
1: 0.75, # 2nd drop: 75%
|
||||||
}
|
}
|
||||||
MAX_DROP_PENALTY = 50
|
MAX_DROP_PENALTY_PERCENTAGE = 1.0 # 3rd+ drop: 100%
|
||||||
|
|
||||||
# Event point multipliers
|
# Event point multipliers
|
||||||
EVENT_MULTIPLIERS = {
|
EVENT_MULTIPLIERS = {
|
||||||
@@ -66,6 +66,7 @@ class PointsService:
|
|||||||
def calculate_drop_penalty(
|
def calculate_drop_penalty(
|
||||||
self,
|
self,
|
||||||
consecutive_drops: int,
|
consecutive_drops: int,
|
||||||
|
challenge_points: int,
|
||||||
event: Event | None = None
|
event: Event | None = None
|
||||||
) -> int:
|
) -> int:
|
||||||
"""
|
"""
|
||||||
@@ -73,6 +74,7 @@ class PointsService:
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
consecutive_drops: Number of drops since last completion
|
consecutive_drops: Number of drops since last completion
|
||||||
|
challenge_points: Base points of the challenge being dropped
|
||||||
event: Active event (optional)
|
event: Active event (optional)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@@ -82,10 +84,11 @@ class PointsService:
|
|||||||
if event and event.type == EventType.DOUBLE_RISK.value:
|
if event and event.type == EventType.DOUBLE_RISK.value:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
return self.DROP_PENALTIES.get(
|
penalty_percentage = self.DROP_PENALTY_PERCENTAGES.get(
|
||||||
consecutive_drops,
|
consecutive_drops,
|
||||||
self.MAX_DROP_PENALTY
|
self.MAX_DROP_PENALTY_PERCENTAGE
|
||||||
)
|
)
|
||||||
|
return int(challenge_points * penalty_percentage)
|
||||||
|
|
||||||
def apply_event_multiplier(self, base_points: int, event: Event | None) -> int:
|
def apply_event_multiplier(self, base_points: int, event: Event | None) -> int:
|
||||||
"""Apply event multiplier to points"""
|
"""Apply event multiplier to points"""
|
||||||
|
|||||||
Reference in New Issue
Block a user