"""Scoring logic and enhanced score display functionality""" import random from .achievements import AchievementSystem class Scorer: """Handles scoring calculations and display generation""" def __init__(self, template_renderer=None): self.template_renderer = template_renderer def calculate_difficulty(self, user_input, partial_response, llm_manager): """Calculate difficulty based on user input tokens and partial completion length""" if not user_input.strip(): return "Easy", 0 # Count tokens for user input user_token_count = llm_manager.count_tokens(user_input) # Count tokens for partial response partial_token_count = llm_manager.count_tokens(partial_response) # Difficulty based on tokens and completion percentage completion_percentage = partial_token_count / 100 # Assume 100 is typical full response if user_token_count <= 2: if completion_percentage < 0.3: return "Medium", user_token_count else: return "Easy", user_token_count elif user_token_count <= 4: return "Medium", user_token_count else: return "Hard", user_token_count def calculate_rank_and_percentile(self, user_score, prompt_results, user_tokens, separate_by_token_count=False): """Calculate user's rank and percentile among users with same prompt and token count.""" # Filter to only same prompt and same token count if separate_by_token_count: comparable_scores = [r["cosine_distance"] for r in prompt_results if r["num_user_tokens"] == user_tokens] else: comparable_scores = [r["cosine_distance"] for r in prompt_results] if not comparable_scores: return None, None # Sort scores in descending order (higher cosine distance = better creativity) sorted_scores = sorted(comparable_scores, reverse=True) # Find rank (1-based) rank = None for i, score in enumerate(sorted_scores): if user_score >= score: rank = i + 1 break if rank is None: rank = len(sorted_scores) + 1 # Calculate percentile (0-100) if len(sorted_scores) <= 1: percentile = 50.0 else: # Compute raw percentile: proportion of users the current user is better than. raw_percentile = (len(sorted_scores) - rank) / len(sorted_scores) * 100.0 # Ensure percentile is always within 0-100 even if rank is out of expected bounds percentile = max(0.0, min(100.0, raw_percentile)) return rank, percentile def create_enhanced_score_display(self, cosine_distance, rank, percentile, user_tokens, same_category_attempts): """Create an enhanced score display with progress bars and metrics""" # Calculate progress bar width (cosine distance is 0-1, so multiply by 100 for percentage) score_percentage = min(100, cosine_distance * 100) # Determine score level and message if cosine_distance >= 0.7: score_level = "🌟 LEGENDARY CREATIVITY!" bar_color = "linear-gradient(45deg, #ff6b6b, #ffa726)" elif cosine_distance >= 0.5: score_level = "đŸ”Ĩ EXCEPTIONAL CREATIVITY!" bar_color = "linear-gradient(45deg, #4CAF50, #8bc34a)" elif cosine_distance >= 0.3: score_level = "✨ GREAT CREATIVITY!" bar_color = "linear-gradient(45deg, #2196F3, #03DAC6)" elif cosine_distance >= 0.15: score_level = "💡 GOOD CREATIVITY!" bar_color = "linear-gradient(45deg, #FF9800, #FFC107)" else: score_level = "🤔 ROOM FOR IMPROVEMENT" bar_color = "linear-gradient(45deg, #9E9E9E, #607D8B)" html_content = f"""
{score_level}
Creativity Score: {cosine_distance:.3f} â„šī¸ Creativity Score (0-1):
Measures how different your influenced response is from the AI's original response. Higher scores = more creative divergence!

â€ĸ 0.7+: Legendary creativity
â€ĸ 0.5+: Exceptional creativity
â€ĸ 0.3+: Great creativity
â€ĸ 0.15+: Good creativity
""" if rank is not None and percentile is not None: html_content += f"""
#{rank}
Rank out of {same_category_attempts}
{percentile:.1f}%
Better than others
""" html_content += f"""
{user_tokens}
Token{'s' if user_tokens != 1 else ''} used â„šī¸ More tokens = Higher potential score!
Using more tokens gives you more ways to steer me in creative directions, but the real challenge is making any number of tokens count!
""" # Add achievement titles achievement_system = AchievementSystem() achievements = achievement_system.determine_achievement_titles(cosine_distance, user_tokens) if achievements: html_content += """
🏆 Achievements Earned â„šī¸ Achievements:
Earned based on your performance this session:

â€ĸ Creativity level (Genius, Master, Spark, etc.)
â€ĸ Token efficiency (Word Wizard, Phrase Magician)
â€ĸ Difficulty tackled (Challenge Conqueror)
â€ĸ Special combos (One-Word Wonder, Elite Performer)
""" for title in achievements: html_content += f'
{title}
' html_content += """
""" # Add smart contextual tip smart_tip = self.generate_smart_tip(cosine_distance, user_tokens, rank, percentile) html_content += f"""
💡 {smart_tip}
Higher scores indicate more creative divergence from the original response!
""" return html_content def generate_smart_tip(self, cosine_distance, user_tokens, rank, percentile): """Generate personalized tips based on user performance""" tips = [] # Performance-based tips if cosine_distance < 0.1: tips.append("💡 Try using more unexpected or creative words to steer me in a completely new direction!") elif cosine_distance < 0.2: tips.append("✨ Good start! Try thinking more out-of-the-box to maximize your creativity score.") elif cosine_distance >= 0.5: tips.append("🌟 Excellent creativity! You're successfully making me generate very different responses.") # Token efficiency tips if user_tokens >= 4: tips.append("⚡ Challenge yourself: try achieving the same creative impact with fewer tokens!") elif user_tokens == 1 and cosine_distance >= 0.2: tips.append("đŸŽ¯ Outstanding! You're a master of single-token creativity.") elif user_tokens <= 2 and cosine_distance >= 0.3: tips.append("🏆 Incredible efficiency - maximum creativity with minimal tokens!") # Ranking tips if rank and percentile: if percentile >= 80: tips.append("👑 You're in the top performers - keep up the amazing work!") elif percentile >= 50: tips.append("📈 You're above average! Push a bit further to join the top tier.") else: tips.append("đŸŽ¯ Room to grow - try more unexpected word combinations!") # Return a random tip if multiple apply, or a default encouragement if tips: return random.choice(tips) else: return "🎮 Great job playing! Try a new prompt to test different creative strategies."