diff --git a/server/ladder_service/ladder_service.py b/server/ladder_service/ladder_service.py index 7f3b5d7ed..c6441e0e3 100644 --- a/server/ladder_service/ladder_service.py +++ b/server/ladder_service/ladder_service.py @@ -33,7 +33,6 @@ from server.decorators import with_logger from server.exceptions import DisabledError from server.game_service import GameService -from server.player_service import PlayerService from server.games import InitMode, LadderGame from server.games.ladder_game import GameClosedError from server.ladder_service.game_name import game_name @@ -45,6 +44,7 @@ Search ) from server.metrics import MatchLaunch +from server.player_service import PlayerService from server.players import Player, PlayerState from server.types import GameLaunchOptions, Map, NeroxisGeneratedMap @@ -543,14 +543,14 @@ def get_displayed_rating(player: Player) -> float: pool = queue.get_map_pool_for_rating(rating) if not pool: raise RuntimeError(f"No map pool available for rating {rating}!") - + pool, _, _, _, max_tokens_per_map, minimum_maps_after_veto = queue.map_pools[pool.id] vetoesMap = defaultdict(int) - for map in pool.maps.values(): + for m in pool.maps.values(): for player in all_players: - vetoesMap[map.map_pool_map_version_id] += player.vetoes.get(map.map_pool_map_version_id, 0) + vetoesMap[m.map_pool_map_version_id] += player.vetoes.get(m.map_pool_map_version_id, 0) if (max_tokens_per_map == 0): max_tokens_per_map = self.calculate_dynamic_tokens_per_map(minimum_maps_after_veto, vetoesMap.values()) @@ -713,7 +713,7 @@ def calculate_dynamic_tokens_per_map(self, M: float, tokens: list[int]) -> float sorted_tokens = sorted(tokens) if (sorted_tokens.count(0) >= M): return 1 - + result = 1 last = 0 index = 0 @@ -723,14 +723,14 @@ def calculate_dynamic_tokens_per_map(self, M: float, tokens: list[int]) -> float divider = index - M if (divider <= 0): continue - + result = sum(sorted_tokens[:index]) / divider upperLimit = sorted_tokens[index] if index < len(sorted_tokens) else float("inf") if (result <= upperLimit): return result - + return 0 - + def get_pools_veto_data(self) -> list[tuple[list[int], int, int]]: result = [] for queue in self.queues.values(): diff --git a/server/matchmaker/map_pool.py b/server/matchmaker/map_pool.py index b34641eff..ec5362833 100644 --- a/server/matchmaker/map_pool.py +++ b/server/matchmaker/map_pool.py @@ -21,12 +21,12 @@ def __init__( def set_maps(self, maps: Iterable[MapPoolMap]) -> None: self.maps = {map_.id: map_ for map_ in maps} - def choose_map(self, played_map_ids: Iterable[int]=(), vetoesMap=None, max_tokens_per_map=1) -> Map: + def choose_map(self, played_map_ids: Iterable[int] = (), vetoesMap=None, max_tokens_per_map=1) -> Map: if vetoesMap is None: vetoesMap = {} """ - Select a random map using veto system weights. - The maps which are least played from played_map_ids + Select a random map using veto system weights. + The maps which are least played from played_map_ids and not vetoed by any player are getting x2 weight multiplier. """ if not self.maps: @@ -52,12 +52,11 @@ def choose_map(self, played_map_ids: Iterable[int]=(), vetoesMap=None, max_token least_common = least_common[:i] break - least_common_ids = {id_ for id_, _ in least_common} - + # Multiply weight by 2 if map is least common and not vetoed by anyone - mapList = list((map.map_pool_map_version_id, map, 2 if (map.id in least_common_ids) and (vetoesMap.get(map.map_pool_map_version_id,0) == 0) else 1) for id, map in self.maps.items()) - + mapList = list((map.map_pool_map_version_id, map, 2 if (map.id in least_common_ids) and (vetoesMap.get(map.map_pool_map_version_id, 0) == 0) else 1) for id, map in self.maps.items()) + weights = [max(0, (1 - vetoesMap.get(id, 0) / max_tokens_per_map) * map.weight * least_common_multiplier) for id, map, least_common_multiplier in mapList] return random.choices(mapList, weights=weights, k=1)[0][1] diff --git a/server/players.py b/server/players.py index 5c9406798..83039ac50 100644 --- a/server/players.py +++ b/server/players.py @@ -110,7 +110,7 @@ async def update_vetoes(self, pools_vetodata: list[tuple[list[int], int, int]], for (map_pool_map_version_ids, veto_tokens_per_player, max_tokens_per_map) in pools_vetodata: tokens_sum = 0 for map_id in map_pool_map_version_ids: - new_tokens_applied = max(current.get(map_id, 0),0) + new_tokens_applied = max(current.get(map_id, 0), 0) if (tokens_sum + new_tokens_applied > veto_tokens_per_player): new_tokens_applied = veto_tokens_per_player - tokens_sum if (max_tokens_per_map > 0 and new_tokens_applied > max_tokens_per_map):