diff --git a/ELO_function.php b/ELO_function.php index 5da9c83c0fcfec526b92d2943a61863b50434121..d60f30aff30b5904c89ccde3be638e7c059aa430 100644 --- a/ELO_function.php +++ b/ELO_function.php @@ -7,66 +7,76 @@ * */ -/* @param $tab array - * @param $j int - * @requires $j >= 0 and $j < count($tab) - * @returns float - * Renvoie la moyenne du tableau en passant l'indice $j +/** + * Fonction qui calcule les différentiels de scores obtenus après une partie d'un jeu à deux joueurs + * où l'on peut perdre (0) ou gagner (1). + * @param int $SA : score actuel du premier joueur + * @param int $RA : score (valant 0 ou 1) du premier joueur + * @param int $SB : score actuel du second joueur + * @param int $RB : score (valant 0 ou 1) du second joueur + * @param int $K : la quantité max de points gagnable ou perdable sur une partie + * @param int $nmax : le nombre de parties pour considérer "qu'un joueur est aguerri". Vaut 20 par défaut. + * @param int $nA : le nombre de parties effectués par le premier joueur sur le jeu. + * @param int $nB : le nombre de parties effectués par le second joueur sur le jeu. + * @return array : le différentiel de score du premier joueur et du second joueur */ srand(); -function avg_skip($tab, $j) + +function ELO_duel($SA, $RA, $SB, $RB, $K, $nmax=20, $nA=20, $nB=20) { - $s = 0; - $n = count($tab); - for($i=0;$i < $n;$i++) - { - if ($i != $j) - { - $s = $s + $tab[$i]; - } - } + if ($nA > $nmax) + $nA = $nmax; + if ($nB > $nmax) + $nB = $nmax; - return $s/($n-1); -} + $EA = 1/(1+10**(($SB-$SA)/400)); + $EB = 1/(1+10**(($SA-$SB)/400)); + $newRA = ($K*$nB)/$nmax * ($RA-$EA); + $newRB = ($K*$nA)/$nmax * ($RB-$EB); + return array($newRA, $newRB); +} -/* @param $scores_actuel array - * @param $scores_obtenus array - * @param $K int (Coefficient multiplicatif propre au jeu, plus il est élevé, plus le résultat est fin) - * @param $D int (nombre de points pour qu'un joueur soit 10x plus fort qu'un autre) - * @return int - * - * @requires count($scores_actuel) == count($scores_obtenus) - * @requires $K >= 1 and $D > 1 - * - * Renvoie le nombre de points obtenus (ou perdus, dans ce cas c'est négatif) dans un tableau - * correspondant aux indices de $scores_obtenus. - * +/** + * Fonction qui calcule les différentiels de scores obtenus après une partie à count($S) joueurs + * en considérant que $R correspond au classement des joueurs dans ce jeu (du type array(1,3,4,2) pour + * le premier joueur est 1er, le second est 2e, etc). + * On suppose qu'il y a correpondance entre les indices de $S et les indices de $R. + * @param array $S : scores actuels des joueurs + * @param array $R : classement des joueurs + * @param int $nmax : le nombre de parties pour considérer "qu'un joueur est aguerri". Vaut 20 par défaut. + * @param array $n : nombre de parties de chaque joueurs + * @param int $K : la quantité max de points gagnable ou perdable sur une partie + * @return array : le différentiel de score de chaque joueur + * @throws DomainException */ -function ELO($scores_actuel, $scores_obtenus, $K, $D) +function ELO_classement($S, $R, $n, $K, $nmax=20) { - $newS = array(); - $c = max($scores_obtenus)-min($scores_obtenus); - $d = min($scores_obtenus); - - for ($j=0; $j<count($scores_obtenus); $j++) - { - $m = avg_skip($scores_actuel, $j); - $EA = 1/(1+10**(($m-$scores_actuel[$j])/$D)); - - $EA = $c * $EA + $d; - $s = $K * ($scores_obtenus[$j]-$EA); + $m = count($S); + if (count($R) != $m) + throw new DomainException; - if ($s>=0) - $newS[$j] = floor($s); - else - $newS[$j] = ceil($s); + $count = array_fill(0, $m, 0); + $res = array_fill(0, $m, 0); + for ($i = 0; $i<$m; $i++) + { + for($j=$i+1; $j<$m; $j++) + { + if ($R[$i]<$R[$j]) + $newSAB = ELO_duel($S[$i], 1, $S[$j], 0, $K, $nmax, $n[$i], $n[$j]); + else + $newSAB = ELO_duel($S[$i], 0, $S[$j], 1, $K, $nmax, $n[$i], $n[$j]); + $res[$i] = 1/($count[$i] + 1) * ($count[$i] * $res[$i] + $newSAB[1]); + $count[$i]++; + $res[$j] = 1/($count[$j] + 1) * ($count[$j] * $res[$j] + $newSAB[2]); + $count[$j]++; + } } - - return $newS; + return $res; } +/* function random_scores($n, $min, $max) { $r = array(); @@ -77,8 +87,9 @@ function random_scores($n, $min, $max) return $r; } - +*/ /* Test */ +/* print("<html><body><table><th>Itération</th><th>Joueur 1</th><th>Joueur 2</th><th>Joueur 3</th><th>Joueur 4</th><th>Joueur 5</th><th>Somme</th></tr>"); $DS = array(1000,1000,1000,1000,1000); @@ -107,4 +118,4 @@ for($j=1;$j<20;$j++){ } print("</table></body></html>"); - +*/ \ No newline at end of file