Implémentation classement Elo en Php
Par undefine le lundi, octobre 27 2008, 14:33 - Lien permanent
Rapide introduction
Le sytème Elo est un système qui permet d'évaluer le niveau des joueurs d'échecs, ou d'autres jeux à deux joueurs. En effet établir le classement exact des joueurs est difficile voir impossible il a donc été créée ce classement qui essaye d'en donner une approximation. Il existe d'autres systèmes qui sont plus "performant" : chessMetrics, Glicko 1&2, TrueSkill, TrueChess, Edo mais ils sont plus complexe.
Nous allons dans un premier temps voir le fonctionnement de ce système, puis en donner une implémentation en php.
Comment ça marche ?
Chaque joueur a un rang (1500 pour les nouveaux joueurs) se rang va évoluer selon les résultats des matchs du joueur. Schématiquement, le rang du joueur va augmenter quand il remporte un match et diminuer quand il perd. L'augmentation/diminution de rang ne sera pas la même selon la difficulté du match.
Pour chaque match d'un joueur on re-calcule son rang selon la formule suivante :
nRang = aRang + K * ( résultat - estimation)
nRang : nouveau rang du joueur.
aRang : ancien rang du joueur.
K : un paramètre permettant de régler la "vitesse" d'augmentation du rang des joueurs (établie expérimentalement).
résultat : le résultat du joueur, 1 pour match gagné, 0,5 égalité et 0 pour match perdu.
estimation : le résultat attendu du match calculé d'après le rang du joueur et de son adversaire
Constante K
Ce paramètre contrôle l'inertie des estimations ie. la vitesse d'apprentissage de Elo. Ce paramètre est choisi empiriquement. Il peut être constant par exemple K=16, ou alors varier selon le rang du joueur :
K=25 jusqu'à la 30e partie du joueur, sinon
K=15 en-dessous de 2400, sinon
K=10 au-dessus de 2400
Calcul de l'estimation
Se calcul se fait selon la formule suivante :
estimation = 1 / ( 1+10 ^ ( ( rangAdv - rang ) /400 ) )
^ : puissance
rangAdv : rang de l'adversaire.
Petite Illustration
Dans cet exemple le paramètre K=16. Soit deux joueurs, Anne de rang 2300 et Michel de rang 1800. Calculons l'estimation de chaques joueurs.
estimationAnne = 1 / ( 1+10 ^ ( ( 1800 - 2300 ) /400 ) )=0,946759785
estimationMichel = 1 / ( 1+10 ^ ( ( 2300 - 1800 ) /400 ) )=0,053240215
Dans le cas ou Anne gagne :
nAnne = 2300 + 16 * ( 1 - 0,946759785)=2300,85...
nMichel = 1800 + 16 * ( 0 - 0,053240215)=1799.14...
Le classement des joueurs ne change pratiquement pas vu que le résultat corrobore le classement établie
Dans le cas ou Michel gagne :
nAnne = 2300 + 16 * ( 0 - 0,946759785)=2284,85...
nMichel = 1800 + 16 * ( 1 - 0,053240215)=1815,14...
Le classement des joueurs change de façon significative car le résultat ne correspond pas au classement établie.
Implémentation
Son implémentation simple il suffit de transcrire les formules vu plus haut. getExpectedScore fonction qui calcule l'estimation du joueur 1, prend en entrée le rang Elo du joueur 1 ($EloPlayer1) et celui du joueur 2 ($EloPlayer2).
function getExpectedScore($EloPlayer1,$EloPlayer2){
$exp = -($EloPlayer1-$EloPlayer2)/400;
return 1/(1+pow(10,$exp));
}
updatePlayer1EloRanking fonction qui retourne le nouveau rang du joueur 1, prend en paramètre le rang du joueur 1 ($EloPlayer1), le rang du joueur 2 ($EloPlayer2), et le gagnant : 1=> joueur 1, 2=>joueur 2, 0=>égalité ($winner).
function updatePlayer1EloRanking($EloPlayer1,$EloPlayer2,$winner){
$score=($winner>0)?$winner*-1+2:0.5;
$expectedScore = getExpectedScore($EloPlayer1,$EloPlayer2);
$K=getKConstant($EloPlayer1); // qui est à définir selon vos envie
$updatedRank = round($EloPlayer1+$K*($score-$expectedScore));
//threshold
if($updatedRank<300){
return 300;
}else{
return $updatedRank;
}
}
Et enfin updatePlayersEloRanking qui modifie $EloPlayer1 et $EloPlayer2 selon le gagnant : 1=> joueur 1, 2=>joueur 2, 0=>égalité ($winner)
function updatePlayersEloRanking(&$EloPlayer1,&$EloPlayer2,$winner){
$tmpElo1=updatePlayer1EloRanking($EloPlayer1,$EloPlayer2,$winner);
$winner=($winner>0)?$winner*-1+3:0.5;
$EloPlayer2=updatePlayer1EloRanking($EloPlayer2,$EloPlayer1,$winner);
$EloPlayer1=$tmpElo1;
}
End Of Line
Pour les flemmard l'implémentation est fournis en pièces jointes.
Commentaires
C'est ce que tu utilises pour www.pick-out.fr ou pas?
Très instructif, dommage que la pièce jointe ne soit pas disponible : (
une tres belle facons de voir les choses oui meme si je suis ps convaincu que ca peut parcher
Merci pour ces infos, ca va beaucoup me servir.
Merci pour cet article qui va enormement me servir.
J'ai lu ton article et visite ton blog que je trouve vraiment tres interessant. Je l'ai ajoute dans mes favoris.
Super sympa cet article. J'espere que vous posterez de nouveaux articles prochainement.
Bonjour,
Merci pour ces fonctions, c'est très utile.
Il y a cependant une erreur dans la dernière fonction.
Ca ne doit pas être :
$winner=($winner>0)?$winner*-1+3:0.5;
mais :
$winner=($winner>0)?$winner*-1+3:0;