예제 #1
0
    def _score_entries_top_k_players(self, team: Team, challenge: Challenge, gamedb: Database, engine: Engine) -> List[Player]:
        player_scores = {}
        top_scores = list()
        losing_players = list()
        entries = gamedb.stream_entries(
            from_team=team, from_challenge=challenge)

        with ThreadPoolExecutor(max_workers=self._options.engine_worker_thread_count) as executor:
            executor.submit(self._score_entries_top_k_players_fn,
                            entries=entries, challenge=challenge, score_dict=player_scores, gamedb=gamedb, engine=engine)

        for player_id, score in player_scores.items():
            heapq.heappush(top_scores, (score, player_id))

        # note that the default python heap pops in ascending order,
        # so the rank here is actually worst to best.
        num_scores = len(top_scores)
        if num_scores == 1:
            raise GameError(
                "Unable to rank losing players with team size = 1.")
        else:
            for rank in range(num_scores):
                score, player_id = heapq.heappop(top_scores)
                log_message("Player {} rank {} with score {}.".format(
                    player_id, rank, score))

                # all but the highest scorer lose
                if rank < (num_scores - 1):
                    losing_players.append(gamedb.player_from_id(player_id))

        return losing_players
예제 #2
0
    def _score_entries_tribe_aggregate(self, tribe: Tribe,
                                       challenge: Challenge, gamedb: Database,
                                       engine: Engine):
        score_dict = {'score': 0}
        players = gamedb.count_players(from_tribe=tribe)
        entries = gamedb.stream_entries(from_tribe=tribe,
                                        from_challenge=challenge)

        with ThreadPoolExecutor(max_workers=self._options.
                                engine_worker_thread_count) as executor:
            executor.submit(self._score_entries_tribe_aggregate_fn,
                            entries=entries,
                            challenge=challenge,
                            score_dict=score_dict,
                            gamedb=gamedb,
                            engine=engine)

        # tribe score = avg score of all tribe members
        log_message(message="_score_entries_tribe_agg = {}.".format(
            score_dict['score']),
                    game_id=self._game_id)

        if players > 0:
            return score_dict['score'] / players
        return 0
예제 #3
0
    def _score_entries_top_k_teams(
            self, k: float, tribe: Tribe, challenge: Challenge,
            gamedb: Database, engine: Engine) -> Tuple[List[Team], List[Team]]:
        team_scores = {}
        top_scores = list()
        winning_teams = list()
        losing_teams = list()

        entries = gamedb.stream_entries(from_tribe=tribe,
                                        from_challenge=challenge)

        with ThreadPoolExecutor(max_workers=self._options.
                                engine_worker_thread_count) as executor:
            executor.submit(self._score_entries_top_k_teams_fn,
                            entries=entries,
                            challenge=challenge,
                            score_dict=team_scores,
                            gamedb=gamedb,
                            engine=engine)

        for team_id, score in team_scores.items():
            heapq.heappush(
                top_scores,
                (score /
                 gamedb.count_players(from_team=gamedb.team_from_id(team_id)),
                 team_id))

        rank_threshold = float(k * len(top_scores))
        log_message(message="Rank threshold = {}".format(rank_threshold),
                    game_id=self._game_id)

        # note that the default python heap pops in ascending order,
        # so the rank here is actually worst to best.
        num_scores = len(top_scores)
        if num_scores == 1:
            score, team_id = heapq.heappop(top_scores)
            log_message(message="Winner {}.".format(team_id),
                        game_id=self._game_id)
            winning_teams = [gamedb.team_from_id(team_id)]
        else:
            for rank in range(num_scores):
                score, team_id = heapq.heappop(top_scores)
                log_message(message="Team {} rank {} with score {}.".format(
                    team_id, rank, score),
                            game_id=self._game_id)
                if rank >= rank_threshold:
                    log_message(message="Winner {}.".format(team_id),
                                game_id=self._game_id)
                    winning_teams.append(gamedb.team_from_id(team_id))
                else:
                    log_message(message="Loser {}.".format(team_id),
                                game_id=self._game_id)
                    losing_teams.append(gamedb.team_from_id(team_id))

        return (winning_teams, losing_teams)