public static function _beginEliminations(Api\Bracket $bracket) { $days = Lib\Url::Post('days', true); if ($bracket && $bracket->state == BS_NOMINATIONS) { if (!$days) { $result = Lib\Db::Query('SELECT COUNT(1) AS total FROM `character` WHERE bracket_id = :id', [':id' => $bracket->id]); if ($result) { $count = Lib\Db::Fetch($result); $bracket->count = (int) $count->total; } Lib\Display::renderAndAddKey('content', 'admin/eliminations', $bracket); } else { $days = (int) $days; $result = Lib\Db::Query('SELECT character_id FROM `character` WHERE bracket_id = :id ORDER BY RAND()', [':id' => $bracket->id]); if ($result && $result->count) { $group = 0; $order = 0; while ($row = Lib\Db::Fetch($result)) { $round = new Api\Round(); $round->bracketId = $bracket->id; $round->tier = 0; $round->group = $group; $round->order = $order; $round->character1Id = $row->character_id; $round->character2Id = 1; $round->sync(); $order++; $group = $order % $days; } $bracket->state = BS_ELIMINATIONS; if ($bracket->sync()) { $message = self::_createMessage('success', 'Eliminations for "' . $bracket->name . '" have started.'); } self::_refreshCaches($bracket); self::_main($message); } } } }
/** * Takes the results from the elimination rounds and creates a seeded bracket */ public function createBracketFromEliminations($entrants, $groups) { $retVal = false; if (is_numeric($entrants)) { // Generate the bracket template $seeding = self::generateSeededBracket($entrants); // Get the max vote counts for each day $result = Lib\Db::Query('SELECT COUNT(1) AS total, r.round_group FROM votes v INNER JOIN round r ON r.round_id = v.round_id WHERE v.bracket_id = :bracketId GROUP BY r.round_group', [':bracketId' => $this->id]); $groupCounts = []; $max = 0; while ($row = Lib\Db::Fetch($result)) { $votes = (int) $row->total; $groupCounts[(int) $row->round_group] = $votes; $max = $votes > $max ? $votes : $max; } $characters = []; $result = Lib\Db::Query('SELECT COUNT(1) AS total, c.*, r.round_group FROM `round` r INNER JOIN `character` c ON c.character_id = r.round_character1_id LEFT OUTER JOIN votes v ON v.character_id = c.character_id WHERE r.round_tier = 0 AND r.bracket_id = :bracketId GROUP BY c.character_id', [':bracketId' => $this->id]); // Ensure that we have characters and there are at least enough to meet the bracket constraints if ($result && $result->count >= $entrants) { while ($row = Lib\Db::Fetch($result)) { $obj = new Character($row); // Normalize the votes against the highest day of voting to ensure that seeding order is reflective of flucuations in daily voting // $obj->adjustedVotes = round(($obj->votes / $groups[$obj->group]) * $max); $obj->adjustedVotes = round((int) $row->total / $groupCounts[(int) $row->round_group] * $max); $characters[] = $obj; } // Reorder by adjusted votes usort($characters, function ($a, $b) { return $a->adjustedVotes < $b->adjustedVotes ? 1 : -1; }); // Set up the rounds $groupSplit = $entrants / $groups; for ($i = 0; $i < $entrants; $i += 2) { $round = new Round(); $round->bracketId = $this->id; $round->tier = 1; $round->order = ($i + 1) % $groupSplit; $round->group = floor($i / $groupSplit); // Get the correct character and save their seed $character1 = $characters[$seeding[$i] - 1]; $character1->seed = $seeding[$i]; $character1->sync(); $character2 = $characters[$seeding[$i + 1] - 1]; $character2->seed = $seeding[$i + 1]; $character2->sync(); $round->character1Id = $character1->id; $round->character2Id = $character2->id; $round->sync(); } // Change the state to standard bracket voting $this->state = BS_VOTING; $retVal = $this->sync(); // Force update the results cache $this->getResults(true); } } return $retVal; }