From f1bf4ef8ac628cdee4aea425e8fb3fbf7246e0b0 Mon Sep 17 00:00:00 2001 From: hujiabin <519660157@qq.com> Date: Thu, 25 Apr 2024 19:33:40 +0800 Subject: [PATCH] 1 --- webapp/controller/BattleController.class.php | 19 ++++ webapp/services/FormulaService.php | 42 +++++++++ webapp/services/RoomBattleDataService.php | 96 +++++++++----------- webapp/services/TameBattleDataService.php | 39 ++++---- 4 files changed, 127 insertions(+), 69 deletions(-) diff --git a/webapp/controller/BattleController.class.php b/webapp/controller/BattleController.class.php index b5a94865..3eb2e070 100644 --- a/webapp/controller/BattleController.class.php +++ b/webapp/controller/BattleController.class.php @@ -230,6 +230,7 @@ class BattleController extends BaseAuthedController { } } $realUserNum = 0; + //对赌模式统计真人数 if ($roomBattleDataService->mapMode == mt\MapMode::BET_MODE){ foreach ($input["team_list"] as $teamData){ foreach ($teamData['members'] as $member){ @@ -239,6 +240,24 @@ class BattleController extends BaseAuthedController { } } } + //排位模式计算个人排名 + if ($roomBattleDataService->mapMode == mt\MapMode::RANKING_MODE){ + foreach ($input["team_list"] as $teamData){ + foreach ($teamData['members'] as $member){ + $ExpScore = $roomBattleDataService->_calBattleScore($member); + array_push($roomBattleDataService->teamExpScoreSort,array( + 'account_id' => getXVal($member,'account_id', 0), + 'expScore' => $ExpScore + )); + } + } + usort($roomBattleDataService->teamExpScoreSort,function ($a,$b){ + if ($a['expScore'] == $b['expScore']) { + return 0; + } + return ($a['expScore'] < $b['expScore']) ? -1 : 1; + }); + } $roomBattleDataService->realUserCount = $realUserNum; foreach ($input["team_list"] as $teamData){ $battle_uuid = getXVal($teamData,'battle_uuid', 0); diff --git a/webapp/services/FormulaService.php b/webapp/services/FormulaService.php index e3ae6bee..41063e61 100644 --- a/webapp/services/FormulaService.php +++ b/webapp/services/FormulaService.php @@ -377,6 +377,48 @@ class FormulaService extends BaseService { return round(max($userDb['elo']+$K*($winRate-$winRateSum),150)); } + + public static function calcBattleAfterRankScoreNew($userDb,$ranked,$teamRank,$winningPro){ + /**一个玩家的赛后积分 = 赛前积分+K/2*(MAX(胜负率-总胜率,0))+K*(表现分-段位要求的及格分)*/ + //胜负率=1-(排名-1)/(最大排名-1) +// $ranked = getXVal($params, 'pvp_personal_rank'); +// $teamRank = min(getXVal($params, 'pvp_team_rank'),10); + $maxRanked = mt\Parameter::getVal('rank_order_max',40); //************** parameter 参数表获取 ************ + $winRate = 1-($ranked-1)/($maxRanked-1); + //总胜率=70%*P(个人ELO值-敌队平均ELO值)+30%*P(己队平均ELO值-敌队平均ELO值) --> P(D)=1/(1+10^(-D/400)) + $winRateSum = $winningPro; + //表现分=f(个人存活时间排名TopX/4)*50%+f(队伍排名TopY)*50% f(TopX) = ROUND(1-(X-1)/9,2) + $expreScore = (ROUND(1-($ranked/4-1)/9,2))*0.5+ROUND(1-($teamRank-1)/9,2)*0.5; + + $rankMeta = mt\Rank::getRankById($userDb['rank']); + //不同段位的及格分 = ROUND(1-(大段位排名-1)/(MAX(10)-1),2) + $topRanking = $rankMeta['rank_order']; //************** rankRank 参数表获取 ************ + $rankPint = mt\Parameter::getVal('rank_pass_point',0); //************** parameter 参数表获取 ************ + $rankPintArr = explode('|',$rankPint); + $askedScore = $rankPintArr[$topRanking-1]; + //一个玩家的赛后积分 = 赛前积分+K*(胜负率-总胜率)+2K*(表现分-段位要求的及格分) + //一个玩家的赛后积分 = 赛前积分+K/2*(MAX(胜负率-总胜率,0))+K*(表现分-段位要求的及格分) + //一个玩家的赛后积分 = 赛前积分+K/2*(MAX(胜负率-0.5,0))+K/2*(表现分-段位要求的及格分) 新 + $kArr = explode('|',mt\Parameter::getVal('rank_k',0)); //************** parameter 参数表获取 ************ + $K = $kArr[$rankMeta['rank_order2']-1]; + $battleAfterScore = $userDb['score'] + $K/2 * max(($winRate-0.5),0) + ($K/2) * ($expreScore-$askedScore); + return round($battleAfterScore); + } + + public static function calcUserEloValueNew($userDb,$ranked,$winningPro){ + /**一个玩家的赛后ELO值 = MAX(赛前ELO值+K*(胜负率-总胜率),150)*/ + //胜负率=1-(排名-1)/(最大排名-1) +// $ranked = getXVal($params, 'pvp_personal_rank'); + $maxRanked = mt\Parameter::getVal('rank_order_max',40); //************** parameter 参数表获取 ************ + $winRate = 1-($ranked-1)/($maxRanked-1); + //总胜率=70%*P(个人ELO值-敌队平均ELO值)+30%*P(己队平均ELO值-敌队平均ELO值) --> P(D)=1/(1+10^(-D/400)) + $winRateSum = $winningPro; + $rankMeta = mt\Rank::getRankById($userDb['rank']); + $kArr = explode('|',mt\Parameter::getVal('rank_k',0)); //************** parameter 参数表获取 ************ + $K = $kArr[$rankMeta['rank_order2']-1]; + return round(max($userDb['elo']+$K*($winRate-$winRateSum),150)); + } + /** -------------------------------------------------新公式----------------------------------------------------------- */ diff --git a/webapp/services/RoomBattleDataService.php b/webapp/services/RoomBattleDataService.php index 611ae1e0..eea35139 100644 --- a/webapp/services/RoomBattleDataService.php +++ b/webapp/services/RoomBattleDataService.php @@ -6,6 +6,7 @@ require_once('models/Hero.php'); require_once('models/HashRate.php'); require_once('mt/MapMode.php'); +require_once('mt/Rank.php'); require_once('services/AwardService.php'); require_once('services/PropertyChgService.php'); @@ -24,6 +25,9 @@ class RoomBattleDataService extends BaseService { const ROOM_MODE_MOBA = 2; + public $teamExpScoreSort = array(); + + public $mapMode = 0; public $inputData = array(); public $teamData = array(); @@ -63,59 +67,12 @@ class RoomBattleDataService extends BaseService { $propertyChgService = new services\PropertyChgService(); $awardService = new services\AwardService(); foreach ($battleData['members'] as &$member){ -// if ($this->maxKill == 0){ -// $killSco = $scoreParam[0]; -// }else{ -// $kill = getXVal($member,'pvp_kill', 0); -// $killSco = ($scoreParam[1] - $scoreParam[0]) / ($this->maxKill - 0) * ($kill - 0) + $scoreParam[0]; -// } -// if ($this->maxAssist == 0){ -// $assistSco = $scoreParam[0]; -// }else{ -// $assist = getXVal($member,'pvp_assist', 0); -// $assistSco = ($scoreParam[1] - $scoreParam[0]) / ($this->maxAssist - 0) * ($assist - 0) + $scoreParam[0]; -// } -// if ($this->maxDamage == 0){ -// $damageSco = $scoreParam[0]; -// }else{ -// $damage = getXVal($member,'pvp_damage', 0); -// $damageSco = ($scoreParam[1] - $scoreParam[0]) / ($this->maxDamage - 0) * ($damage - 0) + $scoreParam[0]; -// } -// if ($this->maxRecover == 0){ -// $recoverSco = $scoreParam[0]; -// }else{ -// $recover = getXVal($member,'pvp_recover', 0); -// $recoverSco = ($scoreParam[1] - $scoreParam[0]) / ($this->maxRecover - 0) * ($recover - 0) + $scoreParam[0]; -// } -// if ($this->maxLevel == 1){ -// $levelSco = $scoreParam[0]; -// }else{ -// $level = getXVal($member,'hero_lv', 0); -// $levelSco = ($scoreParam[1] - $scoreParam[0]) / ($this->maxLevel - 0) * ($level - 0) + $scoreParam[0]; -// } -// if ($this->maxAlive == 0){ -// $aliveSco = $scoreParam[0]; -// }else{ -// $alive = getXVal($member,'pvp_survia_time', 0) / 1000; -// $aliveSco = ($scoreParam[1] - $scoreParam[0]) / ($this->maxAlive - 0) * ($alive - 0) + $scoreParam[0]; -// } -// switch ($room_mode){ -// case self::ROOM_MODE_PVP: { -// $battleScore = round($killSco + $assistSco + $damageSco + $recoverSco + $aliveSco , 2); -// } -// break; -// case self::ROOM_MODE_MOBA :{ -// $battleScore = round($killSco + $assistSco + $damageSco + $recoverSco + $levelSco , 2); -// } -// break; -// default : { -// $battleScore = 0; -// } -// } $battleScore = $this->_calBattleScore($member); $member['battle_score'] = $battleScore; // //验证非机器人 + $teamRanked = getXVal($member,'pvp_team_rank', 0); + $winningPro = getXVal($member,'winningPro', 0); $account = getXVal($member,'account_id', 0); if(!myself()->_isAndroidAccountId($account)){ error_log('Real Account:'.$account); @@ -123,6 +80,32 @@ class RoomBattleDataService extends BaseService { $userDb = myself()->_getOrmUserInfo(); $heroDb = Hero::find(getXVal($member,'hero_uniid', 0)); if ($userDb && $heroDb){ + //排位模式排位分计算 + if ($this->mapMode == mt\MapMode::RANKING_MODE){ + $newRank=$userDb['rank']; + $ranked = $this->getMyRanked($account); + $newScore = FormulaService::calcBattleAfterRankScoreNew($userDb,$ranked,$teamRanked,$winningPro); + $newElo = FormulaService::calcUserEloValueNew($userDb,$ranked,$winningPro); + if ($newScore < $userDb['score'] && $userDb['score']< 1300){ + $newScore = $userDb['score']; + } + mt\Rank::calcNewRankAndScore( $newRank, $newScore); + myself()->_updateUserInfo(array( + 'rank' => $newRank, + 'score' => $newScore, + 'elo' => $newElo, + 'history_best_rank' => max($userDb['history_best_rank'], $newRank), + 'history_best_score' => max($userDb['history_best_score'], $newScore), + 'score_modifytime' => myself()->_getNowTime(), + 'best_rank_modifytime' => $newRank > $userDb['rank'] ? + myself()->_getNowTime() : $userDb['best_rank_modifytime'], + )); + $member['new_rank'] = $newRank; + $member['new_score'] = $newScore; + $member['new_elo'] = $newElo; + } + + $this->_getBattleRewards($userDb,$heroDb,$battleScore,$myTeamScoreAvg,$myTeamScore,$member['reward']); myself()->_addItems($member['reward'], $awardService,$propertyChgService); @@ -130,6 +113,9 @@ class RoomBattleDataService extends BaseService { if ($battleSingleDb){ $battleSingleData = emptyReplace(json_decode($battleSingleDb['data'], true), array()); $battleSingleData['reward'] = $member['reward']; + $battleSingleData['new_rank'] = $member['new_rank']; + $battleSingleData['new_score'] = $member['new_score']; + $battleSingleData['new_elo'] = $member['new_elo']; BattleSettlement::addSingle($battleSingleDb['battle_uuid'],$battleSingleDb['room_uuid'],$battleSingleData); } } @@ -251,8 +237,7 @@ class RoomBattleDataService extends BaseService { } } - - private function _calBattleScore($battleInfo){ + public function _calBattleScore($battleInfo){ $paramMeta = mt\Parameter::getVal('performance_score_range',0); $scoreParam = explode("|",$paramMeta); if (count($scoreParam) < 2){ @@ -312,4 +297,13 @@ class RoomBattleDataService extends BaseService { return $battleScore; } + private function getMyRanked($account){ + foreach ($this->teamExpScoreSort as $k=>$value){ + if ($value['account_id'] == $account){ + return $k+1; + } + } + return 8; + } + } diff --git a/webapp/services/TameBattleDataService.php b/webapp/services/TameBattleDataService.php index e2a054c8..9f3a344f 100644 --- a/webapp/services/TameBattleDataService.php +++ b/webapp/services/TameBattleDataService.php @@ -635,32 +635,33 @@ class TameBattleDataService extends BaseService { $newScore = 0; $oldElo = 0; $newElo = 0; + $winningPro=0; $userDb = User::find(getXVal($info,'account_id', 0)); $rewards = array(); if ($userDb){ -// $this->calStarNum2($rewards,getXVal($info,'pvp_personal_rank', 0),$userDb['account_id']); + $winningPro = $this->celWinningPro($userDb); $oldRank = $userDb['rank']; $newRank = $userDb['rank']; $oldScore = $userDb['score']; $newScore = $userDb['score']; $oldElo = $userDb['elo']; $newElo = $userDb['elo']; - $heroDb = Hero::findByAccountId(getXVal($info,'account_id', 0),getXVal($info,'hero_uniid', 0)); - if ($heroDb){ -// self::calBattleReward($userDb,$heroDb,$rewards); - if ($pvp_mode == self::MATCH_MODE_RANK){ - $winningPro = $this->celWinningPro($userDb); - if ($winningPro){ - $newElo = FormulaService::calcUserEloValue($userDb,$info,$winningPro); //赛后elo积分 - $newScore = FormulaService::calcBattleAfterRankScore($userDb,$info,$winningPro); //赛后排位积分 - //黄金以下段位,失败时不扣积分 - if ($newScore < $userDb['score'] && $userDb['score']< 1300){ - $newScore = $userDb['score']; - } - mt\Rank::calcNewRankAndScore( $newRank, $newScore); - } - } - } +// $heroDb = Hero::findByAccountId(getXVal($info,'account_id', 0),getXVal($info,'hero_uniid', 0)); +// if ($heroDb){ +//// self::calBattleReward($userDb,$heroDb,$rewards); +// if ($pvp_mode == self::MATCH_MODE_RANK){ +// $winningPro = $this->celWinningPro($userDb); +// if ($winningPro){ +// $newElo = FormulaService::calcUserEloValue($userDb,$info,$winningPro); //赛后elo积分 +// $newScore = FormulaService::calcBattleAfterRankScore($userDb,$info,$winningPro); //赛后排位积分 +// //黄金以下段位,失败时不扣积分 +// if ($newScore < $userDb['score'] && $userDb['score']< 1300){ +// $newScore = $userDb['score']; +// } +// mt\Rank::calcNewRankAndScore( $newRank, $newScore); +// } +// } +// } } $temp = array( @@ -687,6 +688,7 @@ class TameBattleDataService extends BaseService { 'pvp_recover'=> getXVal($info,'pvp_recover', 0), 'pvp_rescue'=> getXVal($info,'pvp_rescue', 0), 'pvp_personal_rank'=> getXVal($info,'pvp_personal_rank', 0), + 'pvp_team_rank'=> getXVal($info,'pvp_team_rank', 0), 'pve_order'=> getXVal($info,'pve_order', 0), 'pve_score'=> getXVal($info,'pve_score', 0), 'pve_star'=> getXVal($info,'pve_star', 0), @@ -699,7 +701,8 @@ class TameBattleDataService extends BaseService { 'hero_lv'=> getXVal($info,'hero_lv', 1), 'dead_times'=> getXVal($info,'dead_times', 0), 'battle_score'=> 0, - 'reward' => $rewards + 'reward' => $rewards, + 'winningPro' => $winningPro ); array_push($data['members'],$temp); }