Skip to content

Commit

Permalink
Call teifion's algo when not enough noobs
Browse files Browse the repository at this point in the history
More improvements
  • Loading branch information
jauggy committed Jun 25, 2024
1 parent 2cd66d9 commit 182e034
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 21 deletions.
9 changes: 5 additions & 4 deletions lib/teiserver/battle/balance/cheeky_switcher_smart.ex
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ defmodule Teiserver.Battle.Balance.CheekySwitcherSmart do
# Alias the types
alias Teiserver.Battle.BalanceLib
alias Teiserver.Battle.Balance.BalanceTypes, as: BT
import Teiserver.Helper.NumberHelper, only: [format: 1]

# @type algorithm_state :: %{
# teams: map,
Expand Down Expand Up @@ -158,7 +159,7 @@ defmodule Teiserver.Battle.Balance.CheekySwitcherSmart do
|> Enum.map(fn {group, _} ->
group.names
|> Enum.with_index()
|> Enum.map(fn {name, i} -> "#{name}[#{Enum.at(group.ratings, i)}]" end)
|> Enum.map(fn {name, i} -> "#{name}[#{format(Enum.at(group.ratings, i))}]" end)
end)
|> List.flatten()
|> Enum.join(",")
Expand All @@ -168,7 +169,7 @@ defmodule Teiserver.Battle.Balance.CheekySwitcherSmart do
|> Enum.map(fn {group, _} ->
group.names
|> Enum.with_index()
|> Enum.map(fn {name, i} -> "#{name}[#{Enum.at(group.ratings, i)}]" end)
|> Enum.map(fn {name, i} -> "#{name}[#{format(Enum.at(group.ratings, i))}]" end)
end)
|> List.flatten()
|> Enum.join(",")
Expand Down Expand Up @@ -429,11 +430,11 @@ defmodule Teiserver.Battle.Balance.CheekySwitcherSmart do

if next_group.count > 1 do
[
"Group picked #{names |> Enum.join(", ")} for team #{team_key}, adding #{group_rating} points for a new total of #{round(existing_team_rating + group_rating)}"
"Group picked #{names |> Enum.join(", ")} for team #{team_key}, adding #{format(group_rating)} points for a new total of #{round(existing_team_rating + group_rating)}"
]
else
[
"Picked #{Enum.at(names, 0)} for team #{team_key}, adding #{group_rating} points for a new total of #{round(existing_team_rating + group_rating)}"
"Picked #{Enum.at(names, 0)} for team #{team_key}, adding #{format(group_rating)} points for a new total of #{round(existing_team_rating + group_rating)}"
]
end
end
Expand Down
45 changes: 30 additions & 15 deletions lib/teiserver/battle/balance/split_one_chevs.ex
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ defmodule Teiserver.Battle.Balance.SplitOneChevs do
"""
alias Teiserver.Battle.Balance.SplitOneChevsTypes, as: ST
alias Teiserver.Battle.Balance.BalanceTypes, as: BT
import Teiserver.Helper.NumberHelper, only: [format: 1]

@splitter "---------------------------"

Expand All @@ -26,10 +27,34 @@ defmodule Teiserver.Battle.Balance.SplitOneChevs do
See split_one_chevs_internal_test.exs for sample input
"""
@spec perform([BT.expanded_group()], non_neg_integer(), list()) :: any()
def perform(expanded_group, team_count, _opts \\ []) do
members = flatten_members(expanded_group) |> sort_members()
%{teams: teams, logs: logs} = assign_teams(members, team_count)
standardise_result(teams, logs)
def perform(expanded_group, team_count, opts \\ []) do
if has_enough_noobs?(expanded_group) do
members = flatten_members(expanded_group) |> sort_members()
%{teams: teams, logs: logs} = assign_teams(members, team_count)
standardise_result(teams, logs)
else
# Not enough noobs; so call another balancer
result = Teiserver.Battle.Balance.LoserPicks.perform(expanded_group, team_count, opts)

new_logs =
["Not enough noobs; calling another balancer.", @splitter, result.logs]
|> List.flatten()

Map.put(result, :logs, new_logs)
end
end

@spec has_enough_noobs?([BT.expanded_group()]) :: bool()
def has_enough_noobs?(expanded_group) do
ranks =
Enum.map(expanded_group, fn x ->
Map.get(x, :ranks, [])
end)
|> List.flatten()

Enum.any?(ranks, fn x ->
x < 2
end)
end

@doc """
Expand Down Expand Up @@ -73,16 +98,6 @@ defmodule Teiserver.Battle.Balance.SplitOneChevs do
|> List.flatten()
end

defp round_number(rating_value) when is_float(rating_value) do
rating_value
|> Decimal.from_float()
|> Decimal.round(1)
end

defp round_number(rating_value) when is_integer(rating_value) do
rating_value
end

@doc """
Assigns teams using algorithm defined in moduledoc
See split_one_chevs_internal_test.exs for sample input
Expand All @@ -104,7 +119,7 @@ defmodule Teiserver.Battle.Balance.SplitOneChevs do
username = x.name

new_log =
"#{username} (#{round_number(x.rating)}, σ: #{round_number(x.uncertainty)}, Chev: #{x.rank + 1}) picked for Team #{picking_team.team_id}"
"#{username} (#{format(x.rating)}, σ: #{format(x.uncertainty)}, Chev: #{x.rank + 1}) picked for Team #{picking_team.team_id}"

%{
teams: [update_picking_team | get_non_picking_teams(acc.teams, picking_team)],
Expand Down
16 changes: 16 additions & 0 deletions lib/teiserver/helpers/number_helper.ex
Original file line number Diff line number Diff line change
Expand Up @@ -120,4 +120,20 @@ defmodule Teiserver.Helper.NumberHelper do
def percent(v, dp) do
round(v * 100, dp)
end

@doc """
Use this function for printing floats with only one decimal place.
Integers will be returned without modification.
If you need to always print the same amount of decimals no matter if float or integer,
then use the round function also defined in this module.
"""
def format(rating_value) when is_float(rating_value) do
rating_value
|> Decimal.from_float()
|> Decimal.round(1)
end

def format(rating_value) when is_integer(rating_value) do
rating_value
end
end
72 changes: 72 additions & 0 deletions test/teiserver/battle/split_one_chevs_internal_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -108,4 +108,76 @@ defmodule Teiserver.Battle.SplitOneChevsInternalTest do
%{members: [], team_id: 3}
]
end

test "has enough noobs" do
expanded_group = [
%{
count: 2,
members: ["Pro1", "Noob1"],
group_rating: 13,
ratings: [8, 5],
ranks: [1, 0],
names: ["Pro1", "Noob1"],
uncertainties: [0, 1]
},
%{
count: 1,
members: ["Noob2"],
group_rating: 6,
ratings: [6],
ranks: [0],
names: ["Noob2"],
uncertainties: [2]
},
%{
count: 1,
members: ["Noob3"],
group_rating: 7,
ratings: [17],
ranks: [0],
names: ["Noob3"],
uncertainties: [3]
}
]

result = SplitOneChevs.has_enough_noobs?(expanded_group)

assert result
end

test "not have enough noobs" do
expanded_group = [
%{
count: 2,
members: ["B", "A"],
group_rating: 13,
ratings: [8, 5],
ranks: [2, 2],
names: ["B", "A"],
uncertainties: [0, 1]
},
%{
count: 1,
members: ["C"],
group_rating: 6,
ratings: [6],
ranks: [2],
names: ["C"],
uncertainties: [2]
},
%{
count: 1,
members: ["D"],
group_rating: 7,
ratings: [17],
ranks: [2],
names: ["D"],
uncertainties: [3]
}
]

result = SplitOneChevs.has_enough_noobs?(expanded_group)

refute result
end
end
27 changes: 25 additions & 2 deletions test/teiserver/battle/split_one_chevs_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ defmodule Teiserver.Battle.SplitOneChevsTest do
algorithm: @split_algo
)

assert result.team_players == %{1 => [1, 5], 2 => [2, 6], 3 => [3, 4]}
assert result.team_players == %{1 => [5, 2], 2 => [6, 1], 3 => [4, 3]}
end

test "split one chevs simple group" do
Expand All @@ -83,7 +83,7 @@ defmodule Teiserver.Battle.SplitOneChevsTest do
algorithm: @split_algo
)

assert result.team_players == %{1 => [4, 1], 2 => [2, 3]}
assert result.team_players == %{1 => [1, 4], 2 => [2, 3]}
end

test "logs FFA" do
Expand Down Expand Up @@ -135,4 +135,27 @@ defmodule Teiserver.Battle.SplitOneChevsTest do
"Noob2 (8, σ: 8, Chev: 1) picked for Team 1"
]
end

test "calls another balancer when no noobs" do
result =
BalanceLib.create_balance(
[
%{"A" => %{rating: 5, rank: 2}},
%{"B" => %{rating: 6, rank: 2}},
%{"C" => %{rating: 7, rank: 2, uncertainty: 7.9}},
%{"D" => %{rating: 8, rank: 2, uncertainty: 8}}
],
2,
algorithm: @split_algo
)

assert result.logs == [
"Not enough noobs; calling another balancer.",
"---------------------------",
"Picked D for team 1, adding 8.0 points for new total of 8.0",
"Picked C for team 2, adding 7.0 points for new total of 7.0",
"Picked B for team 2, adding 6.0 points for new total of 13.0",
"Picked A for team 1, adding 5.0 points for new total of 13.0"
]
end
end

0 comments on commit 182e034

Please sign in to comment.