ChessJam and ratings... need some input...

Discussion of anything and everything relating to chess playing software and machines.

Moderator: Ras

gw5815

ChessJam and ratings... need some input...

Post by gw5815 »

I am one of the developers of ChessJam, a new online chess app for playing live chess.

We recently implemented ratings using the basic ELO formula and the basic FIDE K-factors....but I'm starting to think that we need to handle things differently for new players. Looking through the history of the 2,000+ games played so far, I see flaws, especially for people that simply login and play one or two games. A newbie can play another newbie with one game and walk away with a 1230 rating....meanwhile, some of us that play 30 games are lower rated. Shouldn't we have some sort of weighting for this?

I noticed that some sites don't even give a rating until after several games have been played. I also noticed that some sites do rating tweaks for "non-established players" ...and other sites use glicko and glicko-2 which seems to factor in the "newness factor" a bit better.

We also have robots to allow people to practice, but we don't count those games toward human ratings, which I think makes sense.

Since I am more of a software guy than a chess guy, I was hoping to get some feedback from some of you. Should we try to "tweak/hack" ELO or should we bite the bullet and implement glicko-2?

Any suggestions?

Thanks!

Greg Wilson
http://ChessJam.com
http://chessjam.blogspot.com
http://twitter.com/chessjam
Dann Corbit
Posts: 12808
Joined: Wed Mar 08, 2006 8:57 pm
Location: Redmond, WA USA

Re: ChessJam and ratings... need some input...

Post by Dann Corbit »

You are describing a "provisional rating".
Here is what the USCF does:

Code: Select all

#include <stdio.h>
#include <math.h>
#include "uscf.h"

double          provisional_rating(
                                             double opponent_average_rating,
                                                   unsigned wins,
                                                   unsigned draws,
                                                   unsigned losses
)
{
    double          new_rating;
    if (wins + draws + losses == 0)
        new_rating = 0.;
    else
        new_rating = opponent_average_rating +
            (400.0 * ((wins + 0.5 * draws) - (0.5 * draws + losses)) /
             (wins + draws + losses));
    return (double) (unsigned) (new_rating + 0.5);
}
double          established_rating(
                                                   double old_rating,
                                                   double event_score,
                                                   double rating_difference,
                                                   char half_k_event,
                                                   double prize_amount,
                                                   unsigned event_level
)
{
    double          rating;
    double          k = old_rating >= 2400.0 ? 16.0 : old_rating >= 2100.0 ? 24.0 : 32.0;
    if (half_k_event)
        k *= 0.5;
    rating = old_rating + k * (event_score - win_expectancy(rating_difference));
    if (old_rating <= 2099.0 &&
        rating >= 2100.0 &&
        rating <= 2399.0)
        rating = 2100.0 + (rating - 2100.0) * 0.75;
    else if (old_rating >= 2100.0 &&
             old_rating <= 2399.0 &&
             rating <= 2099.0)
        rating = 2100.0 * (rating - 2100.0) * 1.33;
    else if (old_rating >= 2100.0 &&
             old_rating <= 2399.0 &&
             rating >= 2400.0 &&
             rating <= 3000.0)
        rating = 2400.0 * (rating - 2400.0) * 0.66;
    else if (old_rating >= 2400.0 &&
             old_rating <= 3000.0 &&
             rating >= 2100.0 &&
             rating <= 2399.0)
        rating = 2400.0 * (rating - 2400.0) * 1.50;
    return rating_floor_adj(old_rating, rating, prize_amount, event_level);
}
double          win_expectancy(
                                               double rating_difference
)
{
    return 1.0 / (pow(10.0, (rating_difference / 400.0)) + 1.);
}
double          rating_floor_adj(
                                                 double old_rating,
                                                 double new_rating,
                                                 double prize_amount,
                                                 unsigned event_level
)
{
    char            large_cash_prize = 0;
    double          temp_floor = old_rating - 200.0;
    unsigned        ltf = ((unsigned) (temp_floor)) % 100UL * 100UL;
    if (old_rating >= 2400 || old_rating <= 100)
        return new_rating;
    if (old_rating < 1600)
        ltf = 100;
    if (old_rating < 2200 && prize_amount >= 1000)
        large_cash_prize = 1;
    else if (old_rating < 2300 && prize_amount >= 1500)
        large_cash_prize = 1;
    else if (old_rating < 2400 && prize_amount >= 2000)
        large_cash_prize = 1;
    if (large_cash_prize)
        ltf = event_level;
    return ltf > new_rating ? (double) ltf : new_rating;
}
unsigned long   rating_floor(
                                             double old_rating,
                                             double new_rating,
                                             double prize_amount,
                                             unsigned event_level
)
{
    char            large_cash_prize = 0;
    unsigned        floor_value = (((unsigned) (old_rating - 200)) % 100U) * 100U;
    if (old_rating >= 2400 || old_rating <= 100)
        return (unsigned long) (new_rating + 0.5);
    if (old_rating < 1600)
        floor_value = 100;
    if (old_rating < 2200 && prize_amount >= 1000)
        large_cash_prize = 1;
    else if (old_rating < 2300 && prize_amount >= 1500)
        large_cash_prize = 1;
    else if (old_rating < 2400 && prize_amount >= 2000)
        large_cash_prize = 1;
    if (large_cash_prize)
        floor_value = event_level;
    return floor_value;
}
const char     *
                describe_uscf_rating(
                                                     unsigned rating
)
{
    char           *rating_name;
    if (rating > 2399)
        rating_name = "Senior Master";
    else if (rating >= 2200)
        rating_name = "Master";
    else if (rating >= 2000)
        rating_name = "Expert";
    else if (rating >= 1800)
        rating_name = "Class A";
    else if (rating >= 1600)
        rating_name = "Class B";
    else if (rating >= 1400)
        rating_name = "Class C";
    else if (rating >= 1200)
        rating_name = "Class D";
    else if (rating >= 1000)
        rating_name = "Class E";
    else if (rating >= 800)
        rating_name = "Class F";
    else if (rating >= 600)
        rating_name = "Class G";
    else if (rating >= 400)
        rating_name = "Class H";
    else if (rating >= 200)
        rating_name = "Class I";
    else
        rating_name = "Class J";
    return rating_name;
}
char            string[32767];
int             main(void)
{
    double          rating_difference;
    for (rating_difference = 0; rating_difference <= 3000; rating_difference += 100) {
        printf("Win expectency for a difference of %.0f points is %g\n", rating_difference,
               win_expectancy(rating_difference));
    }
    printf("%.15g\n", win_expectancy(60.0));
    puts("Elo difference:");
    fgets(string, sizeof string, stdin);
    rating_difference = atof(string);
    printf("Win expectency for a difference of %.0f points is %g\n", rating_difference,
           win_expectancy(rating_difference));

    return 0;
}
See:
http://math.bu.edu/people/mg/ratings/approx/approx.html
http://math.bu.edu/people/mg/ratings/rating.system.pdf
http://math.bu.edu/people/mg/ratings/approx.pdf
http://math.bu.edu/people/mg/ratings/fideuscf.pdf

Glicko calculation:
http://math.bu.edu/people/mg/research/gdescrip.pdf
http://math.bu.edu/people/mg/research/glicko.pdf

See also:
http://math.bu.edu/people/mg/research.html
http://en.wikipedia.org/wiki/Elo_rating_system
http://remi.coulom.free.fr/Bayesian-Elo/
http://www.chessbase.com/newsdetail.asp?newsid=562
http://www.ratingtheory.com/
gw5815

Re: ChessJam and ratings... need some input...

Post by gw5815 »

This seems like a good approach. Would you consider this a better option than Glicko? (It's easier for me to implement for sure.

Thanks for sharing!

Greg Wilson
gw5815

Re: ChessJam and ratings... need some input...

Post by gw5815 »

Dann,

I see what the code is doing for provisional ratings. I'm wondering if I should treat the following situations differently:

provisional rated player vs. established player
provisional rated player vs. provisional rated player

The code above treats them the same (avg of opponents +/-400).

Any suggestions?

Thanks!

Greg Wilson
http://chessjam.com
http://chessjam.blogspot.com