Skip to content

Commit ac7965b

Browse files
committed
Finish top200 tournament
1 parent 204eada commit ac7965b

File tree

4 files changed

+860
-315
lines changed

4 files changed

+860
-315
lines changed

services/app/apps/codebattle/lib/codebattle/game/engine.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -407,15 +407,15 @@ defmodule Codebattle.Game.Engine do
407407
case {old_game_state, new_game.state} do
408408
{old_state, "timeout"}
409409
when old_state in ["waiting_opponent", "playing"] ->
410-
Codebattle.PubSub.broadcast("game:finished", %{game: new_game})
411-
412410
update_game!(new_game, %{
413411
state: get_state(new_game),
414412
players: get_game_players(new_game),
415413
duration_sec: new_game.duration_sec,
416414
finishes_at: new_game.finishes_at
417415
})
418416

417+
Codebattle.PubSub.broadcast("game:finished", %{game: new_game})
418+
419419
if game.tournament_id do
420420
terminate_game_after(game, 1)
421421
else

services/app/apps/codebattle/lib/codebattle/tournament/strategy/top200.ex

Lines changed: 15 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@ defmodule Codebattle.Tournament.Top200 do
88
@impl Tournament.Base
99
def complete_players(tournament) do
1010
# just for the UI test
11-
users =
12-
Codebattle.User
13-
|> Codebattle.Repo.all()
14-
|> Enum.filter(&(&1.is_bot == false and &1.subscription_type != :admin))
15-
|> Enum.take(199)
16-
17-
add_players(tournament, %{users: users})
18-
# tournament
11+
# users =
12+
# Codebattle.User
13+
# |> Codebattle.Repo.all()
14+
# |> Enum.filter(&(&1.is_bot == false and &1.subscription_type != :admin))
15+
# |> Enum.take(199)
16+
17+
# add_players(tournament, %{users: users})
18+
tournament
1919
end
2020

2121
@impl Tournament.Base
@@ -221,7 +221,7 @@ defmodule Codebattle.Tournament.Top200 do
221221
total_ranking = TournamentResult.get_user_ranking(tournament)
222222

223223
# Get winners from first 8 matches
224-
top_match_winner_ids =
224+
top_8_winner_ids =
225225
tournament
226226
|> get_round_matches(3)
227227
|> Enum.sort_by(& &1.id)
@@ -232,16 +232,7 @@ defmodule Codebattle.Tournament.Top200 do
232232
(get_in(ranking, [p1_id, :score]) >= get_in(ranking, [p2_id, :score]) && p1_id) || p2_id
233233
end)
234234

235-
# Take top 8 winners based on ranking
236-
top_8_winner_ids =
237-
ranking
238-
|> Map.values()
239-
|> Enum.filter(&(&1.id in top_match_winner_ids))
240-
|> Enum.sort_by(&{-&1.score, &1.id})
241-
|> Enum.map(& &1.id)
242-
|> Enum.take(8)
243-
244-
# Pick top 6 from the 8 winners
235+
# Take top 6 winners based on ranking
245236
top_6_winner_ids =
246237
ranking
247238
|> Map.values()
@@ -250,23 +241,22 @@ defmodule Codebattle.Tournament.Top200 do
250241
|> Enum.map(& &1.id)
251242
|> Enum.take(6)
252243

253-
# Get all remaining players
254-
remaining_ids = ranking |> Map.values() |> Enum.map(& &1.id) |> Kernel.--(top_8_winner_ids)
255-
256244
# Pick top 2 from remaining players
257245
top_2_remaining_ids =
258246
total_ranking
259-
|> Map.values()
260-
|> Enum.filter(&(&1.id in remaining_ids))
247+
|> Enum.filter(&(&1.id not in top_6_winner_ids))
261248
|> Enum.sort_by(&{-&1.score, &1.id})
262249
|> Enum.map(& &1.id)
263250
|> Enum.take(2)
264251

265252
# Combine top 6 winners with top 2 remaining players
266253
top_8_ids = top_6_winner_ids ++ top_2_remaining_ids
267254

255+
# Get all remaining players
256+
remaining_ids = ranking |> Map.values() |> Enum.map(& &1.id) |> Kernel.--(top_8_ids)
257+
268258
# Create 4 pairs from top 8 players
269-
top_pair_ids = Enum.chunk_every(Enum.shuffle(top_8_ids), 2)
259+
top_pair_ids = top_8_ids |> Enum.shuffle() |> Enum.chunk_every(2)
270260

271261
# Shuffle and pair the rest of the players
272262
remaining_pair_ids = remaining_ids |> Enum.shuffle() |> Enum.chunk_every(2)

services/app/apps/codebattle/lib/codebattle/tournament/tournament_result.ex

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -94,16 +94,16 @@ defmodule Codebattle.Tournament.TournamentResult do
9494
g.id as game_id,
9595
g.round_position,
9696
g.was_cheated,
97-
dt.min_duration,
98-
dt.max_duration,
99-
dt.base_score,
97+
COALESCE(dt.base_score, 0) AS base_score,
98+
COALESCE(dt.min_duration, 0) AS min_duration,
99+
COALESCE(dt.max_duration, 0) AS max_duration,
100100
CASE
101101
-- Handle timeout case where both players lost
102102
WHEN g.state = 'timeout' THEN
103-
0.5 * dt.base_score * COALESCE((p.player_info->>'result_percent')::numeric, 0) / 100.0
103+
0.5 * COALESCE(dt.base_score, 0) * COALESCE((p.player_info->>'result_percent')::numeric, 0) / 100.0
104104
ELSE
105-
dt.base_score * (
106-
2 - ((g.duration_sec - dt.min_duration)::numeric / GREATEST(dt.max_duration - dt.min_duration, 1))
105+
COALESCE(dt.base_score, 0) * (
106+
2 - ((g.duration_sec - COALESCE(dt.min_duration, 0))::numeric / GREATEST(COALESCE(dt.max_duration - COALESCE(dt.min_duration, 0), 1), 1))
107107
) * COALESCE((p.player_info->>'result_percent')::numeric, 0) / 100.0
108108
END AS score,
109109
g.level,
@@ -112,7 +112,7 @@ defmodule Codebattle.Tournament.TournamentResult do
112112
from games g
113113
CROSS JOIN LATERAL
114114
jsonb_array_elements(g.players) AS p(player_info)
115-
inner join duration_percentile_for_tasks dt
115+
left join duration_percentile_for_tasks dt
116116
on dt.task_id = g.task_id
117117
where g.tournament_id = #{tournament.id}
118118
and state in ('game_over', 'timeout')

0 commit comments

Comments
 (0)