Exemplo n.º 1
0
def test_exercise():
    player = Glicko2Entry(1500, 200, 0.06)
    glicko2_update(
        player,
        [
            (Glicko2Entry(100, 100), 0),
            (Glicko2Entry(30000, 10000), 1),
            (Glicko2Entry(1500, 100), 1),
            (Glicko2Entry(1500, 100), 0),
        ],
    )
Exemplo n.º 2
0
def test_glicko2():
    glicko2_configure(
        tao=0.5, min_rd=10, max_rd=500,
    )

    player = Glicko2Entry(1500, 200, 0.06)
    a = Glicko2Entry(1400, 30, 0.06)
    b = Glicko2Entry(1550, 100, 0.06)
    c = Glicko2Entry(1700, 300, 0.06)
    player = glicko2_update(player, [(a, 1), (b, 0), (c, 0)])

    assert round(player.rating, 1) == 1464.1
    assert round(player.deviation, 1) == 151.5
Exemplo n.º 3
0
def test_copy():
    player = Glicko2Entry(1500, 200, 0.06)
    copy = player.copy()
    assert copy.rating == player.rating
    assert copy.deviation == player.deviation
    assert copy.volatility == player.volatility
    assert copy.mu == player.mu
    assert copy.phi == player.phi
Exemplo n.º 4
0
    def process_game(self, game: GameRecord) -> Glicko2Analytics:
        if game.black_manual_rank_update is not None:
            self._storage.set(
                game.black_id,
                Glicko2Entry(rank_to_rating(game.black_manual_rank_update)))

        if game.white_manual_rank_update is not None:
            self._storage.set(
                game.white_id,
                Glicko2Entry(rank_to_rating(game.white_manual_rank_update)))

        ## Only count the first timeout in correspondence games as a ranked loss
        if game.timeout and game.speed == 3:  # correspondence timeout
            player_that_timed_out = game.black_id if game.black_id != game.winner_id else game.white_id
            skip = self._storage.get_timeout_flag(
                game.black_id) or self._storage.get_timeout_flag(game.white_id)
            self._storage.set_timeout_flag(player_that_timed_out, True)
            if skip:
                return Glicko2Analytics(skipped=True, game=game)
        if game.speed == 3:  # clear corr. timeout flags
            self._storage.set_timeout_flag(game.black_id, True)
            self._storage.set_timeout_flag(game.white_id, True)

        window = (int(game.ended) // 86400) * 86400
        black_base = self._storage.get_first_rating_older_than(
            game.black_id, window)
        white_base = self._storage.get_first_rating_older_than(
            game.white_id, window)
        black_cur = self._storage.get(game.black_id)
        white_cur = self._storage.get(game.white_id)

        self._storage.add_match_history(game.black_id, game.ended,
                                        (game, white_cur))
        self._storage.add_match_history(game.white_id, game.ended,
                                        (game, black_cur))

        updated_black = glicko2_update(black_base, [
            (opponent.copy(
                (1 if past_game.black_id != game.black_id else -1) *
                get_handicap_adjustment(opponent.rating, past_game.handicap)),
             past_game.winner_id == game.black_id) for past_game, opponent in
            self._storage.get_matches_newer_or_equal_to(game.black_id, window)
        ])

        updated_white = glicko2_update(white_base, [
            (opponent.copy(
                (1 if past_game.black_id != game.white_id else -1) *
                get_handicap_adjustment(opponent.rating, past_game.handicap)),
             past_game.winner_id == game.white_id) for past_game, opponent in
            self._storage.get_matches_newer_or_equal_to(game.white_id, window)
        ])

        self._storage.set(game.black_id, updated_black)
        self._storage.set(game.white_id, updated_white)
        self._storage.add_rating_history(game.black_id, game.ended,
                                         updated_black)
        self._storage.add_rating_history(game.white_id, game.ended,
                                         updated_white)

        return Glicko2Analytics(
            skipped=False,
            game=game,
            expected_win_rate=black_cur.expected_win_probability(
                white_cur,
                get_handicap_adjustment(black_cur.rating, game.handicap),
                ignore_g=True),
            black_rating=black_cur.rating,
            white_rating=white_cur.rating,
            black_deviation=black_cur.deviation,
            white_deviation=white_cur.deviation,
            black_rank=rating_to_rank(black_cur.rating),
            white_rank=rating_to_rank(white_cur.rating),
            black_updated_rating=updated_black.rating,
            white_updated_rating=updated_white.rating,
        )
Exemplo n.º 5
0
def test_nop():
    player = Glicko2Entry(1500, 200, 0.06)
    p = glicko2_update(player, [])
    assert p.rating == player.rating
Exemplo n.º 6
0
def test_expected_win_probability():
    player = Glicko2Entry(1500, 200, 0.06)
    assert player.expected_win_probability(player, 0) == 0.5
Exemplo n.º 7
0
def test_expansion():
    player = Glicko2Entry(1500, 200, 0.06)
    player.expand_deviation_because_no_games_played(1)
    assert round(player.deviation, 1) == 200.3
Exemplo n.º 8
0
def test_str():
    player = Glicko2Entry(1500, 200, 0.06)
    assert isinstance(str(player), str)
Exemplo n.º 9
0
    def process_game(self, game: GameRecord) -> Glicko2Analytics:
        ## Only count the first timeout in correspondence games as a ranked loss
        if game.timeout and game.speed == 3:  # correspondence timeout
            player_that_timed_out = game.black_id if game.black_id != game.winner_id else game.white_id
            skip = self._storage.get_timeout_flag(
                game.black_id) or self._storage.get_timeout_flag(game.white_id)
            self._storage.set_timeout_flag(player_that_timed_out, True)
            if skip:
                return Glicko2Analytics(skipped=True, game=game)
        if game.speed == 3:  # clear corr. timeout flags
            self._storage.set_timeout_flag(game.black_id, True)
            self._storage.set_timeout_flag(game.white_id, True)

        ## read base rating (last rating before the current rating period)
        window = (int(game.ended) // window_width) * window_width
        black_base = self._storage.get_first_rating_older_than(
            game.black_id, window).copy()
        white_base = self._storage.get_first_rating_older_than(
            game.white_id, window).copy()

        ## since we do not update deviation in periods without games, we have to do update it now if there are empty periods size the base rating was calclulated
        black_base_time = self._storage.get_first_timestamp_older_than(
            game.black_id, window)
        white_base_time = self._storage.get_first_timestamp_older_than(
            game.white_id, window)

        if black_base_time is not None:
            black_base.expand_deviation_because_no_games_played(
                int((game.ended - black_base_time) / no_games_window_witdh))
        if white_base_time is not None:
            white_base.expand_deviation_because_no_games_played(
                int((game.ended - white_base_time) / no_games_window_witdh))

        ## store games in the match history
        self._storage.add_match_history(game.black_id, game.ended,
                                        (game, white_base))
        self._storage.add_match_history(game.white_id, game.ended,
                                        (game, black_base))

        ## update ratings
        updated_black = glicko2_update(black_base, [
            (opponent.copy(
                (1 if past_game.black_id != game.black_id else -1) *
                get_handicap_adjustment(opponent.rating, past_game.handicap)),
             past_game.winner_id == past_game.black_id)
            for past_game, opponent in
            self._storage.get_matches_newer_or_equal_to(game.black_id, window)
        ])

        updated_white = glicko2_update(white_base, [
            (opponent.copy(
                (1 if past_game.black_id != game.white_id else -1) *
                get_handicap_adjustment(opponent.rating, past_game.handicap)),
             past_game.winner_id == past_game.white_id)
            for past_game, opponent in
            self._storage.get_matches_newer_or_equal_to(game.white_id, window)
        ])

        # do not decrease rating if player won or increase if she lost
        # users complain when their rating drops after they won a game, even if it is only by a few points. This happens
        # regular since the deviation becomes lower with each game played in a period.
        # Here we accept the rating system to be slightly less accurate for the sake of user experience. Since we use
        # the base rating of  both players when updating the ratings, this only affects future rating updates if this
        # game happens to be the last game in the rating period of the affected player.
        black_cur = self._storage.get(game.black_id).copy()
        white_cur = self._storage.get(game.white_id).copy()
        if (game.winner_id == game.black_id and updated_black.rating - black_cur.rating < 0) or \
            (game.winner_id != game.black_id and updated_black.rating - black_cur.rating > 0):
            updated_black = Glicko2Entry(rating=black_cur.rating,
                                         deviation=updated_black.deviation,
                                         volatility=updated_black.volatility)
        if (game.winner_id == game.white_id and updated_white.rating - white_cur.rating < 0) or \
            (game.winner_id != game.white_id and updated_white.rating - white_cur.rating > 0):
            updated_white = Glicko2Entry(rating=white_cur.rating,
                                         deviation=updated_white.deviation,
                                         volatility=updated_white.volatility)

        self._storage.set(game.black_id, updated_black)
        self._storage.set(game.white_id, updated_white)
        self._storage.add_rating_history(game.black_id, game.ended,
                                         updated_black)
        self._storage.add_rating_history(game.white_id, game.ended,
                                         updated_white)

        return Glicko2Analytics(
            skipped=False,
            game=game,
            expected_win_rate=black_cur.expected_win_probability(
                white_cur,
                get_handicap_adjustment(black_cur.rating, game.handicap),
                ignore_g=True),
            black_rating=black_cur.rating,
            white_rating=white_cur.rating,
            black_deviation=black_cur.deviation,
            white_deviation=white_cur.deviation,
            black_rank=rating_to_rank(black_cur.rating),
            white_rank=rating_to_rank(white_cur.rating),
            black_updated_rating=updated_black.rating,
            white_updated_rating=updated_white.rating,
        )
Exemplo n.º 10
0
    def process_game(self, game: GameRecord) -> Dict[str, Glicko2Analytics]:
        global ALWAYS_USE_OVERALL
        ret = {}
        overall_storage = self._storages['999-999']

        for speed in [game.speed, 999]:
            for size in [game.size, 999]:
                k = '%d-%d' % (speed, size)
                storage = self._storages[k]
                if game.black_manual_rank_update is not None:
                    storage.set(
                        game.black_id,
                        Glicko2Entry(
                            rank_to_rating(game.black_manual_rank_update)))

                if game.white_manual_rank_update is not None:
                    storage.set(
                        game.white_id,
                        Glicko2Entry(
                            rank_to_rating(game.white_manual_rank_update)))

                ## Only count the first timeout in correspondence games as a ranked loss
                if game.timeout and game.speed == 3:  # correspondence timeout
                    player_that_timed_out = game.black_id if game.black_id != game.winner_id else game.white_id
                    skip = storage.get_timeout_flag(
                        game.black_id) or storage.get_timeout_flag(
                            game.white_id)
                    storage.set_timeout_flag(player_that_timed_out, True)
                    if skip:
                        ret[k] = Glicko2Analytics(skipped=True, game=game)
                        continue
                if game.speed == 3:  # clear corr. timeout flags
                    storage.set_timeout_flag(game.black_id, True)
                    storage.set_timeout_flag(game.white_id, True)

                black = storage.get(game.black_id)
                white = storage.get(game.white_id)
                if ALWAYS_USE_OVERALL:
                    src_black = overall_storage.get(game.black_id)
                    src_white = overall_storage.get(game.white_id)
                else:
                    src_black = black
                    src_white = white

                updated_black = glicko2_update(
                    black,
                    [(
                        src_white.copy(-get_handicap_adjustment(
                            src_white.rating, game.handicap)),
                        game.winner_id == game.black_id,
                    )],
                )

                updated_white = glicko2_update(
                    white,
                    [(
                        src_black.copy(
                            get_handicap_adjustment(src_black.rating,
                                                    game.handicap)),
                        game.winner_id == game.white_id,
                    )],
                )

                storage.set(game.black_id, updated_black)
                storage.set(game.white_id, updated_white)
                #storage.add_rating_history(game.black_id, game.ended, updated_black)
                #storage.add_rating_history(game.white_id, game.ended, updated_white)

                ret[k] = Glicko2Analytics(
                    skipped=False,
                    game=game,
                    expected_win_rate=black.expected_win_probability(
                        white,
                        get_handicap_adjustment(black.rating, game.handicap),
                        ignore_g=True),
                    black_rating=black.rating,
                    white_rating=white.rating,
                    black_deviation=black.deviation,
                    white_deviation=white.deviation,
                    black_rank=rating_to_rank(black.rating),
                    white_rank=rating_to_rank(white.rating),
                    black_updated_rating=updated_black.rating,
                    white_updated_rating=updated_white.rating,
                )

        return ret
Exemplo n.º 11
0
    def process_game(self, game: GameRecord) -> Glicko2Analytics:
        if game.black_manual_rank_update is not None:
            self._storage.set(game.black_id, Glicko2Entry(rank_to_rating(game.black_manual_rank_update)))

        if game.white_manual_rank_update is not None:
            self._storage.set(game.white_id, Glicko2Entry(rank_to_rating(game.white_manual_rank_update)))

        ## Only count the first timeout in correspondence games as a ranked loss
        if game.timeout and game.speed == 3: # correspondence timeout
            player_that_timed_out = game.black_id if game.black_id != game.winner_id else game.white_id
            skip = self._storage.get_timeout_flag(game.black_id) or self._storage.get_timeout_flag(game.white_id)
            self._storage.set_timeout_flag(player_that_timed_out, True)
            if skip:
                return Glicko2Analytics(skipped=True, game=game)
        if game.speed == 3: # clear corr. timeout flags
            self._storage.set_timeout_flag(game.black_id, True)
            self._storage.set_timeout_flag(game.white_id, True)


        black = self._storage.get(game.black_id)
        white = self._storage.get(game.white_id)

        updated_black = glicko2_update(
            black,
            [
                (
                    white.copy(-get_handicap_adjustment(white.rating, game.handicap)),
                    game.winner_id == game.black_id,
                )
            ],
        )

        updated_white = glicko2_update(
            white,
            [
                (
                    black.copy(get_handicap_adjustment(black.rating, game.handicap)),
                    game.winner_id == game.white_id,
                )
            ],
        )

        self._storage.set(game.black_id, updated_black)
        self._storage.set(game.white_id, updated_white)
        #self._storage.add_rating_history(game.black_id, game.ended, updated_black)
        #self._storage.add_rating_history(game.white_id, game.ended, updated_white)

        return Glicko2Analytics(
            skipped=False,
            game=game,
            expected_win_rate=black.expected_win_probability(
                white, get_handicap_adjustment(black.rating, game.handicap), ignore_g=True
            ),
            black_rating=black.rating,
            white_rating=white.rating,
            black_deviation=black.deviation,
            white_deviation=white.deviation,
            black_rank=rating_to_rank(black.rating),
            white_rank=rating_to_rank(white.rating),
            black_updated_rating=updated_black.rating,
            white_updated_rating=updated_white.rating,
        )