From e00de33df47f07ae00d57a703416b5d174833593 Mon Sep 17 00:00:00 2001 From: Linus Behrbohm Date: Sun, 13 Jul 2025 13:19:02 +0200 Subject: [PATCH 1/2] Use max rating deviation per team for match quality --- server/matchmaker/algorithm/team_matchmaker.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server/matchmaker/algorithm/team_matchmaker.py b/server/matchmaker/algorithm/team_matchmaker.py index 6ec12c3ed..cab97e0d1 100644 --- a/server/matchmaker/algorithm/team_matchmaker.py +++ b/server/matchmaker/algorithm/team_matchmaker.py @@ -325,17 +325,17 @@ def assign_game_quality( minority_bonus = min(minority_bonus, config.MINORITY_BONUS) rating_disparity = abs(match[0].cumulative_rating - match[1].cumulative_rating) unfairness = rating_disparity / config.MAXIMUM_RATING_IMBALANCE - deviation = statistics.pstdev(ratings) - rating_variety = deviation / config.MAXIMUM_RATING_DEVIATION + max_team_deviation = max(map(statistics.pstdev, [match[0].displayed_ratings, match[1].displayed_ratings])) + max_rating_variety = max_team_deviation / config.MAXIMUM_RATING_DEVIATION # Visually this creates a cone in the unfairness-rating_variety plane # that slowly raises with the time bonuses. - quality = 1 - sqrt(unfairness ** 2 + rating_variety ** 2) + time_bonus + minority_bonus + quality = 1 - sqrt(unfairness ** 2 + max_rating_variety ** 2) + time_bonus + minority_bonus if not any(team.has_high_rated_player() for team in match): quality += newbie_bonus self._logger.debug( "bonuses: %s rating disparity: %s -> unfairness: %f deviation: %f -> variety: %f -> game quality: %f", - newbie_bonus + time_bonus + minority_bonus, rating_disparity, unfairness, deviation, rating_variety, quality + newbie_bonus + time_bonus + minority_bonus, rating_disparity, unfairness, max_team_deviation, max_rating_variety, quality ) return GameCandidate(match, quality) From 871c64e5217818a3c628e89a35b375ddad18eaa0 Mon Sep 17 00:00:00 2001 From: Linus Behrbohm Date: Sat, 6 Sep 2025 18:11:21 +0200 Subject: [PATCH 2/2] Fix tests --- .../test_matchmaker_algorithm_team_matchmaker.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/unit_tests/test_matchmaker_algorithm_team_matchmaker.py b/tests/unit_tests/test_matchmaker_algorithm_team_matchmaker.py index 26ea6de33..c4cec1c85 100644 --- a/tests/unit_tests/test_matchmaker_algorithm_team_matchmaker.py +++ b/tests/unit_tests/test_matchmaker_algorithm_team_matchmaker.py @@ -80,10 +80,10 @@ def test_team_matchmaker_algorithm(player_factory): matches, unmatched = matchmaker.find(s, 4, 1000) - assert set(matches[1][0].get_original_searches()) == {c1, s[2], s[5]} - assert set(matches[1][1].get_original_searches()) == {c3, s[1], s[6]} - assert set(matches[0][0].get_original_searches()) == {c4, s[4]} - assert set(matches[0][1].get_original_searches()) == {c2, s[0], s[3]} + assert set(matches[0][0].get_original_searches()) == {c1, s[2], s[5]} + assert set(matches[0][1].get_original_searches()) == {c3, s[1], s[6]} + assert set(matches[1][0].get_original_searches()) == {c4, s[4]} + assert set(matches[1][1].get_original_searches()) == {c2, s[0], s[3]} assert set(unmatched) == {s[7]} for match in matches: assert matchmaker.assign_game_quality(match, 4, 1000).quality > config.MINIMUM_GAME_QUALITY