Latest Posts

Topic: Rating system

WorldSavior
Avatar
Joined: 2016-10-15, 04:10
Posts: 2091
OS: Linux
Version: Recent tournament version
Ranking
One Elder of Players
Location: Germany
Posted at: 2019-07-31, 18:15

einstein13 wrote:

WorldSavior wrote:

einstein13 wrote:

The simpliest idea for rank I know is to find proportion of win/all games. And since "rating" is providing decimals, the (almost) most precise equation for rank value would be:

ranking = 1000.0 * number_of_win_games / (number_of_win_games + number_of_lost_games)

This isn't a meaningful value.

Yes it is.

ranking = number_of_win_games / (number_of_win_games + number_of_lost_games)

is a "fraction of winnings". Multiplying it by a constant doesn't change the meaning.

No. If player A is better than player B, player A can still easily have a much lower winning percentage than player B. And number of draws is missing also.


Wanted to save the world, then I got widetracked

Top Quote
einstein13
Avatar
Joined: 2013-07-29, 00:01
Posts: 1118
Ranking
One Elder of Players
Location: Poland
Posted at: 2019-07-31, 19:32

But the fraction of winnings still has its meaning.

You are probably complaining about that this is not a true player's power measurement. You're right. But not all ranks are doing that. Fraction of winning is not measuring real power of the player, but how often the participant is winning over his/her opponents.

I am not forcing that this should be calculated, but I am suggesting that it is worth doing, especially that this doesn't require much work and it is providing lots of fun to the casual players.

About draws, it is not a problem to add them to the equation:

rating = (number_of_wins + 0.5 * number_of_draws) / (number_of_wins + number_of_draws + number_of_loses)
Edited: 2019-07-31, 19:32

einstein13
calculations & maps packages: http://wuatek.no-ip.org/~rak/widelands/
backup website files: http://kartezjusz.ddns.net/upload/widelands/

Top Quote
trimard
Avatar
Topic Opener
Joined: 2009-03-05, 22:40
Posts: 230
Ranking
Widelands-Forum-Junkie
Location: Paris
Posted at: 2019-07-31, 20:15

Ok more precise questions for einstein:

What's the point of subtype? We are gonna put a special function for each score anyway

Two questions about your code:

def save(self):
        if self.id == None:
            # update previous records (if exist) of the same type & subtype to be inactive
            previous = Rating.objects.filter(active=True)
            previous = previous.filter(type=self.type)
            if self.subtype:
                previous = previous.filter(subtype=self.subtype)
            previous.update(active=False)
        super().save() # for Python 3.X
        super(Rating, self).save() # for Python 2.7
        return
  • What's the point of having such function in the model? Never seen that face-tongue.png

  • Isn't the server always in python3?

float1 = models.FloatField(null=True, blank=True) # rating_deviation for Glicko
float2 = models.FloatField(null=True, blank=True) # volatility for Glicko
integer1 = models.IntegerField(null=True, blank=True) # number of win games for simple ladder
integer2 = models.IntegerField(null=True, blank=True) # number of lost games for simple ladder

Why not put everything in floats? If we are gonna use many score system, just transform to int when retrieving from db. 2 less lines face-tongue.png

updated = models.DateTimeField(auto_now_add=True)
active = models.BooleanField(default=True)

Couldn't we rather have a new table with a season data (start date, end date, selected maps, players that particpated, their games, all the scores)? ==> i.e all that will be shown on the website to players It would also avoid this idea of active and inactive.


Top Quote
einstein13
Avatar
Joined: 2013-07-29, 00:01
Posts: 1118
Ranking
One Elder of Players
Location: Poland
Posted at: 2019-07-31, 22:51

What's the point of subtype?

It is not necessary. It is just my point of view. The same solution can be done to type only. But then "type" will be one of ["Glicko official weekly", "Glicko official instant", "Glicko all weekly", "Glicko all instant", ...]. With type and subtype you has less types. But it is not necessary at all. face-smile.png

  • What's the point of having such function in the model? Never seen that face-tongue.png

Function save() is called every time when object of the model is created or updated in the database. In my code I have overridden the original function by small piece. At the end you can see two lines: super().save() # for Python 3.X and super(Rating, self).save() # for Python 2.7 which are one for each version of Python (I don't know which is used now in Widelands). Those lines are calling original save function from models.Model

Why in my proposal is such thing? Because that is solving updating active value to False when new record appear. So that no other action is needed, but the history of the records is preserved.

  • Isn't the server always in python3?

I am not sure what do you mean by "server". "Save" function exists in all django classes that are inheriting from models.Model.

Why not put everything in floats? If we are gonna use many score system, just transform to int when retrieving from db. 2 less lines face-tongue.png

You're right. Since we won't reach 10^15 cases, the float and integer values will be the same. face-smile.png But as it was suggested by WorldSavior, I have forgot about forfeits in my "simplest rank", so it needs 3 values instead of 2.

updated = models.DateTimeField(auto_now_add=True)
active = models.BooleanField(default=True)

Couldn't we rather have a new table with a season data (start date, end date, selected maps, players that particpated, their games, all the scores)? ==> i.e all that will be shown on the website to players It would also avoid this idea of active and inactive.

I am not sure what do you mean by "season data", or rather: how it will be stored? But as I understand, you want to store old data in an "archive table". It is possible to do that. For very large tables (millions of records) it is even better, but as I understand our situation (up to 100 records per week) it will be enough to store everything in one table. I know that the model I propose seem to be a bit more complicated, but it is not the worst one face-wink.png . Of course you don't have to implement such system. You can do anything you think is a good idea. It is possible to implement without history of records, and the "active" should be erased from the model. face-smile.png

Hopefully I answered all you questions for now. face-smile.png

Edited: 2019-07-31, 22:52

einstein13
calculations & maps packages: http://wuatek.no-ip.org/~rak/widelands/
backup website files: http://kartezjusz.ddns.net/upload/widelands/

Top Quote
kaputtnik
Avatar
Joined: 2013-02-18, 20:48
Posts: 2433
OS: Archlinux
Version: current master
Ranking
One Elder of Players
Location: Germany
Posted at: 2019-08-01, 00:37

einstein13 wrote:

  • Isn't the server always in python3?

I am not sure what do you mean by "server". "Save" function exists in all django classes that are inheriting from models.Model.

Since the switch to the new server, the website is running on python version 3.6. It's a prerequisite for updating to any django version behind 1.11 face-smile.png

Overriding the save()-method is a common task to apply some changes which are 'behind' of saving just some values into the database, e.g. format some strings or update other models with new values face-wink.png


Fight simulator for Widelands:
https://wide-fighter.netlify.app/

Top Quote
kaputtnik
Avatar
Joined: 2013-02-18, 20:48
Posts: 2433
OS: Archlinux
Version: current master
Ranking
One Elder of Players
Location: Germany
Posted at: 2019-08-01, 18:52

Will there be some kind of league? Say have a 'beginners' league and if a player reaches some points, he will moved up to the 'profi' league?


Fight simulator for Widelands:
https://wide-fighter.netlify.app/

Top Quote
trimard
Avatar
Topic Opener
Joined: 2009-03-05, 22:40
Posts: 230
Ranking
Widelands-Forum-Junkie
Location: Paris
Posted at: 2019-08-01, 19:45

Why in my proposal is such thing? Because that is solving updating active value to False when new record appear. So that no other action is needed, but the history of the records is preserved.

I think I'll use that for current season or not anyway face-tongue.png

But as it was suggested by WorldSavior, I have forgot about forfeits in my "simplest rank", so it needs 3 values instead of 2.

Yes we need 3 value for glicko2 anyway, we store volatility too

Will there be some kind of league? Say have a 'beginners' league and if a player reaches some points, he will moved up to the 'profi' league?

Yes of course! But not before stage 3, we need a lot of data to determine what are the limit of each leagues anyway face-tongue.png


Top Quote
teppo

Joined: 2012-01-30, 09:42
Posts: 423
Ranking
Tribe Member
Posted at: 2019-08-03, 09:25

WorldSavior wrote:

But I guess that if it will be good if both players have to agree before every match about that?

ranking = 1000.0 * number_of_win_games / (number_of_win_games + number_of_lost_games)

This isn't a meaningful value.

No. If player A is better than player B, player A can still easily have a much lower winning percentage than player B. And number of draws is missing also.

If we adopt this system, I will admit to ranking only once, and make sure to win that one game. After that, I will shine on the top forever with my perfect score.

Should the number of games contribute to ranking in some way? Should the ranking deteriorate over time? I would do both.


Top Quote
teppo

Joined: 2012-01-30, 09:42
Posts: 423
Ranking
Tribe Member
Posted at: 2019-08-03, 09:50

teppo wrote:

Should the number of games contribute to ranking in some way? Should the ranking deteriorate over time? I would do both.

There are of course many fancy ways to do that. Placeholder suggestions below; feel free to invent something better.

Regarding "number of games": My simple approach could be that one needs at least 5 games for perfect score. If less games, the score is worse. Example: ranking := (numer_of_fresh_games/5) * 1000.0 * number_of_win_games / (number_of_win_games + number_of_lost_games)

Regarding "over time": Only 5 newest games contribute: number_of_fresh_games := sum (individual_new_game_freshness_value), where individual_new_game_freshness_value := 0.99 ** (number_of_months_since_game_was_played); and the freshness_values of 5 newest games are summed together (unless <5 games total, in which cases all are included).

The constant 5 is pretty small, meaning that it is in reach of many WL player. However, winning 5 games in a row by accident is unlikely enough. The number 5 is not well thought-of.

This suggestion has the funny side-effect that an old guy with lots of wins and recent inactivity can increase his score by losing a game (logic: rating might go down a bit, but ageing multiplier increases). I think this is okay: An old master is rewarded from providing that he is still around.

Once more: I am not saying that these are perfect ways to do it, but still, one single victory should not give perfect ranking forever.


Top Quote
einstein13
Avatar
Joined: 2013-07-29, 00:01
Posts: 1118
Ranking
One Elder of Players
Location: Poland
Posted at: 2019-08-03, 19:52

teppo wrote:

If we adopt this system, I will admit to ranking only once, and make sure to win that one game. After that, I will shine on the top forever with my perfect score.

The easiest way to prohibit such situation is to start simplest ranking after at least N games (f.e. 5 of them). So you have to win 5 games in a row, first 5 games. And the additional info will show that you played only few times instead of 9999 games of WorldSavior & king_of_nowhere (2nd and 3rd place). face-tongue.png


einstein13
calculations & maps packages: http://wuatek.no-ip.org/~rak/widelands/
backup website files: http://kartezjusz.ddns.net/upload/widelands/

Top Quote