Example #1
0
    def test__generate_teams_returns_correct_number_of_teams(self):
        subject = schedule_generator.ScheduleGenerator()

        teams = subject._generate_teams()

        expected_num_teams = NUM_CONFERENCES * NUM_DIVISIONS_PER_CONFERENCE * NUM_TEAMS_PER_DIVISION

        self.assertEqual(expected_num_teams, len(teams))
    def test_simulate_season(self):
        subject = league.League(num_players=10,
                                schedule=schedule_generator.ScheduleGenerator(
                                ).generate_schedule())

        subject.simulate_season()

        num_still_alive = len([p for p in subject.PLAYERS if p.is_alive()])
        self.assertTrue(num_still_alive < len(subject.PLAYERS))
        self.assertEqual(subject._num_active_players(), num_still_alive)
Example #3
0
    def test_generate_schedule_returns_correct_number_of_weeks_with_correct_number_of_games(
            self):
        subject = schedule_generator.ScheduleGenerator()

        result = subject.generate_schedule().weeks

        self.assertEqual(len(result), NUM_WEEKS)
        for week in result:
            self.assertTrue(
                len(week.games) <= NUM_CONFERENCES *
                NUM_DIVISIONS_PER_CONFERENCE * NUM_TEAMS_PER_DIVISION / 2.0)
    def test__num_active_players(self):
        subject = league.League(num_players=10,
                                schedule=schedule_generator.ScheduleGenerator(
                                ).generate_schedule())

        self.assertEqual(subject._num_active_players(), len(subject.PLAYERS))

        subject.PLAYERS[0].eliminate(0)

        self.assertEqual(subject._num_active_players(),
                         len(subject.PLAYERS) - 1)
    def test__choose_teams(self):
        subject = league.League(num_players=10,
                                schedule=schedule_generator.ScheduleGenerator(
                                ).generate_schedule())

        with patch('survivor_league.player.Player.choose_team',
                   return_value='winner'):
            choices = subject._choose_teams(subject.SCHEDULE.weeks[0].games)

        for player in subject.PLAYERS:
            self.assertTrue(player.name() in choices)
            self.assertEqual(choices[player.name()], 'winner')
    def test__determine_game_winners(self):
        subject = league.League(num_players=10,
                                schedule=schedule_generator.ScheduleGenerator(
                                ).generate_schedule())
        games = subject.SCHEDULE.weeks[0].games
        home_teams = [g.home_team for g in games]

        with patch('random.random', return_value=0):
            winners_names = subject._determine_game_winners(
                subject.SCHEDULE.weeks[0].games)

        self.assertEqual(len(home_teams), len(winners_names))
        for t in home_teams:
            self.assertTrue(t.name in winners_names)
    def test__eliminate_losers(self):
        subject = league.League(num_players=10,
                                schedule=schedule_generator.ScheduleGenerator(
                                ).generate_schedule())

        choices = dict()
        for p in subject.PLAYERS:
            choices[p.name()] = 0
        choices[subject.PLAYERS[0].name()] = 1

        winning_team_names = [0]

        subject._eliminate_losers(choices, winning_team_names, 300)

        self.assertListEqual(subject._active_players(), subject.PLAYERS[1:])
        self.assertFalse(subject.PLAYERS[0].is_alive())
        self.assertEqual(subject.PLAYERS[0]._elimination_week_num, 300)
    def test__simulate_week(self):
        subject = league.League(num_players=10,
                                schedule=schedule_generator.ScheduleGenerator(
                                ).generate_schedule())
        week_to_simulate = subject.SCHEDULE.weeks[0]
        games = week_to_simulate.games

        home_teams = set()
        away_teams = set()
        for game in games:
            for player in subject.PLAYERS:
                self.assertFalse(player.have_chosen_team(game.home_team.name))
                self.assertFalse(player.have_chosen_team(game.away_team.name))

            home_teams.add(game.home_team)
            away_teams.add(game.away_team)

        # home team wins every game
        with patch('random.random', return_value=0):
            subject._simulate_week(week_to_simulate)

        alive_players = [
            player for player in subject.PLAYERS if player.is_alive()
        ]
        eliminated_players = [
            player for player in subject.PLAYERS if not player.is_alive()
        ]

        for player in alive_players:
            self.assertEqual(
                len([t for t in home_teams
                     if player.have_chosen_team(t.name)]), 1)
            self.assertEqual(
                len([t for t in away_teams
                     if player.have_chosen_team(t.name)]), 0)

        for player in eliminated_players:
            self.assertEqual(
                len([t for t in home_teams
                     if player.have_chosen_team(t.name)]), 0)
            self.assertEqual(
                len([t for t in away_teams
                     if player.have_chosen_team(t.name)]), 1)
Example #9
0
    def test_assign_games_randomly(self):
        subject = schedule_generator.ScheduleGenerator()
        result = subject.generate_schedule().weeks

        first_half_weeks = result[:int(len(result) / 2)]
        second_half_weeks = result[-int(len(result) / 2):]

        # Each week, there is a greater than 1 / (num_weeks / num_other_teams) chance one team plays another
        num_weeks = NUM_WEEKS - NUM_BYES
        num_teams = NUM_TEAMS_PER_DIVISION * NUM_DIVISIONS_PER_CONFERENCE * NUM_CONFERENCES
        expected_games = (num_weeks - 1) / (num_teams - 1) / 2 + 1
        max_allowable_games = expected_games + 1

        num_successes = 0
        num_failures = 0

        for early_week in first_half_weeks:
            for game in early_week.games:
                t1 = game.home_team
                t2 = game.away_team

                times_played = 1

                for late_week in second_half_weeks:
                    for late_game in late_week.games:
                        if late_game.home_team in {
                                t1, t2
                        } and late_game.away_team in {t1, t2}:
                            times_played += 1

                    if times_played < max_allowable_games:
                        num_successes += 1
                    else:
                        num_failures += 1

        minimum_valid_ratio = 900 / 25
        if num_failures == 0:
            num_successes += minimum_valid_ratio
            num_failures += 1
        self.assertTrue(num_successes / num_failures > minimum_valid_ratio)
Example #10
0
    def test__give_teams_byes_gives_the_right_number_of_teams_byes(self):
        # This test is by design intentionally slightly flaky.  If you encounter an error with the assertions,
        #  try running again.
        subject = schedule_generator.ScheduleGenerator()

        n_trials = 100
        sum_num_non_bye_teams = 0
        for i in range(n_trials):
            non_bye = subject._filter_bye_teams(subject._generate_teams())
            self.assertTrue(len(non_bye) % 2 == 0)
            sum_num_non_bye_teams += len(non_bye)

        num_non_bye_teams = float(sum_num_non_bye_teams) / n_trials

        num_teams = NUM_CONFERENCES * NUM_DIVISIONS_PER_CONFERENCE * NUM_TEAMS_PER_DIVISION
        expected_avg_num_non_byes = num_teams - float(
            NUM_BYES) / NUM_WEEKS * num_teams
        allowable_num_bye_difference = 1
        self.assertTrue(num_non_bye_teams > expected_avg_num_non_byes -
                        allowable_num_bye_difference)
        self.assertTrue(num_non_bye_teams < expected_avg_num_non_byes +
                        allowable_num_bye_difference)
def run_simulation():
    strategy_victory_outcome_dict = dict()
    strategy_victory_dict = dict()
    strategy_elimination_week_dict = dict()
    strategy_end_result_dict = dict()
    strategy_cumulative_elimination_probability = dict()
    strategy_average_winnings_dict = dict()
    num_weeks = 0
    num_winners = 0

    for strategy in league.STRATEGIES:
        strategy_name = strategy().name
        strategy_victory_outcome_dict[strategy_name] = 0
        strategy_victory_dict[strategy_name] = 0
        strategy_elimination_week_dict[strategy_name] = dict()
        strategy_end_result_dict[strategy_name] = dict()
        strategy_average_winnings_dict[strategy_name] = 0

    for _ in range(NUM_SIMULATIONS):
        schedule = schedule_generator.ScheduleGenerator().generate_schedule()
        lg = league.League(NUM_PLAYERS, schedule)
        lg.simulate_season()
        results = lg.PLAYERS
        was_tie = len([result for result in results if result.is_alive()]) == 0

        simulation_weeks = 0
        for result in results:
            if result.elimination_week() is None:
                continue
            simulation_weeks = max(simulation_weeks, result.elimination_week())
        num_weeks += simulation_weeks

        simulation_winners = [result for result in results if
                              result.is_alive() or (was_tie and result.elimination_week() == simulation_weeks)]
        num_winners += len(simulation_winners)

        for winner in simulation_winners:
            strategy_victory_dict[winner.strategy_name()] += 1 / len(simulation_winners)
            strategy_victory_outcome_dict[winner.strategy_name()] += 1 / (len(results) - len(simulation_winners) + 1)
            strategy_average_winnings_dict[winner.strategy_name()] += 1

        strategy_player_count = dict()
        for result in results:
            if result.strategy_name() not in strategy_player_count:
                strategy_player_count[result.strategy_name()] = 0
            strategy_player_count[result.strategy_name()] += 1
        strategy_loser_count = dict()
        for result in results:
            if result.is_alive() or (was_tie and result.elimination_week() == simulation_weeks):
                continue
            if result.strategy_name() not in strategy_loser_count:
                strategy_loser_count[result.strategy_name()] = 0
            strategy_loser_count[result.strategy_name()] += 1
        for result in results:
            if result.is_alive() or (was_tie and result.elimination_week() == simulation_weeks):
                continue
            if result.elimination_week() not in strategy_elimination_week_dict[result.strategy_name()]:
                for week in range(result.elimination_week()):
                    if week not in strategy_elimination_week_dict[result.strategy_name()]:
                        strategy_elimination_week_dict[result.strategy_name()][week] = 0
                        strategy_end_result_dict[result.strategy_name()][week] = 0
                strategy_elimination_week_dict[result.strategy_name()][result.elimination_week()] = 0
                strategy_end_result_dict[result.strategy_name()][result.elimination_week()] = 0
            strategy_elimination_week_dict[result.strategy_name()][result.elimination_week()] += \
                1 / strategy_loser_count[result.strategy_name()]
            strategy_end_result_dict[result.strategy_name()][result.elimination_week()] += \
                1 / strategy_player_count[result.strategy_name()]

    for k in strategy_victory_dict.keys():
        strategy_victory_dict[k] /= NUM_SIMULATIONS
    for k in strategy_victory_outcome_dict.keys():
        strategy_victory_outcome_dict[k] /= NUM_SIMULATIONS
    for s in strategy_elimination_week_dict.keys():
        for w in strategy_elimination_week_dict[s]:
            strategy_elimination_week_dict[s][w] /= NUM_SIMULATIONS
    for s in strategy_end_result_dict.keys():
        if s not in strategy_cumulative_elimination_probability:
            strategy_cumulative_elimination_probability[s] = {0: 0}
        for w in strategy_end_result_dict[s]:
            strategy_end_result_dict[s][w] /= NUM_SIMULATIONS
            strategy_cumulative_elimination_probability[s][w] = 0
            for wn in range(w):
                strategy_cumulative_elimination_probability[s][w] += strategy_end_result_dict[s][wn]
            strategy_cumulative_elimination_probability[s][w] += strategy_end_result_dict[s][w]
    for s in league.STRATEGIES:
        strategy_name = s().name
        strategy_average_winnings_dict[strategy_name] = strategy_victory_dict[strategy_name] / \
            strategy_average_winnings_dict[strategy_name] * NUM_SIMULATIONS * \
            strategy_victory_outcome_dict[strategy_name]
    scale = 1 / sum([v for v in strategy_average_winnings_dict.values()])
    for s in league.STRATEGIES:
        strategy_name = s().name
        strategy_average_winnings_dict[strategy_name] *= scale

    print("Average maximum simulation week number:")
    print(num_weeks / NUM_SIMULATIONS)
    print("Average number of winners:")
    print(num_winners / NUM_SIMULATIONS)
    print("Odds a strategy wins:")
    print(strategy_victory_dict)
    print("Odds of winning, by strategy:")
    print(strategy_victory_outcome_dict)
    print("Odds of being eliminated in a week, by strategy")
    for strategy, elimination_odds in strategy_end_result_dict.items():
        print(strategy, elimination_odds)
    print("Elimination week distribution, by strategy:")
    for strategy, elimination_odds in strategy_elimination_week_dict.items():
        print(strategy, elimination_odds)
    print("Cumulative elimination probability, by strategy")
    for strategy, elimination_odds in strategy_cumulative_elimination_probability.items():
        print(strategy, elimination_odds)
    print("Average player winnings, by strategy")
    print(strategy_average_winnings_dict)
    def test__generate_players(self):
        subject = league.League(num_players=10,
                                schedule=schedule_generator.ScheduleGenerator(
                                ).generate_schedule())

        self.assertEqual(len(subject.PLAYERS), 10)