Skip to content

Commit

Permalink
Add stdev diff penalty to brute_force and split_noobs
Browse files Browse the repository at this point in the history
Fix failing test
  • Loading branch information
jauggy committed Oct 20, 2024
1 parent 091c554 commit f24fb5d
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 87 deletions.
59 changes: 35 additions & 24 deletions lib/teiserver/battle/balance/brute_force.ex
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ defmodule Teiserver.Battle.Balance.BruteForce do
import Teiserver.Helper.NumberHelper, only: [format: 1]
require Integer

@stdev_diff_importance 4
@party_importance 7
@splitter "------------------------------------------------------"

Expand Down Expand Up @@ -110,45 +111,55 @@ defmodule Teiserver.Battle.Balance.BruteForce do
players_with_index = Enum.with_index(players)

# Go through every possibility and get the combination with the lowest score
result =
Enum.map(combos, fn x ->
get_players_from_indexes(x, players_with_index)
end)
|> Enum.map(fn team ->
result = score_combo(team, players, parties)
Map.put(result, :first_team, team)
end)
|> Enum.min_by(fn z ->
z.score
end)

first_team = result.first_team
Enum.map(combos, fn x ->
get_players_from_indexes(x, players_with_index)
end)
|> Enum.map(fn team ->
score_combo(team, players, parties)
end)
|> Enum.min_by(fn z ->
z.score
end)
end

second_team =
players
|> Enum.filter(fn x ->
!Enum.any?(first_team, fn y ->
y.id == x.id
end)
end)
@spec get_second_team([BF.player()], [BF.player()]) :: [BF.player()]
def get_second_team(first_team, all_players) do
all_players
|> Enum.filter(fn player -> !Enum.any?(first_team, fn x -> x.id == player.id end) end)
end

Map.put(result, :second_team, second_team)
@spec get_st_dev([BF.player()]) :: any()
def get_st_dev(team) do
if(length(team) > 0) do
ratings = Enum.map(team, fn player -> player.rating end)
Statistics.stdev(ratings)
else
0
end
end

@spec score_combo([BF.player()], [BF.player()], [String.t()]) :: any()
@spec score_combo([BF.player()], [BF.player()], [String.t()]) :: BF.combo_result()
def score_combo(first_team, all_players, parties) do
second_team = get_second_team(first_team, all_players)
first_team_rating = get_team_rating(first_team)
both_team_rating = get_team_rating(all_players)

rating_diff_penalty = abs(both_team_rating - first_team_rating * 2)
broken_party_penalty = count_broken_parties(first_team, parties) * @party_importance

score = rating_diff_penalty + broken_party_penalty
stdev_diff_penalty =
abs(get_st_dev(first_team) - get_st_dev(second_team)) *
@stdev_diff_importance

score = rating_diff_penalty + broken_party_penalty + stdev_diff_penalty

%{
score: score,
rating_diff_penalty: rating_diff_penalty,
broken_party_penalty: broken_party_penalty
broken_party_penalty: broken_party_penalty,
stdev_diff_penalty: stdev_diff_penalty,
first_team: first_team,
second_team: second_team
}
end

Expand Down
1 change: 1 addition & 0 deletions lib/teiserver/battle/balance/brute_force_types.ex
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ defmodule Teiserver.Battle.Balance.BruteForceTypes do
@type combo_result :: %{
broken_party_penalty: number(),
rating_diff_penalty: number(),
stdev_diff_penalty: number(),
score: number(),
first_team: [player()],
second_team: [player()]
Expand Down
1 change: 1 addition & 0 deletions lib/teiserver/battle/balance/split_noobs.ex
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ defmodule Teiserver.Battle.Balance.SplitNoobs do
"Brute force result:",
"Team rating diff penalty: #{format(combo_result.rating_diff_penalty)}",
"Broken party penalty: #{combo_result.broken_party_penalty}",
"Stdev diff penalty: #{format(combo_result.stdev_diff_penalty)}",
"Score: #{format(combo_result.score)} (lower is better)",
@splitter,
"Draft remaining players (ordered from best to worst).",
Expand Down
52 changes: 36 additions & 16 deletions test/teiserver/battle/brute_force_internal_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -118,34 +118,54 @@ defmodule Teiserver.Battle.BruteForceInternalTest do

assert result == %{
broken_party_penalty: 0,
first_team: [
%{id: 1, name: "kyutoryu", rating: 12.25},
%{id: 2, name: "fbots1998", rating: 13.98},
%{id: 3, name: "Dixinormus", rating: 18.28},
%{id: 4, name: "HungDaddy", rating: 2.8},
%{id: 5, name: "SLOPPYGAGGER", rating: 8.89},
%{id: 6, name: "jauggy", rating: 20.49}
],
rating_diff_penalty: 11.670000000000044,
score: 11.670000000000044
score: 13.987048974705417,
second_team: [
%{id: 7, name: "reddragon2010", rating: 18.4},
%{id: 8, name: "Aposis", rating: 20.42},
%{id: 9, name: "MaTThiuS_82", rating: 8.26},
%{id: 10, name: "Noody", rating: 17.64},
%{id: 11, name: "[DTG]BamBin0", rating: 20.06},
%{id: 12, name: "barmalev", rating: 3.58}
],
stdev_diff_penalty: 2.317048974705372
}

best_combo = BruteForce.get_best_combo(combos, input.players, input.parties)

assert best_combo == %{
broken_party_penalty: 0,
rating_diff_penalty: 0.5100000000000477,
score: 0.5100000000000477,
first_team: [
%{id: 1, name: "kyutoryu", rating: 12.25},
%{id: 2, name: "fbots1998", rating: 13.98},
%{id: 5, name: "SLOPPYGAGGER", rating: 8.89},
%{id: 6, name: "jauggy", rating: 20.49},
%{id: 7, name: "reddragon2010", rating: 18.4},
%{id: 9, name: "MaTThiuS_82", rating: 8.26}
%{id: 8, name: "Aposis", rating: 20.42},
%{id: 12, name: "barmalev", rating: 3.58}
],
rating_diff_penalty: 5.830000000000041,
score: 7.322550984245979,
second_team: [
%{id: 3, name: "Dixinormus", rating: 18.28},
%{id: 4, name: "HungDaddy", rating: 2.8},
%{id: 8, name: "Aposis", rating: 20.42},
%{id: 7, name: "reddragon2010", rating: 18.4},
%{id: 9, name: "MaTThiuS_82", rating: 8.26},
%{id: 10, name: "Noody", rating: 17.64},
%{id: 11, name: "[DTG]BamBin0", rating: 20.06},
%{id: 12, name: "barmalev", rating: 3.58}
]
%{id: 11, name: "[DTG]BamBin0", rating: 20.06}
],
stdev_diff_penalty: 1.4925509842459377
}

# The stdev team 1 = 5.47, and team 2 = 6.91

result = BruteForce.standardise_result(best_combo, input.parties) |> Map.drop([:logs])

assert result == %{
Expand All @@ -155,19 +175,19 @@ defmodule Teiserver.Battle.BruteForceInternalTest do
%{count: 1, group_rating: 13.98, members: [2], ratings: [13.98]},
%{count: 1, group_rating: 8.89, members: [5], ratings: [8.89]},
%{count: 1, group_rating: 20.49, members: [6], ratings: [20.49]},
%{count: 1, group_rating: 18.4, members: [7], ratings: [18.4]},
%{count: 1, group_rating: 8.26, members: [9], ratings: [8.26]}
%{count: 1, group_rating: 20.42, members: ~c"\b", ratings: [20.42]},
%{count: 1, group_rating: 3.58, members: ~c"\f", ratings: [3.58]}
],
2 => [
%{count: 1, group_rating: 18.28, members: [3], ratings: [18.28]},
%{count: 1, group_rating: 2.8, members: [4], ratings: [2.8]},
%{count: 1, group_rating: 20.42, members: [8], ratings: [20.42]},
%{count: 1, group_rating: 17.64, members: [10], ratings: [17.64]},
%{count: 1, group_rating: 20.06, members: [11], ratings: [20.06]},
%{count: 1, group_rating: 3.58, members: [12], ratings: [3.58]}
%{count: 1, group_rating: 18.4, members: ~c"\a", ratings: [18.4]},
%{count: 1, group_rating: 8.26, members: ~c"\t", ratings: [8.26]},
%{count: 1, members: ~c"\n", ratings: [17.64], group_rating: 17.64},
%{count: 1, group_rating: 20.06, members: ~c"\v", ratings: [20.06]}
]
},
team_players: %{1 => [1, 2, 5, 6, 7, 9], 2 => [3, 4, 8, 10, 11, 12]}
team_players: %{1 => [1, 2, 5, 6, 8, 12], 2 => [3, 4, 7, 9, 10, 11]}
}
end

Expand Down
29 changes: 15 additions & 14 deletions test/teiserver/battle/brute_force_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -102,35 +102,36 @@ defmodule Teiserver.Battle.BruteForceTest do

result = BruteForce.perform(expanded_group, 2) |> Map.drop([:logs])

# If we us a stdev penalty of less than 4, then all the 20+ players end up on the same team
assert result == %{
team_groups: %{
1 => [
%{count: 1, group_rating: 12.25, members: ["kyutoryu"], ratings: [12.25]},
%{count: 1, group_rating: 13.98, members: ["fbots1998"], ratings: [13.98]},
%{count: 1, group_rating: 8.89, members: ["SLOPPYGAGGER"], ratings: [8.89]},
%{count: 1, group_rating: 20.49, members: ["jauggy"], ratings: [20.49]},
%{count: 1, group_rating: 18.4, members: ["reddragon2010"], ratings: [18.4]},
%{count: 1, group_rating: 8.26, members: ["MaTThiuS_82"], ratings: [8.26]}
%{count: 1, group_rating: 20.42, members: ["Aposis"], ratings: [20.42]},
%{count: 1, group_rating: 3.58, members: ["barmalev"], ratings: [3.58]}
],
2 => [
%{count: 1, group_rating: 18.28, members: ["Dixinormus"], ratings: [18.28]},
%{count: 1, group_rating: 2.8, members: ["HungDaddy"], ratings: [2.8]},
%{count: 1, group_rating: 20.42, members: ["Aposis"], ratings: [20.42]},
%{count: 1, group_rating: 17.64, members: ["Noody"], ratings: [17.64]},
%{count: 1, group_rating: 20.06, members: ["[DTG]BamBin0"], ratings: [20.06]},
%{count: 1, group_rating: 3.58, members: ["barmalev"], ratings: [3.58]}
%{count: 1, group_rating: 18.4, members: ["reddragon2010"], ratings: [18.4]},
%{count: 1, group_rating: 8.26, members: ["MaTThiuS_82"], ratings: [8.26]},
%{count: 1, members: ["Noody"], ratings: [17.64], group_rating: 17.64},
%{count: 1, group_rating: 20.06, members: ["[DTG]BamBin0"], ratings: [20.06]}
]
},
team_players: %{
1 => [
"kyutoryu",
"fbots1998",
"SLOPPYGAGGER",
"jauggy",
1 => ["kyutoryu", "fbots1998", "SLOPPYGAGGER", "jauggy", "Aposis", "barmalev"],
2 => [
"Dixinormus",
"HungDaddy",
"reddragon2010",
"MaTThiuS_82"
],
2 => ["Dixinormus", "HungDaddy", "Aposis", "Noody", "[DTG]BamBin0", "barmalev"]
"MaTThiuS_82",
"Noody",
"[DTG]BamBin0"
]
}
}
end
Expand Down
2 changes: 1 addition & 1 deletion test/teiserver/battle/respect_avoids_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ defmodule Teiserver.Battle.RespectAvoidsTest do
"Avoid min time required: 2 h",
"Avoids considered: 0 (Max: 6)",
"------------------------------------------------------",
"New players: None",
"Solo new players: None",
"------------------------------------------------------",
"Perform brute force with the following players to get the best score.",
"Players: fraqzilla, Spaceh, [DmE], Jeff, Jarial, AcowAdonis, AbyssWatcher, Gmans, MeowCat, mighty, Threekey, Zippo9, Kaa, Faeton",
Expand Down
24 changes: 13 additions & 11 deletions test/teiserver/battle/split_noobs_internal_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -596,12 +596,12 @@ defmodule Teiserver.Battle.SplitNoobsInternalTest do
},
%{
id: "reddragon2010",
in_party?: false,
index: 6,
name: "reddragon2010",
uncertainty: 3,
rating: 18.4,
rank: 2,
in_party?: false
rating: 18.4,
uncertainty: 3
},
%{
id: "Noody",
Expand All @@ -614,7 +614,7 @@ defmodule Teiserver.Battle.SplitNoobsInternalTest do
}
],
rating_diff_penalty: 6.203564356435635,
score: 6.203564356435635,
score: 7.221262567387239,
second_team: [
%{
id: "Dixinormus",
Expand Down Expand Up @@ -653,12 +653,12 @@ defmodule Teiserver.Battle.SplitNoobsInternalTest do
},
%{
id: "MaTThiuS_82",
in_party?: false,
index: 9,
name: "MaTThiuS_82",
uncertainty: 3,
rating: 8.26,
rank: 2,
in_party?: false
rating: 8.26,
uncertainty: 3
},
%{
id: "barmalev",
Expand All @@ -669,7 +669,8 @@ defmodule Teiserver.Battle.SplitNoobsInternalTest do
rating: 3.58,
uncertainty: 3
}
]
],
stdev_diff_penalty: 1.017698210951604
}

standard_result = SplitNoobs.standardise_result(result, initial_state)
Expand All @@ -692,7 +693,8 @@ defmodule Teiserver.Battle.SplitNoobsInternalTest do
"Brute force result:",
"Team rating diff penalty: 6.2",
"Broken party penalty: 0",
"Score: 6.2 (lower is better)",
"Stdev diff penalty: 1.0",
"Score: 7.2 (lower is better)",
"------------------------------------------------------",
"Draft remaining players (ordered from best to worst).",
"Remaining: Dixinormus, HungDaddy",
Expand Down Expand Up @@ -722,7 +724,7 @@ defmodule Teiserver.Battle.SplitNoobsInternalTest do
ratings: [2.768316831683173]
},
%{count: 1, group_rating: 20.06, members: ["[DTG]BamBin0"], ratings: [20.06]},
%{count: 1, members: ["reddragon2010"], ratings: [18.4], group_rating: 18.4},
%{count: 1, group_rating: 18.4, members: ["reddragon2010"], ratings: [18.4]},
%{count: 1, group_rating: 17.64, members: ["Noody"], ratings: [17.64]}
],
2 => [
Expand All @@ -735,7 +737,7 @@ defmodule Teiserver.Battle.SplitNoobsInternalTest do
%{count: 1, group_rating: 20.49, members: ["jauggy"], ratings: [20.49]},
%{count: 1, group_rating: 20.42, members: ["Aposis"], ratings: [20.42]},
%{count: 1, group_rating: 8.89, members: ["SLOPPYGAGGER"], ratings: [8.89]},
%{count: 1, members: ["MaTThiuS_82"], ratings: [8.26], group_rating: 8.26},
%{count: 1, group_rating: 8.26, members: ["MaTThiuS_82"], ratings: [8.26]},
%{count: 1, group_rating: 3.58, members: ["barmalev"], ratings: [3.58]}
]
},
Expand Down
Loading

0 comments on commit f24fb5d

Please sign in to comment.