/** * Recalculates match history for all teams and matches * * Recalculation is done as follows: * 1. A match is chosen as a starting point - it's stored old team ELOs are * considered correct * 2. Team ELOs are reset to their values at the starting point * 3. Each match that occurred since the first specified match has its ELO * recalculated based on the current team values, and the new match data * and team ELOs are stored in the database * * @param Match $match The first match */ private function recalculate(Match $match) { try { // Commented out to prevent ridiculously large recalculations //set_time_limit(0); $query = Match::getQueryBuilder()->where('status')->notEquals('deleted')->where('type')->equals(Match::OFFICIAL)->where('time')->isAfter($match->getTimestamp(), $inclusive = true)->sortBy('time'); /** @var Match[] $matches */ $matches = $query->getModels($fast = true); // Send the total count to client-side javascript $this->log(count($matches) . "\n"); // Start a transaction so tables are locked and we don't stay with // messed up data if something goes wrong Database::getInstance()->startTransaction(); $teamsReset = []; // Reset match teams, in case the selected match is deleted and does // not show up in the list of matches to recalculate $match->getTeamA()->setElo($match->getTeamAEloOld()); $match->getTeamB()->setElo($match->getTeamBEloOld()); $teamsReset[$match->getTeamA()->getId()] = true; $teamsReset[$match->getTeamB()->getId()] = true; foreach ($matches as $i => $match) { // Reset teams' ELOs if they haven't been reset already if (!isset($teamsReset[$match->getTeamA()->getId()])) { $teamsReset[$match->getTeamA()->getId()] = true; $match->getTeamA()->setElo($match->getTeamAEloOld()); } if (!isset($teamsReset[$match->getTeamB()->getId()])) { $teamsReset[$match->getTeamB()->getId()] = true; $match->getTeamB()->setElo($match->getTeamBEloOld()); } $match->recalculateElo(); // Send an update to the client-side javascript, so that a // progress bar can be updated $this->log("m"); } } catch (Exception $e) { Database::getInstance()->rollback(); Database::getInstance()->finishTransaction(); throw $e; } Database::getInstance()->finishTransaction(); $this->log("\n\nCalculation successful\n"); }
/** * Find if a specific match is the team's last one * * @param int|Match $match The match * @return bool */ public function isLastMatch($match) { // Find if this team participated in any matches after the current match return !Match::getQueryBuilder()->with($this)->where('status')->notEquals('deleted')->where('time')->isAfter(Match::get($match)->getTimestamp())->any(); }
/** * Get the match activity in matches per day for a player * * @return float */ public function getMatchActivity() { $activity = 0.0; $matches = Match::getQueryBuilder()->active()->with($this)->where('time')->isAfter(TimeDate::from('45 days ago'))->getModels($fast = true); foreach ($matches as $match) { $activity += $match->getActivity(); } return $activity; }
/** * Find if a specific match is the team's last one * * @param int $matchID The ID of the match * @return bool */ public function isLastMatch($matchID) { // Find if this team participated in any matches after the current match return !Match::getQueryBuilder()->with($this)->active()->sortBy('id')->reverse()->startAt($matchID)->any(); }
/** * Get the number of matches played on this map * * @return int */ public function countMatches() { return Match::getQueryBuilder()->active()->where('map')->is($this)->count(); }