php实现dota天梯、wow竞技场、lol排位赛匹配加分算法ELO

public function marchOpponents()

{

$rstep = Yii::$app->params[‘ratingStep’];//(随机范围)

$rsN=100;

$db=Yii::$app->db;

$m= $this->streak*$rstep;//根据连败取人数

$c = GmPlayerRating::find()->where(“rating > :rating”,[‘:rating’=>$this->rating])->count();//分数所在排名

Yii::error(“gid “.$this->gid.” 排名 “.$c );

if ($c<$m)//如50名 要取6连胜后的-10-0名

{

$m=0;

Yii::error(” c < m “);

}else {//否则取开头 如取3连胜则取 20-30区间

$m = $c-$m;

}

//从上到下取匹配到的玩家

$sql = “select gid from gm_player_rating where gid !=:uid and protect_tm<:nowtm order by rating desc limit :m,:n”;

$values = [‘:uid’=>$this->gid,‘:nowtm’=>time(),‘:m’=>$m,‘:n’=>$rsN];

$res = $db->createCommand($sql)->bindValues($values)

->queryAll();

//         if ($this->streak > 0 && count($res==0)){//连胜 取高分,上方无人

//             $sql = “select gid from gm_player_rating where protect_tm<:nowtm order by rating desc limit :n”;

//             $values = [‘:nowtm’=>time(),':n’=>$rstep];

//             $res = $db->createCommand($sql)->bindValues($values)

//             ->queryAll();

//         }

if ($this->streak < 0 && count($res)==0){//连败取低分,下方无人

//

$sql = “select gid from gm_player_rating where  gid !=:uid and protect_tm<:nowtm order by rating asc limit :n”;

$values = [‘:uid’=>$this->gid,‘:nowtm’=>time(),‘:n’=>$rsN];

$res = $db->createCommand($sql)->bindValues($values)

->queryAll();

}

//         echo “count rest:”.count($res);

if ($res==“” || count($res)==0)

return 0;

$rx=$res[array_rand($res)];

//         print_r($rx);

return $rx[‘gid’];

}

///核心 elo 算法内容计算期望值

public static function eloRatingScore($pa,$pb,$win=1)

{//按照rating 获取期望所得的声望值

$Ra=GmPlayerRating::findOne($pa)->rating;

$Rb=GmPlayerRating::findOne($pb)->rating;

$Ea = 1/(1+pow(10, ($Rb-$Ra)/400));

//         $Eb = 1/(1+pow(10, ($Ra-$Rb)/400));

//胜利期望值

$rssss=(1 – $Ea);

if ($rssss<(1/Yii::$app->params[‘ratingK’]/2))$rssss=0;

$RSa = intval(Yii::$app->params[‘ratingK’] *$rssss);

//失败期望值

if ($win==-1) $RSa = intval(Yii::$app->params[‘ratingK’] * (0 – $Ea));

return $RSa;

}