Skip to content

Commit

Permalink
Fix create balance when incomplete data (#315)
Browse files Browse the repository at this point in the history
* Fix create balance when incomplete data

* Update after geekingfrog review

Remove context

* Drop mock dependencies

---------

Co-authored-by: Dominik Stańczak-Marikin <[email protected]>
  • Loading branch information
jauggy and StanczakDominik authored Jun 9, 2024
1 parent c926fcc commit f49619c
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 2 deletions.
26 changes: 26 additions & 0 deletions lib/teiserver/battle/libs/balance_lib.ex
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ defmodule Teiserver.Battle.BalanceLib do

def create_balance(groups, team_count, opts) do
start_time = System.system_time(:microsecond)
groups = standardise_groups(groups)

# We perform all our group calculations here and assign each group
# an ID that's used purely for this run of balance
Expand Down Expand Up @@ -154,6 +155,23 @@ defmodule Teiserver.Battle.BalanceLib do
|> Map.put(:time_taken, System.system_time(:microsecond) - start_time)
end

@doc """
Sometimes groups have missing data so we need to refetch it.
If we go through balancer_server then all the required data should be there
"""
def standardise_groups(groups) do
groups
|> Enum.map(fn group ->
# Iterate over our map
Map.new(group, fn {user_id, value} ->
cond do
is_number(value) -> {user_id, get_user_rating_rank_old(user_id, value)}
true -> {user_id, value}
end
end)
end)
end

# Removes various keys we don't care about
defp cleanup_result(result) do
Map.take(
Expand Down Expand Up @@ -582,6 +600,14 @@ defmodule Teiserver.Battle.BalanceLib do
%{rating: rating, rank: rank, name: name}
end

@doc """
This is used by some screens to calculate a theoretical balance based on old ratings
"""
def get_user_rating_rank_old(userid, rating_value) do
%{rank: rank, name: name} = Account.get_user_by_id(userid)
%{rating: rating_value, rank: rank, name: name}
end

defp fuzz_rating(rating, multiplier) do
# Generate something between -1 and 1
modifier = 1 - :rand.uniform() * 2
Expand Down
72 changes: 72 additions & 0 deletions test/teiserver/battle/balance_lib_internal_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
defmodule Teiserver.Battle.BalanceLibInternalTest do
@moduledoc """
Can run all balance tests via
mix test --only balance_test
"""
use Teiserver.DataCase, async: true
@moduletag :balance_test
alias Teiserver.Battle.BalanceLib

test "Able to standardise groups with incomplete data" do
[user1, user2, user3, user4, user5] = create_test_users()

groups = [
%{user1.id => 19, user2.id => 20},
%{user3.id => 18},
%{user4.id => 15},
%{user5.id => 11}
]

fixed_groups = BalanceLib.standardise_groups(groups)

assert fixed_groups == [
%{
user1.id => %{name: "User_1", rank: 0, rating: 19},
user2.id => %{name: "User_2", rank: 0, rating: 20}
},
%{user3.id => %{name: "User_3", rank: 0, rating: 18}},
%{user4.id => %{name: "User_4", rank: 0, rating: 15}},
%{user5.id => %{name: "User_5", rank: 0, rating: 11}}
]

# loser_picks algo will hit the databases so let's just test with split_one_chevs
result = BalanceLib.create_balance(fixed_groups, 2, algorithm: "split_one_chevs")
assert result != nil
end

test "Handle groups with incomplete data in create_balance loser_pics" do
[user1, user2, user3, user4, user5] = create_test_users()

groups = [
%{user1.id => 19, user2.id => 20},
%{user3.id => 18},
%{user4.id => 15},
%{user5.id => 11}
]

# loser_picks algo will hit the databases so let's just test with split_one_chevs
result = BalanceLib.create_balance(groups, 2, algorithm: "loser_picks")
assert result != nil
end

test "Handle groups with incomplete data in create_balance split_one_chevs" do
[user1, user2, user3, user4, user5] = create_test_users()

groups = [
%{user1.id => 19, user2.id => 20},
%{user3.id => 18},
%{user4.id => 15},
%{user5.id => 11}
]

# loser_picks algo will hit the databases so let's just test with split_one_chevs
result = BalanceLib.create_balance(groups, 2, algorithm: "split_one_chevs")
assert result != nil
end

defp create_test_users do
Enum.map(1..5, fn k ->
Teiserver.TeiserverTestLib.new_user("User_#{k}")
end)
end
end
2 changes: 1 addition & 1 deletion test/teiserver/battle/split_one_chevs_internal_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ defmodule Teiserver.Battle.SplitOneChevsInternalTest do
Can run tests in this file only by
mix test test/teiserver/battle/split_one_chevs_internal_test.exs
"""
use Teiserver.DataCase, async: true
use ExUnit.Case
@moduletag :balance_test
alias Teiserver.Battle.Balance.SplitOneChevs

Expand Down
2 changes: 1 addition & 1 deletion test/teiserver/battle/split_one_chevs_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ defmodule Teiserver.Battle.SplitOneChevsTest do
Can run tests in this file only by
mix test test/teiserver/battle/split_one_chevs_test.exs
"""
use Teiserver.DataCase, async: true
use ExUnit.Case
@moduletag :balance_test
alias Teiserver.Battle.BalanceLib

Expand Down

0 comments on commit f49619c

Please sign in to comment.