Example #1
0
    def test_team_elo(self):
        """Test du calcul de l'elo de l'équipe. Cas basiques"""
        elo_team1 = calc_team_elo([self.players[0]])
        elo_team2 = calc_team_elo([self.players[1]])

        self.assertEqual(elo_team1, self.players[0].get_elo())
        self.assertEqual(elo_team2, self.players[1].get_elo())

        elo_team1 = calc_team_elo([self.players[0], self.players[1]])
        elo_team2 = calc_team_elo([self.players[2], self.players[3]])

        self.assertEqual(elo_team1, 2050)
        self.assertEqual(elo_team2, 2300)

        elo_team1 = calc_team_elo(
            [self.players[0], self.players[1], self.players[4]])
        elo_team2 = calc_team_elo(
            [self.players[2], self.players[3], self.players[5]])

        self.assertEqual(round(elo_team1, 0), 2475)
        self.assertEqual(round(elo_team2, 0), 2309)

        elo_team1 = calc_team_elo([
            self.players[0], self.players[1], self.players[4], self.players[7]
        ])
        elo_team2 = calc_team_elo([
            self.players[2], self.players[3], self.players[5], self.players[6]
        ])

        self.assertEqual(round(elo_team1, 0), 2400)
        self.assertEqual(round(elo_team2, 0), 2325)
Example #2
0
    def test_prob_winning(self):
        """Test probabilité de gagner (>50%)"""
        team1 = [
            self.players[0], self.players[1], self.players[4], self.players[7]
        ]
        team2 = [
            self.players[2], self.players[3], self.players[5], self.players[6]
        ]

        self.assertEqual(
            round(
                prob_winning(calc_team_elo(team1) - calc_team_elo(team2)) *
                100, 2), 66.61)
        self.assertEqual(
            round(
                prob_winning(calc_team_elo(team2) - calc_team_elo(team1)) *
                100, 2), 33.39)
Example #3
0
    def test_prob_winnng_under50(self):
        """Test probabilité de gagner (<50%)"""
        team1 = [
            self.players[0], self.players[1], self.players[6], self.players[7]
        ]
        team2 = [
            self.players[2], self.players[3], self.players[4], self.players[5]
        ]

        # Probability is the same for everyone in the team
        self.assertEqual(
            round(
                prob_winning(calc_team_elo(team1) - calc_team_elo(team2)) *
                100, 2), 1.24)
        self.assertEqual(
            round(
                prob_winning(calc_team_elo(team2) - calc_team_elo(team1)) *
                100, 2), 98.76)
Example #4
0
def balance_teams(request):
    if request.method == "POST":
        form = TeamsForm(request.POST)

        if form.is_valid() and len(form.cleaned_data["players"]) > 1:
            team_balancer = TeamBalancer(form.cleaned_data["players"])

            teams = team_balancer.get_teams()
            context = {'form': form}
            context.update({
                'team1': teams[0],
                'team2': teams[1],
                'elo_team1': calc_team_elo(teams[0]),
                'elo_team2': calc_team_elo(teams[1])
            })

            teams_eq = team_balancer.get_balanced_teams()

            if teams_eq[0] not in teams:

                delta_elo = calc_team_elo(teams_eq[0]) - calc_team_elo(
                    teams_eq[1])
                pw = prob_winning(delta_elo) * 100

                context.update({
                    'team1eq': teams_eq[0],
                    'team2eq': teams_eq[1],
                    'pw_team1eq': pw,
                    'pw_team2eq': 100 - pw
                })
            else:
                context.update({'team1eq': None, 'team2eq': None})

            # Add winning probability for teams
            delta_elo = calc_team_elo(teams[0]) - calc_team_elo(teams[1])
            pw = prob_winning(delta_elo) * 100

            if pw > 60 or pw < 40:
                color_cls = "is-danger"
            elif pw > 55 or pw < 45:
                color_cls = "is-warning"
            else:
                color_cls = "is-success"

            context.update({
                "pw_team1": pw,
                "pw_team2": 100 - pw,
                "color_cls": color_cls
            })

            return render(request, "gametracker/balance_teams.html", context)
        else:
            return render(request, "gametracker/balance_teams.html",
                          {'form': form})
    else:
        form = TeamsForm()
        return render(request, "gametracker/balance_teams.html", {
            'form': form,
            'team1': None,
            'team2': None
        })
Example #5
0
def update_elo(date=datetime.min):
    # Delete ELoLogs newer than the provided date
    elos_to_be_deleted = EloLog.objects.filter(date__gte=date)
    elos_to_be_deleted.delete()

    # Only get the queryset once, to avoid unnecessary calls to .save()
    persons = {p.name: p for p in Person.objects.all()}

    # Keep track of elo after each game
    elos = []

    # Init elo and number of games
    for person_name, person in persons.items():
        try:
            person_elos = EloLog.objects.filter(person=person)
            person.elo = person_elos.latest('date').elo
            person.ngames = person_elos.count() - 1  # First EloLog is init_elo
        except:
            person.elo = person.init_elo
            person.ngames = 0
            elos.append(
                EloLog(person=person, date=datetime.min, elo=person.init_elo))

    for game in Game.objects.filter(
            date__gte=date).order_by('date').prefetch_related(
                'team1', 'team2').iterator():
        # We can't call the queryset directly, otherwise the elo is updated to the latest one
        # So here we select 'persons' that are in game.team1 and game.team2
        team1 = [
            persons[name["identity__person__name"]]
            for name in game.team1.all().values("identity__person__name")
            if name["identity__person__name"] in persons
        ]
        team2 = [
            persons[name["identity__person__name"]]
            for name in game.team2.all().values("identity__person__name")
            if name["identity__person__name"] in persons
        ]

        team1_elo = calc_team_elo(team1)
        team2_elo = calc_team_elo(team2)

        # Only update the elo if elo of both team1 and team2 have been calculated
        if game.ranked and team1_elo and team2_elo:
            delta_elo = team1_elo - team2_elo

            # Calculate each player's new elo
            for person in team1 + team2:
                if person in team1:
                    person.elo = calculate_new_elo(person.elo, delta_elo,
                                                   game.winner == "team1")
                else:
                    person.elo = calculate_new_elo(person.elo, -delta_elo,
                                                   game.winner == "team2")
                elos.append(
                    EloLog(person=person, date=game.date, elo=person.elo))
                person.ngames += 1

    # Commit changes
    EloLog.objects.bulk_create(elos)

    for person_name, person in persons.items():
        person.save()