Skip to content

Commit 3d6ecfd

Browse files
VitalyVitaly
authored andcommitted
Add seasons generator
1 parent 3441e9d commit 3d6ecfd

24 files changed

+1528
-425
lines changed

docs/001_product_review.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
Codebattle: Competitive Programming Game
2+
3+
Codebattle (codebattle.hexlet.io) is a real‑time coding duel platform. Two players solve the same task in parallel; whoever solves it first wins the match.
4+
5+
The platform hosts Swiss‑system tournaments across several grades with a seasonal ranking model inspired by tennis.
6+
7+
Key Concepts
8+
9+
Match (Duel): 1v1, same task, first correct solution wins; otherwise ends by timeout.
10+
11+
Tournament (Swiss): Multiple rounds; in each round, players are paired vs players with similar cumulative score; no repeat pairings (unless unavoidable on round 1 bootstrap or via bot fill‑ins).
12+
13+
Tournament grades: open, rookie, challenger, pro, elite, masters, grand_slam — determine prestige, task pools, points, schedules, and limits.
14+
15+
Seasons: Four per year aligned to equinoxes/solstices. Season points reset each season; lifetime Elo never resets.
16+
17+
Languages: 16 supported — clojure, cpp, csharp, dart, elixir, golang, haskell, java, js, kotlin, php, python, ruby, rust, swift, ts.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
Tournament Gameplay & Matches
2+
3+
Joining
4+
5+
Players may late‑join any Swiss tournament while it is active. They enter with 0 tournament points and are scheduled into the next round.
6+
7+
Minimum participants to start: 2 for any grade.
8+
9+
Time Controls
10+
11+
Tournament uses a single round timeout: round_timeout_seconds (applied to all matches in the round). Organizers may set different values per tournament and (optionally) per task difficulty in future.
12+
13+
Outcomes
14+
15+
Win: First accepted solution (100% tests) within timeout.
16+
17+
Timeout: No accepted solution when time expires. Treated as non‑draw for scoring: both receive a partial score (see 75‑percentile scoring), but Elo is not updated for timeout games.
18+
19+
Cheating reports: If cheating is confirmed against your opponent, your match score is recalculated according to anti‑cheat policy (see docs/08-anti-cheat.md).
20+
21+
Languages & Environment
22+
23+
Supported languages: clojure, cpp, csharp, dart, elixir, golang, haskell, java, js, kotlin, php, python, ruby, rust, swift, ts.
24+
25+
Same task for both players in the match.

docs/003_swiss_tournament.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
Swiss Tournaments
2+
3+
Pairing
4+
5+
Round 1: random mixed seeding (shuffled), pair by adjacent order.
6+
7+
Subsequent rounds: sort by current tournament score (desc); pair within bands; no repeat pairings (tracked set). If odd participants, a bot fills the last unmatched player.
8+
9+
10+
These are platform defaults and can be configured if needed.
11+
12+
One Task per Round
13+
14+
Every round features one task shared by all matches.
15+
16+
In‑Tournament Scoring (Score Strategy)
17+
18+
Default strategy: 75_percentile (a.k.a. "percentile‑based"):
19+
20+
For each task (round), compute base_score = 25th percentile of winners' duration_sec (faster → smaller time).
21+
22+
Winner scaling: winners get between 2× and 1× base_score linearly, mapping min winner time → 2×, max winner time → 1×.
23+
24+
Losers/partials: scale by result_percent/100 and by the same linear time factor. For pure timeout games, grant 0.5 × base_score × (result_percent/100).
25+
26+
The tournament table sums per‑round scores.
27+
28+
Tournament Table & Tie‑Breakers
29+
30+
Sorted by Total Score (desc).
31+
32+
Tie‑break: Total Duration (asc).
33+
34+
Finals & Places
35+
36+
Final places are taken from the sorted table after the last round.

docs/004-seasons-and-points.md

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
Seasons, Grades, Points
2+
3+
Seasons
4+
5+
Season 0: Sep 21 – Dec 21
6+
Season 1: Dec 21 – Mar 21
7+
Season 2: Mar 21 – Jun 21
8+
Season 3: Jun 21 – Sep 21
9+
10+
On each season end date (the 21st), we run a Grand Slam at 16:00 UTC.
11+
12+
Season Points reset each season.
13+
14+
Elo never resets (lifetime).
15+
16+
Grades
17+
18+
open — casual/unranked (no points; free task setups by users).
19+
20+
rookie — once per 4 hours (except 16:00 UTC);
21+
should be 3 7 11 15 19 23 UTC
22+
easy tasks;
23+
grind‑friendly.
24+
25+
challenger — daily 16:00 UTC; backbone of the calendar.
26+
27+
pro — weekly Tuesday 16:00 UTC (preempted by higher grades in its week).
28+
29+
elite — bi‑weekly Wednesday 16:00 UTC (no pro that week).
30+
31+
masters — monthly Thursday 16:00 UTC (no pro/elite that week). Exactly one per day.
32+
33+
grand_slam — season finale on the 21st at 16:00 UTC (no pro/elite/masters that week).
34+
35+
Player Limits(players_limit)
36+
37+
rookie: 8
38+
challenger: 16
39+
pro: 32
40+
elite: 64
41+
masters: 128
42+
grand_slam: 256
43+
44+
Rounds per Grade (rounds_limit)
45+
46+
rookie: 4 rounds
47+
challenger: 6 rounds
48+
pro: 8 rounds
49+
elite: 10 rounds
50+
masters: 12 rounds
51+
grand_slam: 14 rounds
52+
53+
54+
Task Provisioning
55+
56+
For masters & grand_slam: use task packs (task_provider: task_pack).
57+
58+
Naming: masters_s{season}_{year}_{N} (e.g., masters_s0_2025_1), grand_slam_s{season}_{year}.
59+
60+
For others: use existing tasks via task_provider: level, task_strategy: random.
61+
62+
Swiss always uses one task per round.
63+
64+
Season Points Distribution
65+
66+
For each finished tournament (grade ≠ open), we award Season Points by final place using these grade tables; all remaining participants (outside prize slots) receive 2 points each.
67+
68+
rookie: [8, 4, 2] (top‑3)
69+
70+
challenger: [64, 32, 16, 8, 4, 2] (top‑6)
71+
72+
pro: [128, 64, 32, 16, 8, 4, 2] (top‑7)
73+
74+
elite: [256, 128, 64, 32, 16, 8, 4, 2] (top‑8)
75+
76+
masters: [1024, 512, 256, 128, 64, 32, 16, 8, 4, 2] (top‑10)
77+
78+
grand_slam: [2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2] (top‑11)
79+
80+
Prize points are not added on top of the participation points.
81+
82+
Season Leaderboard Tie‑Breakers
83+
84+
Total Season Points (desc)
85+
86+
Tournament wins in season (desc)
87+
88+
Tournament participations in season (desc)
89+
90+
Hall of Fame
91+
92+
Maintain a HoF for Season Champions and Grand Slam Champions (participants page optional later).

docs/005_elo_rating.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
Elo Rating (Lifetime)
2+
3+
Initial rating: 1200 for new players.
4+
5+
Updates only for: tournament matches in graded events (rookie..grand_slam) vs human opponents.
6+
7+
No Elo change on:
8+
- Matches involving a bot.
9+
- Timeout games.
10+
- Any open (casual) tournaments.
11+
12+
K‑Factors by Grade
13+
14+
rookie: 2
15+
challenger: 2
16+
pro: 4
17+
elite: 4
18+
masters: 8
19+
grand_slam: 16
20+
21+
Expected score is computed in the standard Elo way; winners and losers updated with their grade’s task level K.
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
Tournament Scheduling & Preemption
2+
3+
Daily/Hourly Rules (UTC)
4+
5+
Rookie: every hour except 16:00.
6+
7+
Challenger: daily at 16:00, unless preempted by a higher grade that day/week.
8+
9+
Weekly Slots (16:00 UTC)
10+
11+
Priority: grand_slam > masters > elite > pro.
12+
13+
In any given week, exactly one of pro/elite/masters/grand_slam runs at 16:00.
14+
15+
Canonical Weekly Pattern (per 12–13‑week season)
16+
17+
Weeks without special events alternate pro and elite as backbone, with masters approximately once per month (Thu). Example outline:
18+
19+
w1 Tue: pro
20+
w2 Wed: elite
21+
w3 Tue: pro
22+
w4 Thu: masters
23+
w5 Tue: pro
24+
w6 Wed: elite
25+
w7 Tue: pro
26+
w8 Thu: masters
27+
w9 Tue: pro
28+
w10 Wed: elite
29+
w11 Tue: pro
30+
w12 21st: grand_slam
31+
w13 Tue: pro (if present within season window)
32+
33+
Exact weekdays for masters/grand_slam follow the 21st constraint and season calendar; if a masters week is selected, no pro/elite that week. On a grand_slam week, only grand_slam at 16:00.
34+
35+
Deterministic Planner (Pseudo‑code)
36+
37+
input: season_start, season_end
38+
for each day in [season_start, season_end]:
39+
if hour==16:00:
40+
if date == season_end (21st): schedule grand_slam
41+
else if is_thursday and is_monthly_slot and not special_week: schedule masters
42+
else if is_wednesday and is_biweekly_slot and not masters_week: schedule elite
43+
else if is_tuesday and not elite_week and not masters_week: schedule pro
44+
else: schedule challenger
45+
else:
46+
if hour != 16:00: schedule rookie hourly
47+
48+
biweekly_slot can be tracked as every second Wednesday in the season window.
49+
50+
monthly_slot for masters is the nearest Thursday not colliding with GS.
51+
52+
Preemption means the higher‑priority grade replaces challenger that day and replaces lower grades in that week as per rules.

docs/007-hall-of-fame.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Hall of Fame
2+
3+
Display Season Champions (by Season Points rank 1 for S0..S3).
4+
5+
Display Grand Slam Champions (winners of the Grand Slam for each season).
6+
7+
Optional future addition: Grand Slam participants board.
8+
9+
Data sources:
10+
11+
Season leaderboard snapshot at season end.
12+
13+
tournament_places for the corresponding grand_slam event.

docs/008-anti-cheat.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Anti‑Cheat & Dispute Resolution (MVP)
2+
3+
Players can report suspected cheating.
4+
5+
Admins review evidence; if cheating is confirmed:
6+
7+
Offending player’s match result may be voided/banned per policy.
8+
9+
The victim’s tournament score for the game is recalculated to a fair value (e.g., set to the average winners' score for that task or a policy‑defined replacement).
10+
11+
Admin actions may update tournament_results.was_cheated and trigger a recompute of tournament aggregates/places.
12+
13+
Elo is not granted for bot games or timeouts; cheating cases follow the same Elo exclusions until a fair game result exists.

services/app/apps/codebattle/assets/js/widgets/components/icons/grades/RookieIcon.jsx

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,33 @@ const COLOR = '#00FF00'; // Неоново-зелёный (Neon-green)
55
const RookieIcon = ({ size = '48px' }) => (
66
<div className="rank-icon-container">
77
<svg
8-
className="rank-svg-icon flicker-animation"
8+
className="rank-svg-icon"
99
width={size}
1010
height={size}
1111
viewBox="0 0 100 100"
1212
xmlns="http://www.w3.org/2000/svg"
1313
style={{ filter: `drop-shadow(0 0 3px ${COLOR})` }}
1414
>
1515
{/* Floppy Disk/Terminal Cursor Symbol */}
16-
<rect x="25" y="25" width="50" height="50" rx="5" fill="none" stroke={COLOR} strokeWidth="4" />
17-
<rect x="35" y="45" width="30" height="15" fill="#000" stroke={COLOR} strokeWidth="2" />
16+
<rect
17+
x="25"
18+
y="25"
19+
width="50"
20+
height="50"
21+
rx="5"
22+
fill="none"
23+
stroke={COLOR}
24+
strokeWidth="4"
25+
/>
26+
<rect
27+
x="35"
28+
y="45"
29+
width="30"
30+
height="15"
31+
fill="#000"
32+
stroke={COLOR}
33+
strokeWidth="2"
34+
/>
1835
<rect x="40" y="30" width="20" height="10" fill={COLOR} />
1936
</svg>
2037
</div>

0 commit comments

Comments
 (0)