示例#1
0
def generate_ranking(dao, now=datetime.now()):
    player_date_map = {}
    player_id_to_player_map = {}

    tournaments = dao.get_all_tournaments(regions=[dao.region_id])
    for tournament in tournaments:
        print 'Processing:', tournament.name

        for player_id in tournament.players:
            player_date_map[player_id] = tournament.date

        # TODO add a default rating entry when we add it to the map
        for match in tournament.matches:
            if not match.winner in player_id_to_player_map:
                db_player = dao.get_player_by_id(match.winner)
                db_player.ratings[dao.region_id] = DEFAULT_RATING
                player_id_to_player_map[match.winner] = db_player

            if not match.loser in player_id_to_player_map:
                db_player = dao.get_player_by_id(match.loser)
                db_player.ratings[dao.region_id] = DEFAULT_RATING
                player_id_to_player_map[match.loser] = db_player

            winner = player_id_to_player_map[match.winner]
            loser = player_id_to_player_map[match.loser]
            
            rating_calculators.update_trueskill_ratings(dao.region_id, winner=winner, loser=loser)

    print 'Checking for player inactivity...'
    i = 1
    players = player_id_to_player_map.values()
    sorted_players = sorted(
            players, 
            key=lambda player: trueskill.expose(player.ratings[dao.region_id].trueskill_rating), reverse=True)
    ranking = []
    for player in sorted_players:
        player_last_active_date = player_date_map.get(player.id)
        if player_last_active_date == None or dao.is_inactive(player, now) or not dao.region_id in player.regions:
            pass # do nothing, skip this player
        else:
            ranking.append(RankingEntry(i, player.id, trueskill.expose(player.ratings[dao.region_id].trueskill_rating)))
            i += 1

    print 'Updating players...'
    for i, p in enumerate(players, start=1):
        dao.update_player(p)
        print 'Updated player %d of %d' % (i, len(players))

    print 'Inserting new ranking...'
    dao.insert_ranking(Ranking(dao.region_id, now, [t.id for t in tournaments], ranking))

    print 'Done!'
示例#2
0
def quality_and_probability(players, names):
    p0, p1 = players[names[0]], players[names[1]]
    quality = trueskill.quality_1vs1(p0, p1)
    probability = arduino_map((1-quality)*100, 0, 100, 50, 100)/100
    ex0, ex1 = trueskill.expose(p0), trueskill.expose(p1)
    if ex0 == ex1:
        favor = None
    elif ex0>ex1:
        favor = names[0]
    else:
        favor = names[1]

    return quality, probability, favor
示例#3
0
文件: views.py 项目: jztd/sc2_live
def display(request):
	#this is the main view
	#it's going to get all of our awesome players from the database
	#and create a leaderboard time thing from them based on their 
	#ratings...it sounds stupid simple but it will probably be harder than anything else here
	all_players = player.objects.all()
	player_list = {}
	final_list = []
	player_skills = []
	player_rounded_skills = []
	for each in all_players:
		if each.wins + each.losses > 5:
			player_mu = each.mu
			player_sigma = each.sigma
			player_rating = Decimal(expose(Rating(float(player_mu), float(player_sigma))))
			#if player_rating in player_list:
			#	player_rating += Decimal(.000000000000000000000000001)
			player_list[player_rating] = each
	sorted_player_list = sorted(player_list, reverse=True)
	for each in sorted_player_list:
		final_list.append(player_list[each])
		player_skills.append(each)
	index_list = range(1, len(all_players)+1)
	for each in player_skills:
		player_rounded_skills.append(round(each, 1))
	zipped_list = zip(final_list, player_rounded_skills, index_list)
	return render(request, 'display.html', {'player_list': final_list, 'skill_list': player_skills, 'zipped_list':zipped_list, 'index_list': index_list, })
示例#4
0
    def calculate_score(self, comparison_pairs):
        """
        Calculate scores for a set of comparisons
        :param comparisons: array of
        :return: dictionary key -> ScoredObject
        """
        self.storage = {}
        self.opponents = {}
        self.ratings = {}
        trueskill.setup()

        keys = self.get_keys_from_comparison_pairs(comparison_pairs)
        # create default ratings for every available key
        for key in keys:
            rating = trueskill.Rating()
            self.ratings[key] = rating
            self.opponents[key] = set()

            self.storage[key] = ScoredObject(
                key=key,
                score=trueskill.expose(rating),
                variable1=rating.mu,
                variable2=rating.sigma,
                rounds=0,
                opponents=0,
                wins=0,
                loses=0,
            )

        # calculate rating by for every match
        for comparison_pair in comparison_pairs:
            key1 = comparison_pair.key1
            key2 = comparison_pair.key2
            winning_key = comparison_pair.winning_key

            # skip incomplete comparisosns
            if winning_key is None:
                self._update_rounds_only(key1)
                self._update_rounds_only(key2)
                continue

            r1 = self.ratings[key1]
            r2 = self.ratings[key2]

            if winning_key == comparison_pair.key1:
                r1, r2 = trueskill.rate_1vs1(r1, r2)
            elif winning_key == comparison_pair.key2:
                r2, r1 = trueskill.rate_1vs1(r2, r1)
            else:
                raise InvalidWinningKeyException

            self._update_rating(key1, r1, key2, winning_key)
            self._update_rating(key2, r2, key1, winning_key)

        # return comparison results
        return self.storage
示例#5
0
def generate_ranking(dao):
    dao.reset_all_player_ratings()

    player_date_map = {}
    now = datetime.now()
    player_id_to_player_map = dict((p.id, p) for p in dao.get_all_players())

    tournaments = dao.get_all_tournaments()
    for tournament in tournaments:
        print 'Processing:', tournament.name

        for player_id in tournament.players:
            player_date_map[player_id] = tournament.date

        for match in tournament.matches:
            winner = player_id_to_player_map[match.winner]
            loser = player_id_to_player_map[match.loser]

            rating_calculators.update_trueskill_ratings(winner=winner, loser=loser)

    excluded_players = set([p.id for p in dao.get_excluded_players()])
    i = 1
    players = player_id_to_player_map.values()
    sorted_players = sorted(players, key=lambda player: trueskill.expose(player.rating.trueskill_rating), reverse=True)
    ranking = []
    for player in sorted_players:
        player_last_active_date = player_date_map.get(player.id)
        if player_last_active_date == None or dao.is_inactive(player, now) or player.id in excluded_players:
            pass # do nothing, skip this player
        else:
            ranking.append(RankingEntry(i, player.id, trueskill.expose(player.rating.trueskill_rating)))
            i += 1

    print 'Updating players...'
    for p in players:
        dao.update_player(p)

    print 'Inserting new ranking...'
    dao.insert_ranking(Ranking(now, [t.id for t in tournaments], ranking))

    print 'Done!'
示例#6
0
def quality_json(rating):
    """
    Convert a Rating into something more JSON serializeable, includes 'exposure' data
    :type rating: Rating
    :param rating: the rating to convert
    :param result: the result sent in initial payload
    :rtype: dict
    :return: dict
    """

    return {'mu':rating.mu,
            'sigma':rating.sigma,
            'exposure':trueskill.expose(rating)}
示例#7
0
    def forwards(self, orm):
        ids = orm['auth.User'].objects.values_list('id', flat=True)
        users = {i: trueskill.Rating() for i in ids}

        for game in orm.Game.objects.filter(confirmed=True).order_by('date_created'):
            wid = game.winner.id
            lid = game.loser.id

            users[wid], users[lid] = trueskill.rate_1vs1(users[wid], users[lid])

        for id, rating in users.iteritems():
            u = orm.Rating.objects.get(user__id=id)
            u.ts_rating = rating
            u.exposure = trueskill.expose(u.ts_rating)
            u.save()
示例#8
0
    def _update_rating(self, key, new_rating, opponent_key, winning_key):
        self.ratings[key] = new_rating
        self.opponents[key].add(opponent_key)
        wins = self.storage[key].wins
        loses = self.storage[key].loses

        # winning_key == None should not increase total wins or loses
        self.storage[key] = ScoredObject(
            key=key,
            score=trueskill.expose(new_rating),
            variable1=new_rating.mu,
            variable2=new_rating.sigma,
            rounds=self.storage[key].rounds + 1,
            opponents=len(self.opponents[key]),
            wins=wins + 1 if winning_key == key else wins,
            loses=loses + 1 if winning_key == opponent_key else loses,
        )
示例#9
0
def signup():
    db = get_db()
    try:
        rating = ts.Rating()
        db.execute('''
            INSERT INTO
            player (alias, nick, mu, sigma, exposure, won, lost, active)
            VALUES (?, ?, ?, ?, ?, 0, 0, 1);''',
            (request.form['alias'],
             request.form['nick'],
             rating.mu,
             rating.sigma,
             ts.expose(rating)))
        db.commit()
    except sqlite3.IntegrityError as e:
        flash(str(e))

    return redirect(url_for('index'))
示例#10
0
文件: models.py 项目: blackrobot/pong
 def save(self, *args, **kwargs):
     self.exposure = trueskill.expose(self.ts_rating)
     super(Rating, self).save(*args, **kwargs)
示例#11
0
def record():
    db = get_db()

    p1 = request.form['p1']
    s1 = int(request.form['s1'])
    p2 = request.form['p2']
    s2 = int(request.form['s2'])

    hi, lo = max(s1, s2), min(s1, s2)

    if (not ((hi == 2 and lo == 0) or
             (hi == 2 and lo == 1) or
             (hi == 3 and lo == 0) or
             (hi == 3 and lo == 1) or
             (hi == 3 and lo == 2))):
        flash('Ladder is based on 3 or 5 game matches only')
        return redirect(url_for('index'))

    if p1 == p2:
        flash('Match players must be different.')
        return redirect(url_for('index'))

    # check if this was a scheduled match
    scheduledrow = db.execute('''
        SELECT (s.id)
        FROM schedule s
        JOIN player p1 ON s.p1 = p1.id
        JOIN player p2 ON s.p2 = p2.id
        WHERE p1.alias=? AND p2.alias=?
        OR p1.alias=? AND p2.alias=?;''',
        (p1, p2, p2, p1)).fetchone()
    scheduled = scheduledrow is not None
    if scheduled:
        db.execute('DELETE FROM schedule WHERE id=?;', (scheduledrow[0],))

    if s1 > s2:
        win_alias, win_score, lose_alias, lose_score = p1, s1, p2, s2
    else:
        win_alias, win_score, lose_alias, lose_score = p2, s2, p1, s1
    
    date_string = request.form['date'] + ' '
    if ':' in request.form['time']:
        date_string += request.form['time'] + ' '
    else:
        date_string += request.form['time'] + ':00 '
    date_string += 'PM' if 'ampm' in request.form else 'AM'
    try:
        date = datetime.strptime(date_string, "%m/%d/%Y %I:%M %p")
    except:
        flash('Invalid time format')
        return redirect(url_for('index'))
    
    db.execute('''
        INSERT INTO 
        match (winner, loser, winscore, losescore, date, scheduled)
        SELECT w.id, l.id, ?, ?, ?, ?
        FROM player w JOIN player l
        WHERE w.alias = ? AND l.alias = ?;''',
        (win_score, lose_score, date, scheduled, win_alias, lose_alias))

    def get_rating(alias):
        sql = 'SELECT mu, sigma FROM player WHERE alias=?;'
        row = db.execute(sql, (alias,)).fetchone()
        if row is None:
            flash('Alias ' + alias + ' does not exist.')
            return None
        return ts.Rating(mu=row['mu'], sigma=row['sigma'])

    win_rating = get_rating(win_alias)
    lose_rating = get_rating(lose_alias)
    if win_rating is None or lose_rating is None:
        return redirect(url_for('index'))

    win_rating, lose_rating = ts.rate_1vs1(win_rating, lose_rating)
    win_exposure = ts.expose(win_rating);
    lose_exposure = ts.expose(lose_rating);

    db.execute('''
        UPDATE player 
        SET exposure=?, mu=?, sigma=?, won=won+1
        WHERE alias=?;''',
        (win_exposure, win_rating.mu, win_rating.sigma, win_alias));

    db.execute('''
        UPDATE player 
        SET exposure=?, mu=?, sigma=?, lost=lost+1
        WHERE alias=?;''',
        (lose_exposure, lose_rating.mu, lose_rating.sigma, lose_alias));
    
    db.commit()
    
    return redirect(url_for('index'))
示例#12
0
def generate_ranking(dao, now=datetime.now(), day_limit=60, num_tourneys=2, tournament_qualified_day_limit=999):
    player_date_map = {}
    player_id_to_player_map = {}

    tournament_qualified_date = (now - timedelta(days=tournament_qualified_day_limit))
    print('Qualified Date: ' + str(tournament_qualified_date))

    tournaments = dao.get_all_tournaments(regions=[dao.region_id])
    for tournament in tournaments:
        if tournament.excluded is True:
            print 'Tournament Excluded:'
            print 'Excluded - ' + str(tournament.name)
            continue

        if tournament_qualified_date <= tournament.date:
            print 'Processing:', tournament.name.encode('utf-8'), str(tournament.date)
            for player_id in tournament.players:
                player_date_map[player_id] = tournament.date

            # TODO add a default rating entry when we add it to the map
            for match in tournament.matches:
                if match.excluded is True:
                    print('match excluded:')
                    print('Tournament: ' + str(tournament.name))
                    print(str(match))
                    continue

                # don't count matches where either player is OOR
                winner = dao.get_player_by_id(match.winner)
                if dao.region_id not in winner.regions:
                    continue
                loser = dao.get_player_by_id(match.loser)
                if dao.region_id not in loser.regions:
                    continue

                if match.winner not in player_id_to_player_map:
                    db_player = dao.get_player_by_id(match.winner)
                    db_player.ratings[dao.region_id] = model.Rating()
                    player_id_to_player_map[match.winner] = db_player

                if match.loser not in player_id_to_player_map:
                    db_player = dao.get_player_by_id(match.loser)
                    db_player.ratings[dao.region_id] = model.Rating()
                    player_id_to_player_map[match.loser] = db_player

                winner = player_id_to_player_map[match.winner]
                loser = player_id_to_player_map[match.loser]


                rating_calculators.update_trueskill_ratings(
                    dao.region_id, winner=winner, loser=loser)

    print 'Checking for player inactivity...'
    rank = 1
    players = player_id_to_player_map.values()
    sorted_players = sorted(
        players,
        key=lambda player: trueskill.expose(player.ratings[dao.region_id].trueskill_rating()), reverse=True)
    ranking = []
    for player in sorted_players:
        player_last_active_date = player_date_map.get(player.id)
        if player_last_active_date is None or \
                dao.is_inactive(player, now, day_limit, num_tourneys) or \
                dao.region_id not in player.regions:
            pass  # do nothing, skip this player
        else:
            ranking.append(model.RankingEntry(
                rank=rank,
                player=player.id, rating=trueskill.expose(player.ratings[dao.region_id].trueskill_rating())))
            rank += 1

    print 'Updating players...'
    for i, p in enumerate(players, start=1):
        dao.update_player(p)
        # TODO: log somewhere later
        # print 'Updated player %d of %d' % (i, len(players))

    print 'Inserting new ranking...'
    dao.insert_ranking(model.Ranking(
        id=ObjectId(),
        region=dao.region_id,
        time=now,
        tournaments=[t.id for t in tournaments],
        ranking=ranking))

    print 'Done!'
示例#13
0
文件: rankings.py 项目: garsh0p/garpr
def _create_ranking_from_tournament_list(
        dao,
        tournaments,
        now,
        day_limit,
        num_tourneys,
        tournament_qualified_day_limit,
        ranking_to_diff_against):
    player_date_map = {}
    player_id_to_player_map = {}

    tournament_qualified_date = (now - timedelta(days=tournament_qualified_day_limit))
    print('Qualified Date: ' + str(tournament_qualified_date))

    for tournament in tournaments:
        if tournament_qualified_date <= tournament.date:
            print 'Processing:', tournament.name.encode('utf-8'), str(tournament.date)
            for player_id in tournament.players:
                player_date_map[player_id] = tournament.date

            # TODO add a default rating entry when we add it to the map
            for match in tournament.matches:
                if match.excluded is True:
                    print('match excluded:')
                    print('Tournament: ' + str(tournament.name))
                    print(str(match))
                    continue

                if match.winner not in player_id_to_player_map:
                    db_player = dao.get_player_by_id(match.winner)
                    db_player.ratings[dao.region_id] = model.Rating()
                    player_id_to_player_map[match.winner] = db_player

                if match.loser not in player_id_to_player_map:
                    db_player = dao.get_player_by_id(match.loser)
                    db_player.ratings[dao.region_id] = model.Rating()
                    player_id_to_player_map[match.loser] = db_player

                winner = player_id_to_player_map[match.winner]
                loser = player_id_to_player_map[match.loser]

                rating_calculators.update_trueskill_ratings(
                    dao.region_id, winner=winner, loser=loser)

    print 'Checking for player inactivity...'
    rank = 1
    players = player_id_to_player_map.values()
    sorted_players = sorted(
        players,
        key=lambda player: (trueskill.expose(player.ratings[dao.region_id].trueskill_rating()), player.name),
        reverse=True)
    ranking = []
    for player in sorted_players:
        player_last_active_date = player_date_map.get(player.id)
        if _is_player_inactive(dao, player, tournaments, player_last_active_date, now, day_limit, num_tourneys):
            pass  # do nothing, skip this player
        else:
            ranking.append(model.RankingEntry(
                rank=rank,
                player=player.id,
                rating=trueskill.expose(player.ratings[dao.region_id].trueskill_rating()),
                previous_rank=ranking_to_diff_against.get_ranking_for_player_id(player.id) if ranking_to_diff_against else None))
            rank += 1

    print 'Updating players...'
    for i, p in enumerate(players, start=1):
        dao.update_player(p)
        # TODO: log somewhere later
        # print 'Updated player %d of %d' % (i, len(players))

    print 'Returning new ranking...'
    return model.Ranking(
        id=ObjectId(),
        region=dao.region_id,
        time=now,
        tournaments=[t.id for t in tournaments],
        ranking=ranking)
示例#14
0
文件: views.py 项目: jztd/sc2_live
def display_player(request, given_player):
	player_name = player.objects.get(name=given_player)
	matches = match.objects.filter(players__name=player_name.name)
	player_rating = expose(Rating(float(player_name.mu), float(player_name.sigma)))
	return render(request,'player_display.html',{'matches':matches, 'player':player_name, 'rating': player_rating})
示例#15
0
文件: player.py 项目: mocsar/csocso
 def get_score(self):
     """
     :rtype : float
     """
     return (trueskill.expose(self.rating) + trueskill.global_env().mu) * 3
示例#16
0
 def elo(self, rating=None):
     if rating is None:
         rating = self.rating
     return trueskill.expose(rating)
示例#17
0
    def calculate_score_1vs1(self, key1_scored_object, key2_scored_object, winning_key, other_comparison_pairs):
        """
        Calcualtes the scores for a new 1vs1 comparison without re-calculating all previous scores
        :param key1_scored_object: Contains score parameters for key1
        :param key2_scored_object: Contains score parameters for key2
        :param winning_key: indicates with key is the winning key
        :param other_comparison_pairs: Contains all previous comparison_pairs that the 2 keys took part in.
            This is a subset of all comparison pairs and is used to calculate round, wins, loses, and opponent counts
        :return: tuple of ScoredObject (key1, key2)
        """
        self.storage = {}
        self.opponents = {}
        self.ratings = {}
        trueskill.setup()

        key1 = key1_scored_object.key
        key2 = key2_scored_object.key

        # Note: if value are None, trueskill.Rating will use default mu 25 and sigma 8.333
        r1 = trueskill.Rating(mu=key1_scored_object.variable1, sigma=key1_scored_object.variable2)

        r2 = trueskill.Rating(mu=key2_scored_object.variable1, sigma=key2_scored_object.variable2)

        if winning_key == key1:
            r1, r2 = trueskill.rate_1vs1(r1, r2)
        elif winning_key == key2:
            r2, r1 = trueskill.rate_1vs1(r2, r1)
        else:
            raise InvalidWinningKeyException

        self.ratings[key1] = r1
        self.ratings[key2] = r2

        for key in [key1, key2]:
            self.opponents[key] = set()
            self.storage[key] = ScoredObject(
                key=key,
                score=trueskill.expose(self.ratings[key]),
                variable1=self.ratings[key].mu,
                variable2=self.ratings[key].sigma,
                rounds=0,
                opponents=0,
                wins=0,
                loses=0,
            )

        # calculate opponents, wins, loses, rounds for every match for key1 and key2
        for comparison_pair in other_comparison_pairs + [ComparisonPair(key1, key2, winning_key)]:
            cp_key1 = comparison_pair.key1
            cp_key2 = comparison_pair.key2
            cp_winning_key = comparison_pair.winning_key

            if cp_key1 == key1 or cp_key1 == key2:
                if cp_winning_key is None:
                    self._update_rounds_only(cp_key1)
                else:
                    self._update_result_stats(cp_key1, cp_key2, cp_winning_key)

            if cp_key2 == key1 or cp_key2 == key2:
                if cp_winning_key is None:
                    self._update_rounds_only(cp_key2)
                else:
                    self._update_result_stats(cp_key2, cp_key1, cp_winning_key)

        return (self.storage[key1], self.storage[key2])