Game Service Rating System
--------------------------
Game Service uses Mark Glickman's rating system. For more information
go to http://math.bu.edu/INDIVIDUAL/mg/research.html.
Major improvemnt in the rating system comes from player's rating being
defined as a pair (Estimated_Rating, Rating_Deviation) or R@D.
Rating_Deviation expresses the accuracy of the Estimated_Rating.
New players start as 1720@350 and as they play other players their
estimated rating and its accuracy changes.
The following function calculates updates of ratings for player1 and
player2 with respect to the outcome NResult. The outcome w is from
first player's point of view: 0.0 for a loss, 0.5 for a draw, and 1.0
for a win.
void Rating::rate( real8 NResult, real8& r1, real8& d1, real8& r2, real8& d2 )
{
const real8 p = 0.00001007241561756780; // 3*ln(10)^2/(pi^2*400^2)
const real8 q = 0.00575646273248511421; // ln(10)/400
const real8 min_K = 16.0;
real8 d12 = r1 - r2;
real8 sd1 = d1 * d1;
real8 sd2 = d2 * d2;
{
real8 f = 1.0 / sqrt( 1 + p * sd2 );
real8 E = 1.0 / ( 1.0 + pow( 10.0, -d12 * f / 400.0 ) );
real8 k = 1.0 / sd1 + q*q * f*f * E * (1.0 - E);
real8 K = q*f / k;
if ( K < min_K ) K = min_K;
r1 = r1 + 2 * K * ( NResult - E );
d1 = 1.0 / sqrt( k );
}
NResult = 1.0 - NResult; // invert result
{
real8 f = 1.0 / sqrt( 1 + p * sd1 );
real8 E = 1.0 / ( 1.0 + pow( 10.0, d12 * f / 400.0 ) );
real8 k = 1.0 / sd2 + q*q * f*f * E * (1.0 - E);
real8 K = q*f / k;
if ( K < min_K ) K = min_K;
r2 = r2 + 2 * K * ( NResult - E );
d2 = 1.0 / sqrt( k );
}
}
The inaccuracy of one's rating increases with inactivity. The following function
calculates new rating deviation with respect to the length of inactivity period:
real8 Rating::Rdev( real8 rdev, sint4 last, sint4 now )
{
static const real8 t_rdev = 100.0; // additional rating deviation
static const real8 t_norm = 60.0 * 60.0 * 24.0 * 30; // time unit
static const real8 t_year = 12.0; // period = 12 * time_unit
static const real8 c = t_rdev * t_rdev / log( 1.0 + t_year );
/* */ real8 t = now < last ? 0 : now - last;
real8 tdev = sqrt( rdev * rdev + c * log( 1.0 + t / t_norm ) );
return tdev > 350.0 ? 350.0 : tdev;
}
Game Service will always display current Estimated_Rating @
Rating_Deviation, but will (re)sort the players in the top list
hourly. For sorting purposes low estimation for players rating er@rd
is used, i.e. er - rd * 1720 / 350.
Smoothing the loss-draw-win transition!
Combined with a fractional komi system, Game score becomes a continous
function for many games! The following function is used to maps score
into (0.0, 1.0) outcome expected by the rating update function:
real8 Match::score( real8 r )
{
const real8 K = 0.75; // +2 -> 0.8, -2 -> 0.2
real8 a = fabs(r);
return 0.5 + r * K * 0.5 / ( 1.0 + a * K );
}
22.Nov.1999 (c) Igor Durdanovic, igord@research.nj.nec.com