to ogolnie zalezy od tego jaki system turniejowy chcesz zaimplementowac. w klasycznym elimination tournament jest to tak:
liczba ludzi jest zawsze równana do potęgi dwójki. Przynajmniej ja tak zrobilem u siebie w systemie turniejowym.
Te osoby które nie mają pary przechodzą do kolejnej rundy za darmo.
Gracze są rozrzucani za pomocą algorytmu który ich miesza ze sobą: pierwszy z ostatnim, drugi z przedostatnim, a jak była wieksza ilosc graczy to sie to tam jakos komplikowalo... w każdym razie jest tak jak powinno być bo algorytm pisałem tak by się pokrywał z drzewkami generowanymi przez esl.com albo bracketgenerator.

tak wyglada przykladowe drzewko dla 5 druzyn.
to na dole to koszyk przegranych czekajacy na spadających graczy z dołu
<?php
/**
* Stała oznaczająca że teraz pobieramy górny środek
*/
/**
* Stała oznaczająca że teraz pobieramy dolny środek
*/
define('UPORDOWN_DOWN', false); /**
* Rekord uzywany do przekazania lewego i prawego końca tabelki która jest podtabelką głównej tabelki
*/
class Bounds
{
/**
* Początek
* @var int
*/
public $beginning;
/**
* Koniec
* @var int
*/
public $ending;
}
/**
* Ta klasa zawiera algorytm ukladajacy liste graczy i zwracajacy gotowe ułożenie graczy do bitew tak by na siebie nie wpadali.
*/
class TeamsPositionAlgorithm
{
/**
* Przechowuje liczbe par drużyn do ułożenia
* @var int
*/
protected $howMuchPlayers;
/**
* Informacja czy teraz górny czy dolny środek
* @var bool
*/
protected $upOrDown;
/**
* Ilość poziomów w układanym tournamencie (rund)
* @var int
*/
protected $levels;
/**
* Wynik zwrocony przez generator ciągu
* @var array
*/
public $generatorResult;
/**
* Koncowy wynik - pary druzyn ulozone w odpowiedniej kolejnosci gotowe do przelozenia na bitwy
* @var array
*/
public $result;
/**
* Konstruktor, przelicza wszystko, pozniej nalezy jedynie uzyc metody getPairsOfPlayers(). chuj
* @param int $levels ilość poziomów w turnieju
*/
public function __construct($levels)
{
/* Ponieważ dla 16 graczy będzie 8 bitw, musimy odjąć jedną potęgę */
$this->levels = $levels;
/* Obliczamy ilość drużyn dla ktorych trzeba cos policzyc (2x mniej niz ilosc bitw) */
$this->howMuchPlayers = pow(2, $this->levels);
/* Przelicz wszystko */
$this->generatePositions();
}
/**
* Metoda zwraca tablicę podanych drużyn poukładaną specjalnym algorytmem, aby gracze na siebie nie wpadali.
* Tablica musi być wcześniej posortowana wedle rankingów malejąco.
* @param unknown_type $teams
* @return array <Team>
*/
public function getProperlyPlacedTeams($teams)
{
$result = null;
/* Dla każdego wyniku z generatora */
foreach ($this->generatorResult as $firstPlayer)
{
if ($firstPlayer)
{
if ($teams[($firstPlayer - 1)])
{
$result[] = $teams[($firstPlayer - 1)];
} else
{
$teamWalkowerValue = _team_walkower;
$result[] = $teamWalkowerValue;
}
}
}
return $result;
}
/**
* Metoda znajduje środek (górny lub dolny w zależności od tego co mówi globalny przełącznik)
* @param int $beginning indeks poczatku przetwarzanej czesci tabelki
* @param int $ending indeks konca przetwarzanej czesci tabelki
*/
private function findCenter($beginning, $ending)
{
$calculatedCenter = (int) (($ending - $beginning) / 2);
$calculatedCenter = $beginning + $calculatedCenter;
if ($this->upOrDown == UPORDOWN_DOWN)
{
$calculatedCenter++;
}
return $calculatedCenter;
}
/**
* Metoda oblicza krawedzie kolejnego poziomu
* @param unknown_type $whichPart
* @param unknown_type $allParts
*/
private function countBounds($whichPart, $allParts)
{
$result = new Bounds();
$lengthOfPart = $this->howMuchPlayers / $allParts;
$result->beginning = ($whichPart - 1) * $lengthOfPart + 1;
$result->ending = ($whichPart) * $lengthOfPart;
return $result;
}
/**
* Metoda przestawia zmienną raz parzyste raz nieparzyste
*/
private function swapUpOrDown()
{
if ($this->upOrDown == UPORDOWN_UP)
$this->upOrDown = UPORDOWN_DOWN;
else
$this->upOrDown = UPORDOWN_UP;
}
/**
* Metoda generuje pozycje dla jednego poziomu
*/
private function generatePositions()
{
$this->upOrDown = UPORDOWN_DOWN;
$this->generatorResult = null;
$this->generatorResult[] = null;
$this->generatorResult[] = 1;
$this->generatorResult[] = $this->howMuchPlayers;
if ($this->levels > 1)
{
$this->generatorResult[] = $this->findCenter(1, $this->howMuchPlayers);
$this->swapUpOrDown();
$this->generatorResult[] = $this->findCenter(1, $this->howMuchPlayers);
$this->swapUpOrDown();
}
if ($this->levels > 2)
{
for ($secondaryCounter = 1; $secondaryCounter < $this->levels - 1; $secondaryCounter++)
{
$auxAlgorithm = new TeamsPositionAlgorithm($secondaryCounter);
$queueOfCalls = $auxAlgorithm->generatorResult;
$countMax = count($queueOfCalls) - 1; for ($count = 1; $count <= $countMax; $count++)
{
$bounds = $this->countBounds($queueOfCalls[$count], $countMax, $this->howMuchPlayers);
$this->generatorResult[] = $this->findCenter($bounds->beginning, $bounds->ending,
$this->upOrDown);
$this->swapUpOrDown();
}
for ($count = $countMax; $count > 0; $count--)
{
$bounds = $this->countBounds($queueOfCalls[$count], $countMax, $this->howMuchPlayers);
$this->generatorResult[] = $this->findCenter($bounds->beginning, $bounds->ending,
$this->upOrDown);
$this->swapUpOrDown();
}
}
}
}
}
?>
aby skorzystać z algorytmu i wygenerować ciąg dla ułożenia graczy wystarczy uzyc: (liczba poziomów to ilosc rund w turnieju, czy wykładnik potęgi liczby oznaczajacej ilosc graczy: np dla 8 miu graczy jest to 3)
$teamposition=new TeamPositionAlgorithm($liczbaPoziomow);
$teamposition->generatePositions();
$result=$teamposition->generatorResult();
dla parametru wejsciowego 3 parametrem wyjsciowym będzie tablica: 1, 8, 7, 2, 6, 3, 5, 4.
teraz wystarczy tylko posortowac twoich graczy wedle rankingu, i ułożyc ich w pary tak jak tablica mówi.
jak masz pięc graczy: gracz1...gracz5 to ulozenei w pary bedzie nastepujace:
1. gracz1-z nikim
2. nikt-gracz2
3. nikt-gracz3
4. gracz4-gracz5
natomiast gdybys chcial dodac koszyk przegranych to trzeba dodać do głównego drzewka jeszcze jeden poziom na korym bedzie rozegrany mecz miedzy zwyciezca glownego turnieju i zwyciezca koszyka przegranych.
jak chcesz to moge ci gotowca sprzedac ale nie sadze bys byl zainteresowany