Source code for rlapi.tier_estimates

# Copyright 2018-present Jakub Kuczys (https://github.com/jack1142)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import annotations

import logging
from math import ceil
from typing import TYPE_CHECKING, Optional, Union

from ._utils import AlwaysGreaterOrEqual

if TYPE_CHECKING:
    from .player import Playlist

log = logging.getLogger(__name__)

__all__ = ("TierEstimates",)


[docs]class TierEstimates: """TierEstimates() Represents Rocket League playlist's tier estimates. Attributes ---------- playlist: `rlapi.Playlist` Playlist object which these estimates are about. tier: int Estimated tier on this playlist. division: int Estimated division on this playlist. div_down: int, optional Estimated amount of points for player to go a division down. div_up: int, optional Estimated amount of points for player to go a division up. tier_down: int, optional Estimated amount of points for player to go a tier down. tier_up: int, optional Estimated amount of points for player to go a tier up. """ __slots__ = ( "playlist", "tier", "division", "div_down", "div_up", "tier_down", "tier_up", ) def __init__(self, playlist: Playlist): self.playlist = playlist self.tier: int self.division: int if playlist.tier == 0: self._estimate_current_tier() else: self.tier = playlist.tier self.division = playlist.division self.div_down = self._estimate_div_down() self.div_up = self._estimate_div_up() self.tier_down = self._estimate_tier_down() self.tier_up = self._estimate_tier_up() def __repr__(self) -> str: return ( f"<{self.__class__.__name__}" f" for playlist {self.playlist.key};" f" tier={self.tier}" f" division={self.division}" f" tier_down={self.tier_down}" f" div_down={self.div_down}" f" div_up={self.div_up}" f" tier_up={self.tier_up}" f">" ) def _estimate_div_down(self) -> Optional[int]: playlist = self.playlist if self.tier == 1 and self.division == 0 or self.tier == 0: return None try: divisions = playlist.breakdown[self.tier] div_down = int(ceil(divisions[self.division][0] - playlist.skill)) except KeyError as e: log.debug(str(e)) return None if div_down > 0: div_down = -1 return div_down def _estimate_div_up(self) -> Optional[int]: playlist = self.playlist if self.tier == playlist.TIER_MAX or self.tier == 0: return None try: divisions = playlist.breakdown[self.tier] if self.tier == self.division == 0: value = divisions[1][0] else: value = divisions[self.division][1] div_up = int(ceil(value - playlist.skill)) except KeyError as e: log.debug(str(e)) return None if div_up < 0: div_up = 1 return div_up def _estimate_tier_down(self) -> Optional[int]: playlist = self.playlist if self.tier in {0, 1}: return None try: divisions = playlist.breakdown[self.tier] tier_down = int(ceil(divisions[0][0] - playlist.skill)) except KeyError as e: log.debug(str(e)) return None if tier_down > 0: tier_down = -1 return tier_down def _estimate_tier_up(self) -> Optional[int]: playlist = self.playlist if self.tier in {0, playlist.TIER_MAX}: return None try: divisions = playlist.breakdown[self.tier] tier_up = int(ceil(divisions[3][1] - playlist.skill)) except KeyError as e: log.debug(str(e)) return None if tier_up < 0: tier_up = 1 return tier_up def _estimate_current_tier(self) -> None: playlist = self.playlist if not playlist.breakdown: self.tier = playlist.tier self.division = playlist.division return lowest_diff: Union[float, int, AlwaysGreaterOrEqual] = AlwaysGreaterOrEqual() for tier, divisions in playlist.breakdown.items(): for division, (begin, end) in divisions.items(): if begin <= playlist.skill <= end: self.tier = tier self.division = division return diff, incr = min( (abs(playlist.skill - begin), -1), (abs(playlist.skill - end), 1) ) condition = diff <= lowest_diff if condition: lowest_diff = diff lowest_diff_tier = tier lowest_diff_division = division + incr if lowest_diff_division == -1: self.tier = lowest_diff_tier - 1 self.division = 3 if self.tier < 1: self.tier = 1 self.division = 0 elif lowest_diff_division == 4: self.tier = lowest_diff_tier + 1 self.division = 0 if self.tier > playlist.TIER_MAX: self.tier = playlist.TIER_MAX else: self.tier = lowest_diff_tier self.division = lowest_diff_division