async def test_compute_rating_balanced_teamgame(game: Game, create_player): await game.clear_data() game.state = GameState.LOBBY players = [( create_player(**info), result, team ) for info, result, team in [ (dict(login='******', id=1, global_rating=Rating(1500, 250.7)), 0, 1), (dict(login='******', id=2, global_rating=Rating(1700, 120.1)), 0, 1), (dict(login='******', id=3, global_rating=Rating(1200, 72.02)), 0, 2), (dict(login='******', id=4, global_rating=Rating(1200, 72.02)), 0, 2), ]] add_connected_players(game, [player for player, _, _ in players]) for player, _, team in players: game.set_player_option(player.id, 'Team', team) game.set_player_option(player.id, 'Army', player.id - 1) await game.launch() for player, result, _ in players: await game.add_result(player, player.id - 1, 'score', result) result = game.compute_rating() for team in result: for player, new_rating in team.items(): assert player in game.players assert new_rating != Rating(*player.global_rating)
async def test_game_results(game: Game, players): game.state = GameState.LOBBY host_id = players.hosting.id join_id = players.joining.id add_connected_players(game, [players.hosting, players.joining]) game.set_player_option(players.hosting.id, "Team", 1) game.set_player_option(players.joining.id, "Team", 1) await game.launch() await game.add_result(host_id, 0, "victory", 1) await game.add_result(join_id, 1, "defeat", 0) game_results = await game.resolve_game_results() result_dict = game_results.to_dict() assert result_dict["validity"] == "VALID" assert result_dict["rating_type"] == "global" assert len(result_dict["teams"]) == 2 for team in result_dict["teams"]: assert team["outcome"] == ("VICTORY" if team["player_ids"] == [host_id] else "DEFEAT") assert result_dict["game_id"] == game.id assert result_dict["map_id"] == game.map_id assert result_dict["featured_mod"] == "faf" assert result_dict["sim_mod_ids"] == []
def add_players_with_rating(player_factory, game, ratings, teams): rating_service = game.game_service._rating_service players = [( player_factory( f"{i}", player_id=i, global_rating=rating, ladder_rating=rating, with_lobby_connection=False, ), team, ) for i, (rating, team) in enumerate(zip(ratings, teams), 1)] game.state = GameState.LOBBY add_connected_players(game, [player for player, _ in players]) for player, team in players: rating_service.set_mock_rating( player.id, RatingType.GLOBAL, Rating(*player.ratings[RatingType.GLOBAL])) rating_service.set_mock_rating( player.id, RatingType.LADDER_1V1, Rating(*player.ratings[RatingType.LADDER_1V1]), ) player._mock_team = team game.set_player_option(player.id, "Team", player._mock_team) player._test_army = player.id - 1 game.set_player_option(player.id, "Army", player._test_army) return players
async def test_compute_rating_balanced_teamgame(game: Game, player_factory): game.state = GameState.LOBBY players = [(player_factory(login=f"{i}", player_id=i, global_rating=rating, with_lobby_connection=False), result, team) for i, (rating, result, team) in enumerate([ (Rating(1500, 250), 0, 2), (Rating(1700, 120), 0, 2), (Rating(1200, 72), 0, 3), (Rating(1200, 72), 0, 3), ], 1)] add_connected_players(game, [player for player, _, _ in players]) for player, _, team in players: game.set_player_option(player.id, 'Team', team) game.set_player_option(player.id, 'Army', player.id - 1) await game.launch() for player, result, team in players: await game.add_result(player, player.id - 1, 'victory' if team == 2 else 'defeat', result) result = game.compute_rating() for team in result: for player, new_rating in team.items(): assert player in game.players assert new_rating != Rating(*player.ratings[RatingType.GLOBAL])
async def test_game_is_invalid_due_to_desyncs(game: Game, players): game.state = GameState.LOBBY add_connected_players(game, [players.hosting, players.joining]) game.host = players.hosting await game.launch() game.desyncs = 30 await game.on_game_end() assert game.validity is ValidityState.TOO_MANY_DESYNCS
async def test_compute_rating_raises_game_error(game: Game, players): game.state = GameState.LOBBY add_connected_players(game, [players.hosting, players.joining]) # add_connected_players sets this, so we need to unset it again del game._player_options[players.hosting.id]["Team"] game.set_player_option(players.joining.id, "Team", 1) await game.launch() with pytest.raises(GameError): game.compute_rating(rating=RatingType.LADDER_1V1)
async def test_resolve_game_fails_if_not_launched(custom_game, players): rating_service = custom_game.game_service._rating_service custom_game.state = GameState.LOBBY add_connected_players(custom_game, [players.hosting, players.joining]) custom_game.set_player_option(players.hosting.id, "Team", 2) custom_game.set_player_option(players.joining.id, "Team", 3) custom_game.enforce_rating = True with pytest.raises(GameError): await custom_game.resolve_game_results()
def game_5p(game): game.state = GameState.LOBBY players = [ Player(id=1, login='******', global_rating=(1500, 500)), Player(id=2, login='******', global_rating=(1500, 500)), Player(id=3, login='******', global_rating=(1500, 500)), Player(id=4, login='******', global_rating=(1500, 500)), Player(id=5, login='******', global_rating=(1500, 500)), ] add_connected_players(game, players) return game
async def test_game_is_invalid_due_to_desyncs(game: Game, players): await game.clear_data() game.state = GameState.LOBBY add_connected_players(game, [players.hosting, players.joining]) game.host = players.hosting await game.launch() game.desyncs = 30 await game.on_game_end() assert game.validity is ValidityState.TOO_MANY_DESYNCS
async def test_rating_summary_missing_team_raises_game_error(game, players): game.state = GameState.LOBBY add_connected_players(game, [players.hosting, players.joining]) del game._player_options[players.hosting.id]["Team"] await game.launch() with pytest.raises(GameError): game.get_team_sets() with pytest.raises(GameError): await game.resolve_game_results()
async def test_compute_rating_computes_ladder_ratings(game: Game, players): game.state = GameState.LOBBY players.hosting.ratings[RatingType.LADDER_1V1] = Rating(1500, 250) players.joining.ratings[RatingType.LADDER_1V1] = Rating(1500, 250) add_connected_players(game, [players.hosting, players.joining]) await game.launch() await game.add_result(players.hosting.id, 0, 'victory', 1) await game.add_result(players.joining.id, 1, 'defeat', 0) game.set_player_option(players.hosting.id, 'Team', 1) game.set_player_option(players.joining.id, 'Team', 1) groups = game.compute_rating(rating=RatingType.LADDER_1V1) assert players.hosting in groups[0] assert players.joining in groups[1]
async def test_persist_results_not_called_with_one_player(game): await game.clear_data() game.persist_results = CoroMock() game.state = GameState.LOBBY players = [Player(id=1, login='******', global_rating=(1500, 500))] add_connected_players(game, players) await game.launch() assert len(game.players) == 1 await game.add_result(0, 1, 'VICTORY', 5) await game.on_game_end() game.persist_results.assert_not_called()
async def test_persist_results_not_called_with_one_player( game, player_factory): game.persist_results = CoroutineMock() game.state = GameState.LOBBY players = [ player_factory("Dostya", player_id=1, global_rating=(1500, 500)) ] add_connected_players(game, players) await game.launch() assert len(game.players) == 1 await game.add_result(0, 1, "victory", 5) await game.on_game_end() game.persist_results.assert_not_called()
async def test_persist_results_not_called_with_one_player(game): await game.clear_data() game.persist_results = CoroMock() game.state = GameState.LOBBY players = [ Player(id=1, login='******', global_rating=(1500, 500)) ] add_connected_players(game, players) await game.launch() assert len(game.players) == 1 await game.add_result(0, 1, 'VICTORY', 5) await game.on_game_end() game.persist_results.assert_not_called()
async def test_game_outcomes_no_results(game: Game, players): await game.clear_data() game.state = GameState.LOBBY players.hosting.ladder_rating = Rating(1500, 250) players.joining.ladder_rating = Rating(1500, 250) add_connected_players(game, [players.hosting, players.joining]) await game.launch() game.set_player_option(players.hosting.id, 'Team', 1) game.set_player_option(players.joining.id, 'Team', 1) host_outcome = game.outcome(players.hosting) guest_outcome = game.outcome(players.joining) assert host_outcome is None assert guest_outcome is None
async def test_compute_rating_computes_global_ratings(game: Game, players): await game.clear_data() game.state = GameState.LOBBY players.hosting.global_rating = Rating(1500, 250) players.joining.global_rating = Rating(1500, 250) add_connected_players(game, [players.hosting, players.joining]) await game.launch() await game.add_result(players.hosting, 0, 'victory', 1) await game.add_result(players.joining, 1, 'defeat', 0) game.set_player_option(players.hosting.id, 'Team', 2) game.set_player_option(players.joining.id, 'Team', 3) groups = game.compute_rating() assert players.hosting in groups[0] assert players.joining in groups[1]
async def test_compute_rating_computes_ladder_ratings(game: Game, players): await game.clear_data() game.state = GameState.LOBBY players.hosting.ladder_rating = Rating(1500, 250) players.joining.ladder_rating = Rating(1500, 250) add_connected_players(game, [players.hosting, players.joining]) await game.launch() await game.add_result(players.hosting, 0, 'victory', 1) await game.add_result(players.joining, 1, 'defeat', 0) game.set_player_option(players.hosting.id, 'Team', 1) game.set_player_option(players.joining.id, 'Team', 1) groups = game.compute_rating(rating='ladder') assert players.hosting in groups[0] assert players.joining in groups[1]
async def test_to_dict(game, create_player): await game.clear_data() game.state = GameState.LOBBY players = [( create_player(**info), result, team ) for info, result, team in [ (dict(login='******', id=1, global_rating=Rating(1500, 250.7)), 0, 1), (dict(login='******', id=2, global_rating=Rating(1700, 120.1)), 0, 1), (dict(login='******', id=3, global_rating=Rating(1200, 72.02)), 0, 2), (dict(login='******', id=4, global_rating=Rating(1200, 72.02)), 0, 2), ]] add_connected_players(game, [player for player, _, _ in players]) for player, _, team in players: game.set_player_option(player.id, 'Team', team) game.set_player_option(player.id, 'Army', player.id - 1) game.host = players[0][0] await game.launch() data = game.to_dict() expected = { "command": "game_info", "visibility": VisibilityState.to_string(game.visibility), "password_protected": game.password is not None, "uid": game.id, "title": game.sanitize_name(game.name), "state": 'playing', "featured_mod": game.game_mode, "featured_mod_versions": game.getGamemodVersion(), "sim_mods": game.mods, "mapname": game.map_folder_name, "map_file_path": game.map_file_path, "host": game.host.login, "num_players": len(game.players), "max_players": game.max_players, "launched_at": game.launched_at, "teams": { team: [ player.login for player in game.players if game.get_player_option(player.id, 'Team') == team ] for team in game.teams } } assert data == expected
async def test_rate_game_late_abort_no_enforce(game_service, game_stats_service, custom_game): custom_game.state = GameState.LOBBY players = [ Player(id=1, login='******', global_rating=(1500, 500)), Player(id=2, login='******', global_rating=(1500, 500)), ] add_connected_players(custom_game, players) custom_game.set_player_option(1, 'Team', 2) custom_game.set_player_option(2, 'Team', 3) await custom_game.launch() await custom_game.add_result(0, 1, 'VICTORY', 5) custom_game.launched_at = time.time() - 600 # seconds await custom_game.on_game_end() assert custom_game.validity == ValidityState.VALID
async def test_to_dict(game, player_factory): game.state = GameState.LOBBY players = [(player_factory(f"{i}", player_id=i, global_rating=rating), result, team) for i, (rating, result, team) in enumerate([ (Rating(1500, 250), 0, 1), (Rating(1700, 120), 0, 1), (Rating(1200, 72), 0, 2), (Rating(1200, 72), 0, 2), ], 1)] add_connected_players(game, [player for player, _, _ in players]) for player, _, team in players: game.set_player_option(player.id, "Team", team) game.set_player_option(player.id, "Army", player.id - 1) game.host = players[0][0] await game.launch() data = game.to_dict() expected = { "command": "game_info", "visibility": game.visibility.value, "password_protected": game.password is not None, "uid": game.id, "title": game.sanitize_name(game.name), "game_type": "custom", "state": "playing", "featured_mod": game.game_mode, "sim_mods": game.mods, "mapname": game.map_folder_name, "map_file_path": game.map_file_path, "host": game.host.login, "num_players": len(game.players), "max_players": game.max_players, "launched_at": game.launched_at, "rating_type": game.rating_type, "rating_min": game.displayed_rating_range.lo, "rating_max": game.displayed_rating_range.hi, "enforce_rating_range": game.enforce_rating_range, "teams": { team: [ player.login for player in game.players if game.get_player_option(player.id, "Team") == team ] for team in game.teams } } assert data == expected
async def test_game_outcomes_conflicting(game: Game, database, players): game.state = GameState.LOBBY players.hosting.ratings[RatingType.LADDER_1V1] = Rating(1500, 250) players.joining.ratings[RatingType.LADDER_1V1] = Rating(1500, 250) add_connected_players(game, [players.hosting, players.joining]) await game.launch() await game.add_result(players.hosting.id, 0, "victory", 1) await game.add_result(players.joining.id, 1, "victory", 0) await game.add_result(players.hosting.id, 0, "defeat", 1) await game.add_result(players.joining.id, 1, "defeat", 0) game.set_player_option(players.hosting.id, "Team", 1) game.set_player_option(players.joining.id, "Team", 1) host_outcome = game.get_player_outcome(players.hosting) guest_outcome = game.get_player_outcome(players.joining) assert host_outcome is GameOutcome.CONFLICTING assert guest_outcome is GameOutcome.CONFLICTING
async def test_game_outcomes_no_results(game: Game, database, players): game.state = GameState.LOBBY players.hosting.ratings[RatingType.LADDER_1V1] = Rating(1500, 250) players.joining.ratings[RatingType.LADDER_1V1] = Rating(1500, 250) add_connected_players(game, [players.hosting, players.joining]) await game.launch() game.set_player_option(players.hosting.id, "Team", 1) game.set_player_option(players.joining.id, "Team", 1) host_outcome = game.get_player_outcome(players.hosting) guest_outcome = game.get_player_outcome(players.joining) assert host_outcome is GameOutcome.UNKNOWN assert guest_outcome is GameOutcome.UNKNOWN await game.on_game_end() expected_scores = {(players.hosting.id, 0), (players.joining.id, 0)} assert await game_player_scores(database, game) == expected_scores
async def test_game_outcomes(game: Game, players): await game.clear_data() game.state = GameState.LOBBY players.hosting.ladder_rating = Rating(1500, 250) players.joining.ladder_rating = Rating(1500, 250) add_connected_players(game, [players.hosting, players.joining]) await game.launch() await game.add_result(players.hosting, 0, 'victory', 1) await game.add_result(players.joining, 1, 'defeat', 0) game.set_player_option(players.hosting.id, 'Team', 1) game.set_player_option(players.joining.id, 'Team', 1) host_outcome = game.outcome(players.hosting) guest_outcome = game.outcome(players.joining) assert host_outcome is GameOutcome.VICTORY assert guest_outcome is GameOutcome.DEFEAT
async def test_clear_slot(game: Game, mock_game_connection: GameConnection): game.state = GameState.LOBBY players = [ Player(id=1, login='******', global_rating=(1500, 500)), Player(id=2, login='******', global_rating=(1500, 500)) ] add_connected_players(game, players) game.set_ai_option('rush', 'StartSpot', 3) game.clear_slot(0) game.clear_slot(3) assert game.get_player_option(1, 'StartSpot') == -1 assert game.get_player_option(1, 'Team') == -1 assert game.get_player_option(1, 'Army') == -1 assert game.get_player_option(2, 'StartSpot') == 1 assert 'rush' not in game.AIs
async def test_single_wrong_report_still_rated_correctly( game: Game, player_factory): # based on replay with UID 11255492 # Mocking out database calls, since not all player IDs exist. game.update_game_player_stats = CoroutineMock() game.state = GameState.LOBBY # Loading log data with open("tests/data/uid11255492.log.json", "r") as f: log_dict = json.load(f) old_rating = 1500 players = { player_id: player_factory( login=f"{player_id}", player_id=player_id, global_rating=Rating(old_rating, 250), with_lobby_connection=False, ) for team in log_dict["teams"].values() for player_id in team } add_connected_players(game, list(players.values())) for team_id, team_list in log_dict["teams"].items(): for player_id in team_list: game.set_player_option(player_id, "Team", team_id) game.set_player_option(player_id, "Army", player_id - 1) await game.launch() for reporter, reportee, outcome, score in log_dict["results"]: await game.add_result(players[reporter], reportee, outcome, score) rating_service = game.game_service._rating_service await game.on_game_end() await rating_service._join_rating_queue() results = get_persisted_results(rating_service) winning_ids = log_dict["teams"][str(log_dict["winning_team"])] for player_id, new_rating in results.ratings.items(): if player_id in winning_ids: assert new_rating.mu > old_rating else: assert new_rating.mu < old_rating
async def test_rate_game_late_abort_no_enforce(game_service, game_stats_service, custom_game): custom_game.state = GameState.LOBBY players = [ Player(id=1, login='******', global_rating=(1500, 500)), Player(id=2, login='******', global_rating=(1500, 500)), ] add_connected_players(custom_game, players) custom_game.set_player_option(1, 'Team', 2) custom_game.set_player_option(2, 'Team', 3) await custom_game.launch() await custom_game.add_result(0, 1, 'VICTORY', 5) custom_game.launched_at = time.time() - 600 # seconds await custom_game.on_game_end() assert custom_game.validity == ValidityState.VALID
async def test_rate_game_late_abort_no_enforce(game_service, game_stats_service, custom_game, player_factory): custom_game.state = GameState.LOBBY players = [ player_factory("Dostya", player_id=1, global_rating=(1500, 500)), player_factory("Rhiza", player_id=2, global_rating=(1500, 500)), ] add_connected_players(custom_game, players) custom_game.set_player_option(1, "Team", 2) custom_game.set_player_option(2, "Team", 3) await custom_game.launch() await custom_game.add_result(0, 1, "victory", 5) custom_game.launched_at = time.time() - 600 # seconds await custom_game.on_game_end() assert custom_game.validity == ValidityState.VALID
async def test_clear_slot(game: Game, mock_game_connection: GameConnection, player_factory): game.state = GameState.LOBBY players = [ player_factory("Dostya", player_id=1, global_rating=(1500, 500)), player_factory("Rhiza", player_id=2, global_rating=(1500, 500)) ] add_connected_players(game, players) game.set_ai_option("rush", "StartSpot", 3) game.clear_slot(0) game.clear_slot(3) assert game.get_player_option(1, "StartSpot") == -1 assert game.get_player_option(1, "Team") == -1 assert game.get_player_option(1, "Army") == -1 assert game.get_player_option(2, "StartSpot") == 1 assert "rush" not in game.AIs
async def test_clear_slot(game: Game, mock_game_connection: GameConnection): game.state = GameState.LOBBY players = [ Player(id=1, login='******', global_rating=(1500, 500)), Player(id=2, login='******', global_rating=(1500, 500)) ] add_connected_players(game, players) game.set_ai_option('rush', 'StartSpot', 3) game.clear_slot(0) game.clear_slot(3) assert game.get_player_option(1, 'StartSpot') == -1 assert game.get_player_option(1, 'Team') == -1 assert game.get_player_option(1, 'Army') == -1 assert game.get_player_option(2, 'StartSpot') == 1 assert 'rush' not in game.AIs
async def test_report_army_stats_sends_stats_for_defeated_player(game: Game): game.state = GameState.LOBBY players = [ Player(id=1, login='******', global_rating=(1500, 500)), Player(id=2, login='******', global_rating=(1500, 500)) ] add_connected_players(game, players) await game.launch() await game.add_result(0, 1, 'defeat', -1) with open("tests/data/game_stats_simple_win.json", "r") as stats_file: stats = stats_file.read() await game.report_army_stats(stats) game._game_stats_service.process_game_stats.assert_called_once_with( players[1], game, stats)
async def test_compute_rating_does_not_rate_double_win(game: Game, player_factory): game.state = GameState.LOBBY players = [(player_factory(f"{i}", player_id=i, global_rating=rating), result, team) for i, (rating, result, team) in enumerate([ (Rating(1500, 250), 10, 2), (Rating(1700, 120), 0, 3), ], 1)] add_connected_players(game, [player for player, _, _ in players]) for player, _, team in players: game.set_player_option(player.id, 'Team', team) game.set_player_option(player.id, 'Army', player.id - 1) await game.launch() for player, result, _ in players: await game.add_result(player, player.id - 1, 'victory', result) with pytest.raises(GameRatingError): game.compute_rating()
async def test_persist_results_called_with_two_players(game): await game.clear_data() game.state = GameState.LOBBY players = [ Player(id=1, login='******', global_rating=(1500, 500)), Player(id=2, login='******', global_rating=(1500, 500)) ] add_connected_players(game, players) await game.launch() assert len(game.players) == 2 await game.add_result(0, 1, 'VICTORY', 5) await game.on_game_end() assert game.get_army_result(1) == 5 assert len(game.players) == 2 await game.load_results() assert game.get_army_result(1) == 5
async def test_to_dict(game, create_player): await game.clear_data() game.state = GameState.LOBBY players = [ (create_player(**info), result, team) for info, result, team in [ (dict(login='******', id=1, global_rating=Rating(1500, 250.7)), 0, 1), (dict(login='******', id=2, global_rating=Rating(1700, 120.1)), 0, 1), (dict(login='******', id=3, global_rating=Rating(1200, 72.02)), 0, 2), (dict(login='******', id=4, global_rating=Rating(1200, 72.02)), 0, 2), ] ] add_connected_players(game, [player for player, _, _ in players]) for player, _, team in players: game.set_player_option(player.id, 'Team', team) game.set_player_option(player.id, 'Army', player.id - 1) game.host = players[0][0] await game.launch() data = game.to_dict() expected = { "command": "game_info", "visibility": VisibilityState.to_string(game.visibility), "password_protected": game.password is not None, "uid": game.id, "title": game.name, "state": 'playing', "featured_mod": game.game_mode, "featured_mod_versions": game.getGamemodVersion(), "sim_mods": game.mods, "mapname": game.map_folder_name, "map_file_path": game.map_file_path, "host": game.host.login, "num_players": len(game.players), "max_players": game.max_players, "launched_at": game.launched_at, "teams": { team: [player.login for player in game.players if game.get_player_option(player.id, 'Team') == team] for team in game.teams } } assert data == expected
async def test_compute_rating_sum_of_scores_edge_case(game: Game, player_factory): """ For certain scores, compute_rating was determining the winner incorrectly, see issue <https://github.com/FAForever/server/issues/485>. """ game.state = GameState.LOBBY win_team = 2 lose_team = 3 players = [(player_factory(login=f"{i}", player_id=i, global_rating=rating, with_lobby_connection=False), result, team) for i, (rating, result, team) in enumerate([ (Rating(1500, 200), 1, lose_team), (Rating(1500, 200), 1, lose_team), (Rating(1500, 200), 1, lose_team), (Rating(1500, 200), -10, lose_team), (Rating(1500, 200), 10, win_team), (Rating(1500, 200), -10, win_team), (Rating(1500, 200), -10, win_team), (Rating(1500, 200), 2, win_team), ], 1)] add_connected_players(game, [player for player, _, _ in players]) for player, _, team in players: game.set_player_option(player.id, 'Team', team) game.set_player_option(player.id, 'Army', player.id - 1) await game.launch() for player, result, team in players: outcome = 'victory' if team is win_team else 'defeat' await game.add_result(player, player.id - 1, outcome, result) result = game.compute_rating() for team in result: for player, new_rating in team.items(): old_rating = Rating(*player.ratings[RatingType.GLOBAL]) if player.id > 4: # `team` index in result might not coincide with `team` index in players assert new_rating > old_rating else: assert new_rating < old_rating
async def test_compute_rating_only_one_surviver(game: Game, player_factory): """ When a player dies their score is reported as "defeat", but this does not necessarily mean they lost the game, if their team mates went on and later reported a "victory". """ game.state = GameState.LOBBY win_team = 2 lose_team = 3 players = [(player_factory(login=f"{i}", player_id=i, global_rating=Rating(1500, 200), with_lobby_connection=False), outcome, result, team) for i, (outcome, result, team) in enumerate([ ("defeat", -10, lose_team), ("defeat", -10, lose_team), ("defeat", -10, lose_team), ("defeat", -10, lose_team), ("defeat", -10, win_team), ("defeat", -10, win_team), ("defeat", -10, win_team), ("victory", 10, win_team), ], 1)] add_connected_players(game, [player for player, _, _, _ in players]) for player, _, _, team in players: game.set_player_option(player.id, 'Team', team) game.set_player_option(player.id, 'Army', player.id - 1) await game.launch() for player, outcome, result, team in players: await game.add_result(player, player.id - 1, outcome, result) result = game.compute_rating() for team in result: for player, new_rating in team.items(): old_rating = Rating(*player.ratings[RatingType.GLOBAL]) # `team` index in result might not coincide with `team` index in players if player.id > 4: assert new_rating > old_rating else: assert new_rating < old_rating
async def test_on_game_end_ladder_ratings_(ladder_game, players): rating_service = ladder_game.game_service._rating_service ladder_game.state = GameState.LOBBY add_connected_players(ladder_game, [players.hosting, players.joining]) ladder_game.set_player_option(players.hosting.id, "Team", 1) ladder_game.set_player_option(players.joining.id, "Team", 1) await ladder_game.launch() await ladder_game.add_result(players.hosting.id, 0, "victory", 1) await ladder_game.add_result(players.joining.id, 1, "defeat", 0) await ladder_game.on_game_end() await rating_service._join_rating_queue() results = get_persisted_results(rating_service) assert results.rating_type is RatingType.LADDER_1V1 assert players.hosting.id in results.ratings assert players.joining.id in results.ratings assert results.outcomes[players.hosting.id] is GameOutcome.VICTORY assert results.outcomes[players.joining.id] is GameOutcome.DEFEAT
async def test_compute_rating_balanced_teamgame(game: Game, create_player): await game.clear_data() game.state = GameState.LOBBY players = [ (create_player(**info), result, team) for info, result, team in [ (dict(login='******', id=1, global_rating=Rating(1500, 250.7)), 0, 1), (dict(login='******', id=2, global_rating=Rating(1700, 120.1)), 0, 1), (dict(login='******', id=3, global_rating=Rating(1200, 72.02)), 0, 2), (dict(login='******', id=4, global_rating=Rating(1200, 72.02)), 0, 2), ] ] add_connected_players(game, [player for player, _, _ in players]) for player, _, team in players: game.set_player_option(player.id, 'Team', team) game.set_player_option(player.id, 'Army', player.id - 1) await game.launch() for player, result, _ in players: await game.add_result(player, player.id - 1, 'score', result) result = game.compute_rating() for team in result: for player, new_rating in team.items(): assert player in game.players assert new_rating != Rating(*player.global_rating)
def test_game_teams_represents_active_teams(game: Game, players): game.state = GameState.LOBBY add_connected_players(game, [players.hosting, players.joining]) game.set_player_option(players.hosting.id, 'Team', 1) game.set_player_option(players.joining.id, 'Team', 2) assert game.teams == {1, 2}