:: Anbieterverzeichnis ::
Globale Branchen
Informieren Sie sich über ausgewählte
Unternehmen im
Anbieterverzeichnis von SELFPHP
:: SELFPHP Forum ::
Fragen rund um die Themen PHP? In über
120.000 Beiträgen finden Sie sicher die passende
Antwort!
:: Newsletter ::
Abonnieren Sie hier den kostenlosen
SELFPHP Newsletter!
:: Qozido ::
Die Bilderverwaltung mit Logbuch für
Taucher und Schnorchler.
|
|
Berechnung der Elo-Zahl für Spielstärken-Bewertung |
Beispielaufgabe
Mit der nachfolgenden PHP5 Klasse kann komfortabel die Elo-Zahl berechnet werden. Bei der Elo-Zahl handelt es sich um ein objektives Wertungssystem, um die Spielstärke eines Spielers berechnen zu können. Das Wertungssystem wurde ursprünglich von Arpad Elo für den amerikanischen Schachverband USCF entwickelt, wird heute allerdings in verschiedenen Varianten für Berechnungen herangezogen (z.B. für das Ranglistensystem der Nationalmannschaften im Fußball).
Diese Klasse und somit die Berechnung kann daher für viele Spielvarianten genutzt werden, bei denen es darum geht, anhand von Ranglisten die Spielstärke zu ermitteln.
Die Elo-Zahl sorgt dafür, dass ein Spieler mit einer hohen Elo-Zahl und somit mit einem hohen Ranking, bei einem Sieg über einem schwächer platzierten Spieler, weniger Punkte erhalten würde, als wenn umgekehrt der schwächere Gegner den stärkeren Gegner bezwingt. Im Umkehrschluß heißt das, wenn ein stärkerer Gegner gegen einen schwächeren Gegner verliert, er mehr Punkte einbüßen würde als umgekehrt, wenn der schwächere Gegner gegen den Stärkeren verliert. Genauso verhält es sich dann auch bei einem Remis - der stärkere Spieler verliert Punkte, während der schwächere Spieler einen Punktezuwachs erhält.
Beispiel 1: Spieler A spielt gegen Spieler B (Erwartung das Spieler A gewinnt: 0.68 - entspricht 68% )
Rank |
Spieler |
Elo-Zahl |
1 |
A |
1950 |
2 |
B |
1820 |
3 |
C |
1590 |
4 |
D |
1495 |
5 |
E |
1410 |
Mögliche Szenarien:
Spieler A gewinnt und erhält für den Sieg 5 Punkte, Spieler B verliert 5 Punkte
Spieler B gewinnt und erhält für den Sieg 10 Punkte, Spieler A verliert 10 Punkte
Bei einem Remis erhält Spieler B 3 Punkte, Spieler A verliert allerdings 3 Punkte
Beispiel 2: Spieler A spielt gegen Spieler E (Erwartung das Spieler A gewinnt: 0.89 - entspricht 89%)
Rank |
Spieler |
Elo-Zahl |
1 |
A |
1950 |
2 |
B |
1820 |
3 |
C |
1590 |
4 |
D |
1495 |
5 |
E |
1410 |
Mögliche Szenarien:
Spieler A gewinnt und erhält für den Sieg 2 Punkte, Spieler E verliert 2 Punkte
Spieler E gewinnt und erhält für den Sieg 13 Punkte, Spieler A verliert 13 Punkte
Bei einem Remis erhält Spieler E 6 Punkte, Spieler A verliert allerdings 6 Punkte
Wie Sie sehen, wird anhand der Rangliste genau differenziert, wieviel ein Spieler bei einem Sieg, einer Niederlage oder bei einem Remis an Punkte erhält oder verliert.
elo-example.php
Hierbei handelt es sich nur um eine Beispieldatei, die die Handhabung der Klasse vorstellen soll.
<?php
include_once 'EloRatingSystem.php';
$elo = new EloRatingSystem( );
$game = $elo -> setGame( 1950, 1410, 0.5, 15 );
// 0 = Spieler A
$newEloA = $elo -> getEloPlayers( 0 );
print_r($newEloA);
// 1 = Spieler B
$newEloB = $elo -> getEloPlayers( 1 );
print_r($newEloB);
?>
|
EloRatingSystem.php
Hier sehen Sie noch die vollständige Klasse für die Berechnung der Elo-Zahl. In dieser Datei müssen Sie nichts ändern.
<?php
/**
* Calculate Elo-Ratings
* http://de.wikipedia.org/wiki/Elo-Zahl
*
* @author SELFPHP OHG
* @copyright 2009, SELFPHP OHG
* @license BSD License
* @link http://www.selfphp.de
*
* Minnimum Elo ist 1200
* Maximum Elo ist 2999
*/
class EloRatingSystem {
/**
* @var integer Elo-Zahl Spieler 1
*/
private $ratingPlayerA = 0;
/**
* @var integer Elo-Zahl Spieler 2
*/
private $ratingPlayerB = 0;
/**
* @var Double Spielausgang
* 1 = Sieg
* 0.5 = Unentschieden
* 0 = Niederlage
*/
private $gameResult = 0;
/**
* @var Integer Faktor
* 25 = bis mindestens 30 Partien
* 15 = solange das Rating (Elo-Zahl) kleiner als 2400
* 10 = wenn Rating (Elo-Zahl) größer als 2400 und mindestens 30 Partien
* danach (nach 2400) bleibt der Wert konstant bei 10
*/
private $kValue = 25;
/**
* @var Double Wert (+ / -) der Erwartung nach Prof. Arpad Elo
*/
private $expectation = 0;
/**
* @var Integer Differenz der beiden Elo-Zahlen
*/
private $difference = 0;
/**
* Spielergebnis setzen
*
* @param integer $playerA Elo-Zahl von Spieler A
* @param integer $playerB Elo-Zahl von Spieler B
* @param integer $result Ergebnis: 1 bei Sieg von Spieler A,
* 0.5 bei Remis, 0 bei Niederlage von Spieler A
* @param integer $constK Konstant K (25, 15 oder 10)
*
* @return bool true
*/
public function setGame( $playerA = NULL, $playerB = NULL, $result = NULL, $constK = NULL ) {
if ( !empty( $playerA ) && $playerA >= 0 )
$this->ratingPlayerA = $playerA;
else
$this->ratingPlayerA = 0;
if ( !empty( $playerB ) && $playerB >= 0 )
$this->ratingPlayerB = $playerB;
else
$this->ratingPlayerB = 0;
if ( $result == 1 )
$this->gameResult = 1;
elseif ( $result == 0.5 )
$this->gameResult = 0.5;
else
$this->gameResult = 0;
$this->setKValue( $constK );
$this->setDifference();
$this->setExpectation();
return true;
}
/**
* Setzt die Konstante K
*
* @return bool true
*/
private function setKValue( $value ){
switch ( $value ) {
case 10:
$this->kValue = 10;
break;
case 15:
$this->kValue = 15;
break;
default:
$this->kValue = 25;
break;
}
return true;
}
/**
* Setzt die Differenz der beiden Elo-Zahlen der Spieler
*
* @return bool true
*/
private function setDifference(){
$this->difference = $this->ratingPlayerA - $this->ratingPlayerB;
return true;
}
/**
* Berechnet den Wert (+ / -) für die Erwartung des Spielausgangs nach Prof. Arpad Elo
*
* @return double Der erwartete Wert
*/
private function setExpectation(){
if ( abs( $this->difference ) > 350)
$diff = 350;
else
$diff = $this->difference;
$value = 0.5 + 1.4217 * bcpow( 10, -3, 3 ) * $diff
-2.4336 * bcpow( 10, -7, 7 ) * $diff * abs( $diff )
-2.5140 * bcpow( 10, -9, 9 ) * $diff * bcpow( abs( $diff ), 2 )
+1.9910 * bcpow( 10, -12, 12 ) * $diff * bcpow( abs( $diff ), 3 );
$this->expectation = round( $value, 2 );
return $this->expectation;
}
/**
* Liefert die neue Elo-Zahl für den jeweiligen Spieler
*
* @param integer $value 0 = Spieler A, 1 = Spieler B
*
* @return array Ein Array mit den Werten
*/
public function getEloPlayers( $value ){
if ( $value == 0 ){
$player = $this->ratingPlayerA;
$newElo['modification'] = round( ( $this->gameResult - $this->expectation ) * $this->kValue );
}
else{
$player = $this->ratingPlayerB;
$newElo['modification'] = -round( ( $this->gameResult - $this->expectation ) * $this->kValue );
}
$newElo['difference'] = $this->difference;
$newElo['oldElo'] = $player;
$newElo['newElo'] = $player + $newElo['modification'];
$newElo['expectation'] = $this->expectation;
return $newElo;
}
}
?>
|
Download
elo-ranking.zip
|
|
|
|
|
|