-
-
Save handy-man/f3ce5a7d86427d5037c3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* http://stackoverflow.com/questions/8355264/tournament-bracket-placement-algorithm | |
* Author: DarkAngel | |
* | |
* Simply ensures that the top player (first player) is seeded/ ordered against the worst player. | |
* 1 vs 8, 4 vs 5, 2 vs 7, 3 vs 6 <-- Typical seeding outcome from this sorting. | |
* | |
* @param $players | |
* @return array | |
*/ | |
public function SeedOrderStandard($players) | |
{ | |
$count = count($players); | |
for ($i = 0; $i < log($count / 2, 2); $i++) { | |
$out = array(); | |
foreach ($players as $player) { | |
$splice = pow(2, $i); | |
$out = array_merge($out, array_splice($players, 0, $splice)); | |
$out = array_merge($out, array_splice($players, -$splice)); | |
} | |
$players = $out; | |
} | |
return $players; | |
} | |
/** | |
* Primary function when dealing with the tournamnet, calls many other functions that take care of our seeding, and sorting of seeded data. | |
* | |
* @param $tournament | |
*/ | |
public function buildBracket($tournament) | |
{ | |
$numberOfLevels = $this->getLevels($tournament); | |
$this->createLevels($numberOfLevels, $tournament); | |
$playersToMatch = $this->SeedSteam($tournament); | |
$playersToMatch = $this->SeedOrderStandard($playersToMatch); | |
$this->SortedSeededPlayerStorage($tournament, $playersToMatch); | |
for ($x = 0; $x < count($playersToMatch); $x++) { | |
if ($x % 2 == 0) { | |
$match = new match(); | |
$match->tournament_id = $tournament->id; | |
$level_id = $tournament->levels->first(); | |
$match->level_id = $level_id->id; | |
$match->save(); | |
$match->players()->attach(array_values($playersToMatch)[$x]['id']); | |
} else { | |
$match->players()->attach(array_values($playersToMatch)[$x]['id']); | |
} | |
} | |
} | |
/** | |
* The primary function for seeding users based on genre, this uses steam but also if no steam exists will use regular points by genre. | |
* The tournament is passed into the function, from the tournament we can get the relations of players taking part. | |
* We first loop through the array of players, inside that foreach loop we do all of our points assignment. | |
* | |
* | |
* @param $tournament | |
* @return array | |
*/ | |
public function SeedSteam($tournament) | |
{ | |
$players = $tournament->playersDesc; | |
$genre = $tournament->genre; | |
$total = 0; | |
$newPlayers = array(); | |
foreach ($players as $player) { | |
$points_total = 0; | |
$appids = array(); | |
$gameids = array(); | |
$userid = $player->id; | |
$player_data = Steam::where('user_id', '=', $userid)->first(); | |
foreach(point::where('user_id', '=', $userid)->GenreSpecific($genre)->get() as $point){ | |
$points_total = $points_total + $point->amount; | |
} | |
if (is_null($player_data)) { | |
array_push($newPlayers, array('points' => $points_total, 'id' => $player->id)); | |
continue; | |
} | |
$steamid = $player_data->steamid; | |
if (is_null($steamid)) { | |
continue;//No steamID lets leave | |
} | |
$apps = steam_games_genre::where('steam_games_genre_id', '=', $genre)->get(); | |
foreach ($apps as $app) { | |
array_push($gameids, $app->steam_games_id); | |
} | |
foreach ($gameids as $game) { | |
array_push($appids, steam_games::find($game)->app_id); | |
} | |
$steam_data = SteamApi::player($steamid)->getownedgames(true, true, $appids); | |
foreach ($steam_data as $steam) { | |
$total = $total + $steam->playtimeForever; | |
} | |
$total = $total + $points_total; | |
array_push($newPlayers, array('points' => $total, 'id' => $player->id)); | |
$total = 0; | |
} | |
$arraysize = count($newPlayers); | |
if ((($arraysize - 1) & $arraysize) == 0) { | |
//Power of 2, YAY! | |
} | |
else | |
{ | |
$newPlayers = $this->ByeSystem($newPlayers, $arraysize); | |
} | |
arsort($newPlayers); | |
$this->StoreSeedData($tournament, $newPlayers); | |
return $newPlayers; | |
} | |
/** | |
* When an odd number of players exists we need to implement a bye system (adding fake results) ID#9 is the ID of my player called "bye" in the test data | |
* This is technically a bad implementation and was required due to a missing feature in the JS library being unable to deal with lack of power of 2. | |
* This looks worst when there are 9 players (needing to add 7 bye's until next power of 2) will look better visually the closer we are. | |
* | |
* @param $newPlayers | |
* @return mixed | |
*/ | |
public function ByeSystem($newPlayers, $arraysize) | |
{ | |
$user = User::where('displayname', '=', 'Bye')->get(); | |
$nextPower = pow(2, ceil(log($arraysize) / log(2))); | |
$differnce = $nextPower - $arraysize; | |
for ($i = 0; $differnce > $i; $i++) { | |
array_push($newPlayers, array('points' => -1, 'id' => $user->id)); | |
} | |
return $newPlayers; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment