Over the holidays I reconnected with an old friend and occasional

chess partner who, upon hearing I was getting soundly thrashed by run

of the mill engines, recommended checking out the ChessTempo site. It

has online tools for training your chess tactics. As you attempt to

solve chess problems your rating is computed depending on how well you

do. The chess problems, too, are rated and adjusted as visitors

attempt them. This should be familar to any chess or table-tennis

player. Rather than the Elo rating system, the Glicko rating system is

used.

You have a choice of the relative difficulty of the problems.

After attempting a number of easy puzzles and seeing my rating slowly

climb, I wondered what was the most effective technique to raise my

rating (the classical blunder). Attempting higher rated problems would lower my

solving rate, but this would be compensated by a smaller loss and

larger gain. Assuming my actual playing strength is greater than my

current rating (a misconception common to us patzers), there should be a

rating that maximizes the rating gain per problem.

The following Maple module computes the expected rating change

using the Glicko system.

Glicko := module()
export DeltaRating
, ExpectedDelta
, Pwin
;
# Return the change in rating for a loss and a win
# for player 1 against player2
DeltaRating := proc(r1,rd1,r2,rd2)
local E, K, g, g2, idd, q;
q := ln(10)/400;
g := rd -> 1/sqrt(1 + 3*q^2*rd^2/Pi^2);
g2 := g(rd2);
E := 1/(1+10^(-g2*(r1-r2)/400));
idd := q^2*(g2^2*E*(1-E));
K := q/(1/rd1^2+idd)*g2;
(K*(0-E), K*(1-E));
end proc:
# Compute the probability of a win
# for a player with strength s1
# vs a player with strength s2.
Pwin := proc(s1, s2)
local p;
p := 10^((s1-s2)/400);
p/(1+p);
end proc:
# Compute the expected rating change for
# player with strength s1, rating r1 vs a player with true rating r2.
# The optional rating deviations are rd1 and rd2.
ExpectedDelta := proc(s1,r1,r2,rd1 := 35, rd2 := 35)
local P, l, w;
P := Pwin(s1,r2);
(l,w) := DeltaRating(r1,rd1,r2,rd2);
P*w + (1-P)*l;
end proc:
end module:

Assume a player has a rating of 1500 but an actual playing strength of 1700. Compute the expected rating change for a given puzzle rating, then plot it. As expected the graph has a peak.

Ept := Glicko:-ExpectedDelta(1700,1500,r2):
plot(Ept,r2 = 1000...2000);

Compute the optimum problem rating

fsolve(diff(Ept,r2));
{r2 = 1599.350691}

As your rating improves, you'll want to adjust the rating of the problems (the site doesn't allow that fine tuning). Here we plot the optimum puzzle rating (r2) for a given player rating (r1), assuming the player's strength remains at 1700.

Ept := Glicko:-ExpectedDelta(1700, r1, r2):
dEpt := diff(Ept,r2):
r2vsr1 := r -> fsolve(eval(dEpt,r1=r)):
plot(r2vsr1, 1000..1680);

Here is a Maple worksheet with the code and computations.

Glicko.mw

**Later**

After pondering this, I realized there is a more useful way to present the results. The shape of the optimal curve is independent of the user's actual strength. Showing that is trivial, just substitute a symbolic value for the player's strength, offset the ratings from it, and verify that the result does not depend on the strength.

Ept := Glicko:-ExpectedDelta(S, S+r1, S+r2):
has(Ept, S);
false

Here's the general curve, shifted so the player's strength is 0, r1 and r2 are relative to that.

r2_r1 := r -> rhs(Optimization:-Maximize(eval(Ept,r1=r), r2=-500..0)[2][]):
p1 := plot(r2_r1, -500..0, 'numpoints'=30);

Compute and plot the expected points gained when playing the optimal partner and your rating is r-points higher than your strength.

EptMax := r -> eval(Ept, [r1=r, r2=r2_r1(r)]):
plot(EptMax, -200..200, 'numpoints'=30, 'labels' = ["r","Ept"]);

When your playing strength matches your rating, the optimal opponent has a relative rating of

r2_r1(0);
-269.86

The expected points you win is

evalf(EptMax(0));
0.00956