After the above proposal I have decided to write up a clear outline of some tournament structures and their differences.
Now, let's explore some alternative systems:
Award points based on the logarithm of the player's daily rank:
1st: 10 points
2nd: 7 points
3rd: 5 points
4th: 4 points
5th: 3 points
6th-10th: 2 points
The total points available each day are fixed (let's say 20 points), but they're distributed based on the spread of scores:
If scores are close (within 10% of each other), points are distributed more evenly (e.g., 6-5-4-3-2)
If there's a clear winner (>20% ahead of second place), more points go to the top (e.g., 10-5-3-2-0)
Here's an example dynamic point allocation formula implemented in python:
import numpy as np def calculate_points(scores, total_points=20, min_points=1): n = len(scores) sorted_scores = sorted(scores, reverse=True) # Calculate the spread factor max_score = max(scores) min_score = min(scores) spread_factor = (max_score - min_score) / max_score if max_score > 0 else 0 # Calculate base points base_points = np.linspace(total_points, min_points, n) # Apply spread factor to create more separation when scores are spread out adjusted_points = base_points ** (1 + spread_factor) # Normalize to ensure total points sum to the desired total normalized_points = (adjusted_points / adjusted_points.sum()) * total_points # Round points to integers final_points = np.round(normalized_points).astype(int) # Adjust to ensure we hit exactly total_points while final_points.sum() != total_points: if final_points.sum() < total_points: final_points[np.argmax(normalized_points - final_points)] += 1 else: final_points[np.argmin(normalized_points - final_points)] -= 1 return dict(zip(sorted_scores, final_points)) # Example usage daily_scores = [8150, 6500, 5500, 5150, 5100, 4500, 4250, 3850, 3500, 3250] point_allocation = calculate_points(daily_scores) for score, points in point_allocation.items(): print(f"Score: {score}, Points: {points}")