Check out Chess with Different Armies, our featured variant for July, 2024.


[ Help | Earliest Comments | Latest Comments ]
[ List All Subjects of Discussion | Create New Subject of Discussion ]
[ List Earliest Comments Only For Pages | Games | Rated Pages | Rated Games | Subjects of Discussion ]

Single Comment

Game Courier Ratings. Calculates ratings for players from Game Courier logs. Experimental.[All Comments] [Add Comment or Rating]
🕸📝Fergus Duniho wrote on Mon, Jan 9, 2006 03:20 AM UTC:
Here is what the code look like after the files are read and the $wins table is made. The $wins table is a two-dimensional array of pairwise wins, for which $wins[$p1][$p2] is the number of times $p1 has beaten $p2. Draws count as half wins for both players. // Calculate various values needed for rating calculations $players = array_keys($wins); // Initialize all ratings to 1500 reset ($players); foreach ($players as $pl) { $gcr[$pl] = $gcr1[$pl] = $gcr2[$pl] = $gcr3[$pl] = $gcr4[$pl] = 1500; } // Count opponents and games of each player reset ($players); $pc = count($players); for ($i = 0; $i < $pc; $i++) { $p1 = $players[$i]; $opponents[$p1] = 0; $gameswon[$p1] = 0; $gameslost[$p1] = 0; for ($j = 0; $j < $pc; $j++) { $p2 = $players[$j]; if (($p1 != $p2) && ($wins[$p1][$p2] || $wins[$p2][$p1])) { $opponents[$p1]++; $gameswon[$p1] += $wins[$p1][$p2]; $gameslost[$p1] += $wins[$p2][$p1]; } } $gamesplayed[$p1] = $gameswon[$p1] + $gameslost[$p1]; $percentwon[$p1] = ($gamesplayed[$p1] > 0) ? (($gameswon[$p1] * 100) / $gamesplayed[$p1]) : 0; } // Sort players function psort ($p1, $p2) { global $opponents, $gamesplayed; if ($opponents[$p1] > $opponents[$p2]) return -1; elseif ($opponents[$p1] < $opponents[$p2]) return 1; elseif ($gamesplayed[$p1] > $gamesplayed[$p2]) return -1; elseif ($gamesplayed[$p1] < $gamesplayed[$p2]) return 1; elseif ($gameswon[$p1] > $gameswon[$p2]) return -1; elseif ($gameswon[$p1] < $gameswon[$p2]) return 1; else return 0; } uasort ($players, 'psort'); // For each pair, calculate new ratings based on previous ratings. // Use zig-zagging order to optimize interdependency between ratings. for ($i = 1; $i < $pc; $i++) { for ($j = $i; $j < $pc; $j++) { $p1 = $players[$j-$i]; $p2 = $players[$j]; $n = $wins[$p1][$p2] + $wins[$p2][$p1]; if ($n == 0) continue; $stability1 = (abs($gcr1[$p1] - 1500) + 500) / 20; $stability2 = (abs($gcr1[$p2] - 1500) + 500) / 20; $reliability = (100 * $n) / ($n + 3); $gap = abs($gcr1[$p1] - $gcr1[$p2]); $lowpoint = min($gcr1[$p1],$gcr1[$p2]); $midpoint = $lowpoint + $gap/2; $gap = max($gap, 400); $lowpoint = min($lowpoint, $midpoint - 200); $pr1 = $lowpoint + ($wins[$p1][$p2] * $gap) / $n; $pr2 = $lowpoint + ($wins[$p2][$p1] * $gap) / $n; $gcr1[$p1] = (($stability1 * $gcr1[$p1]) + ($reliability * $pr1)) / ($stability1 + $reliability); $gcr1[$p2] = (($stability2 * $gcr1[$p2]) + ($reliability * $pr2)) / ($stability2 + $reliability); } } // Calculate all ratings again in reverse zig-zagging order. for ($i = $pc-1; $i > 0; $i--) { for ($j = $pc-1; $j > $i; $j--) { $p1 = $players[$j-$i]; $p2 = $players[$j]; $n = $wins[$p1][$p2] + $wins[$p2][$p1]; if ($n == 0) continue; $stability1 = (abs($gcr2[$p1] - 1500) + 500) / 20; $stability2 = (abs($gcr2[$p2] - 1500) + 500) / 20; $reliability = (100 * $n) / ($n + 3); $gap = abs($gcr2[$p1] - $gcr2[$p2]); $lowpoint = min($gcr2[$p1],$gcr2[$p2]); $midpoint = $lowpoint + $gap/2; $gap = max($gap, 400); $lowpoint = min($lowpoint, $midpoint - 200); $pr1 = $lowpoint + ($wins[$p1][$p2] * $gap) / $n; $pr2 = $lowpoint + ($wins[$p2][$p1] * $gap) / $n; $gcr2[$p1] = (($stability1 * $gcr2[$p1]) + ($reliability * $pr1)) / ($stability1 + $reliability); $gcr2[$p2] = (($stability2 * $gcr2[$p2]) + ($reliability * $pr2)) / ($stability2 + $reliability); } } // Calculate all ratings again in half reverse zig-zagging order. for ($i = 1; $i < $pc; $i++) { for ($j = $pc-1; $j > $i; $j--) { $p1 = $players[$j-$i]; $p2 = $players[$j]; $n = $wins[$p1][$p2] + $wins[$p2][$p1]; if ($n == 0) continue; $stability1 = (abs($gcr3[$p1] - 1500) + 500) / 20; $stability2 = (abs($gcr3[$p2] - 1500) + 500) / 20; $reliability = (100 * $n) / ($n + 3); $gap = abs($gcr3[$p1] - $gcr3[$p2]); $lowpoint = min($gcr3[$p1],$gcr3[$p2]); $midpoint = $lowpoint + $gap/2; $gap = max($gap, 400); $lowpoint = min($lowpoint, $midpoint - 200); $pr1 = $lowpoint + ($wins[$p1][$p2] * $gap) / $n; $pr2 = $lowpoint + ($wins[$p2][$p1] * $gap) / $n; $gcr3[$p1] = (($stability1 * $gcr3[$p1]) + ($reliability * $pr1)) / ($stability1 + $reliability); $gcr3[$p2] = (($stability2 * $gcr3[$p2]) + ($reliability * $pr2)) / ($stability2 + $reliability); } } // Calculate all ratings again in reverse half reverse zig-zagging order. for ($i = $pc-1; $i > 0; $i--) { for ($j = $i; $j < $pc; $j++) { $p1 = $players[$j-$i]; $p2 = $players[$j]; $n = $wins[$p1][$p2] + $wins[$p2][$p1]; if ($n == 0) continue; $stability1 = (abs($gcr4[$p1] - 1500) + 500) / 20; $stability2 = (abs($gcr4[$p2] - 1500) + 500) / 20; $reliability = (100 * $n) / ($n + 3); $gap = abs($gcr4[$p1] - $gcr4[$p2]); $lowpoint = min($gcr4[$p1],$gcr4[$p2]); $midpoint = $lowpoint + $gap/2; $gap = max($gap, 400); $lowpoint = min($lowpoint, $midpoint - 200); $pr1 = $lowpoint + ($wins[$p1][$p2] * $gap) / $n; $pr2 = $lowpoint + ($wins[$p2][$p1] * $gap) / $n; $gcr4[$p1] = (($stability1 * $gcr4[$p1]) + ($reliability * $pr1)) / ($stability1 + $reliability); $gcr4[$p2] = (($stability2 * $gcr4[$p2]) + ($reliability * $pr2)) / ($stability2 + $reliability); } } // Average all four sets of ratings. // This helps minimize the effects of using any order, making ratings more homogonous. for ($i = 0; $i < $pc; $i++) { $p1 = $players[$i]; $gcr[$p1] = ($gcr1[$p1] + $gcr2[$p1] + $gcr3[$p1] + $gcr4[$p1]) / 4; } // Sort ratings arsort ($gcr); reset ($gcr); // Print table of ratings echo ''; foreach ($gcr as $userid => $rating) { printf ('', userid_name($userid), $userid, $rating, $percentwon[$userid]); } echo '
Game Courier Ratings for {$gamewcp}
NameUseridGCRPercent won
%s%s%d%.2f
';