За последние 24 часа нас посетили 25378 программистов и 1718 роботов. Сейчас ищут 873 программиста ...

Как отсортировать данные турнирной таблицы(условия экзотичес

Тема в разделе "PHP для новичков", создана пользователем alexforce2, 25 апр 2014.

  1. alexforce2

    alexforce2 Активный пользователь

    С нами с:
    25 дек 2013
    Сообщения:
    71
    Симпатии:
    12
    Всем привет! Есть проблема, как отсортировать данные турнирной таблицы, на каком этапе сортировать, даже не знаю, или в SQL, или в PHP, надеюсь кто-нибудь подскажет как решить проблему. Есть следующий вывод данных таблицы:
    [​IMG]
    ник зеленый = выйграл, красный = проиграл, чёрный = ещё не играли.
    одна строка турнирной таблицы(юзер1 вс юзер2) = массив('юзер1', 'юзер2', 'другая информация...')
    Проблема в следующем: на скрине видно, что вывод пар оппонентов не соответствует логике. Например, первая ячейка оппонентов во втором раунде "Vayass -vs- eSFo" сформирована из двух победителей ячеек оппонентов первого раунда "Vayass -vs- tima" и "User17 -vs- eSFo", в данном случае, надо чтоб в первом раунде ячейки выводились в таком порядке "Vayass -vs- tima"; "User17 -vs- eSFo" и т.д., как это сделать? Данные хранятся в БД, где одна строка = 'юзер1', 'юзер2', 'раунд', 'другая информация...'.
     
  2. BaranPHP

    BaranPHP Новичок

    С нами с:
    24 янв 2014
    Сообщения:
    356
    Симпатии:
    0
    Re: Как отсортировать данные турнирной таблицы(условия экзот

    Бред. В БД не достаточно данных для такого вывода как ты хочешь. По уму так на каждый раунд в БД должна быть своя таблица и на участников отдельная.
     
  3. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    Re: Как отсортировать данные турнирной таблицы(условия экзот

    надо просто танцевать от последнего раунда и всё.
     
  4. BaranPHP

    BaranPHP Новичок

    С нами с:
    24 янв 2014
    Сообщения:
    356
    Симпатии:
    0
    Re: Как отсортировать данные турнирной таблицы(условия экзот

    Это называется через *опу и то только для людей с даром предвидения. В таблице нет никаких указаний на победителя соответственно пока не внесут результаты жеребьёвки(кто VS кого) просчитать не возможно. А если более грамотно организовать базу, будет всё гораздо проще и функциональние. Ведь там явно ещё и 4 раунд намечается.
     
  5. romach

    romach Старожил

    С нами с:
    26 окт 2013
    Сообщения:
    2.904
    Симпатии:
    719
    Re: Как отсортировать данные турнирной таблицы(условия экзот

    BaranPHP, а когда раундов станет больше будете n-ю таблицу лепить?
     
  6. BaranPHP

    BaranPHP Новичок

    С нами с:
    24 янв 2014
    Сообщения:
    356
    Симпатии:
    0
    Re: Как отсортировать данные турнирной таблицы(условия экзот

    Ну для меня так было бы удобнее. Но я не об этом а о том что надо менять структуру БД. С существующей структурой на мой взгляд сложно не только выводить но и вносить данные. Я конечно могу предположить что написав кучу кода со сложными условиями можно таки вывести то что надо автору при условии что в последний не существующий раунд будет вписан только один участник.
     
  7. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    Re: Как отсортировать данные турнирной таблицы(условия экзот

    ты бабушке своей на кухне хами, понял? :)
    если мы знаем победителей раундов и их последний раунд назначен - жеребьёвка прошла и пары определились, то мы можем выстроить любое дерево назад. если ты не понимаешь задачу, и не понимаешь решение, то не надо хамить. просто начни уже включать мозг.

    Добавлено спустя 2 минуты 30 секунд:
    Re: Как отсортировать данные турнирной таблицы(условия экзотичес
    структура бд тут не при чем - раз. два - о ней мы ничего не знаем. чего ты там себе напридумывал - это твоё личное дело.

    Добавлено спустя 1 минуту 36 секунд:
    Re: Как отсортировать данные турнирной таблицы(условия экзотичес
    это решение на первой же итерации скатывается к универсальному решению с двумя участниками, которое не имеет никаких ограничений на размер дерева. ты собственные мысли не понял.
     
  8. BaranPHP

    BaranPHP Новичок

    С нами с:
    24 янв 2014
    Сообщения:
    356
    Симпатии:
    0
    Re: Как отсортировать данные турнирной таблицы(условия экзот

    Я и не пытался хамить. Прощу прощения если мой ответ таковым показался. Ветка для новичков и если для тебя это не проблема охотно верю. Но посмотри на развитие событий раунд 4 остаётся последняя пара. При такой структуре БД они останутся серыми. Как ты ты их покрасишь при выводе? Как будет отмечен победитель? Ну и самое главное сложность такого запроса, как ты оцениваешь даже для себя, не говоря уже о начинающих.

    Добавлено спустя 1 минуту 43 секунды:
    Re: Как отсортировать данные турнирной таблицы(условия экзотичес
    я исхожу из того что написанно
     
  9. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    Re: Как отсортировать данные турнирной таблицы(условия экзот

    Что с тобой? =)

    ладно.

    ну пара-то есть
    дык они не сыграли ещё.
    задача стоит не в том, чтобы покрасить. они уже покрашены верно. надо просто выстроить строчки в правильном порядке. Выстраивать их надо с конца. Вот и всё. Берём пару после жеребьёвки, потом берём их предыдущий раунд, и потом предыдущие раунды всех участников и так далее.

    У него нет проблемы с покрасом. Только с правильным порядком строк.

    Добавлено спустя 1 минуту 29 секунд:
    Re: Как отсортировать данные турнирной таблицы(условия экзотичес
    Выбирать всех и в массиве на стороне пхп перебирать.
    да пофик. где-то есть данные о том, кто в каком раунде играл и победил. он же откуда-то берёт эту инфу для раскраса. так что не важно откуда и как. инфа есть и от неё можно отталкиваться.
     
  10. BaranPHP

    BaranPHP Новичок

    С нами с:
    24 янв 2014
    Сообщения:
    356
    Симпатии:
    0
    Re: Как отсортировать данные турнирной таблицы(условия экзот

    Ну вот вот. А я о чём, но по условиям задачи нам это не известно.
    Исходя из условий он красит исключительно по одной таблице:
    1) выбирает все значения "юзер1" и "юзер2" где "раунд" =3
    2) выбирает все значения "юзер1" и "юзер2" где "раунд" =2
    3) перебирает, сравнивает те что есть и в 3 и в 2 красит одним цветом, остальные другим.

    Соответственно из заданных условий точно так же можно построить вычисления порядка наследования ячеек в таблице. Но это уже такие расписные узоры, что на мой взгляд ни как не тянут на ветку для новичков. Соответственно и мой совет изменить структуру БД.
    Конечно же если структура БД не полностью описана автором то спорить тут не о чем.
     
  11. dapperkop

    dapperkop Активный пользователь

    С нами с:
    26 сен 2013
    Сообщения:
    890
    Симпатии:
    0
    Re: Как отсортировать данные турнирной таблицы(условия экзот

    Сори за оффтоп, а что за спорт?
     
  12. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    Re: Как отсортировать данные турнирной таблицы(условия экзот

    Подождём че автор скажет. И структуру покажет.
     
  13. alexforce2

    alexforce2 Активный пользователь

    С нами с:
    25 дек 2013
    Сообщения:
    71
    Симпатии:
    12
    Re: Как отсортировать данные турнирной таблицы(условия экзот

    Турнир по компьютерным играм.
    Структура БД следующая:
    id/first_opponent/second_opponent/stage/tournament/game_over(0=не играли; 1=проиграл первый оппонент; 2=проиграл второй оппонент)
    Данные из БД выбираются по tournament и сортируются по stage(в SQL запросе), вопрос не стоит как окрашивать данные, как их туда заносить, а как отсортировать, чтобы таблица визуально выглядела правильной, если кто-то предложит другую структуру данных - буду рад почитать разные мнения.
    Сейчас таблица выводится в цикле(сначала 1 раунд, потом 2 раунд и т.д.)
    Как сказал igordata, мне тоже кажется, надо плясать с последнего раунда, но как это реализовать - не представляю. Количество участников неизвестно, но всегда равно (2 в степени n) (n=целое число). Вообще igordata правильно понял мысль заданного вопроса, может вы подскажите, как отсортировать эти данные?
    Код (Text):
    1.  
    2. array (
    3.           0 => array ( 'stage' => '1', 'first_opponent' => 'Vayass', 'second_opponent' => 'tima'),
    4.           1 => array ( 'stage' => '1', 'first_opponent' => 'F_B*', 'second_opponent' => 'User16'),
    5.           2 => array ( 'stage' => '1', 'first_opponent' => 'User17 ', 'second_opponent' => 'eSFo'),
    6.           3 => array ( 'stage' => '1', 'first_opponent' => 'User19 ', 'second_opponent' => 'User20'),
    7.           4 => array ( 'stage' => '1', 'first_opponent' => 'User21 ', 'second_opponent' => 'Iv'),
    8.           5 => array ( 'stage' => '1', 'first_opponent' => 'User23 ', 'second_opponent' => 'User24'),
    9.           6 => array ( 'stage' => '1', 'first_opponent' => 'Marius', 'second_opponent' => 'NaZZg001'),
    10.           7 => array ( 'stage' => '1', 'first_opponent' => 'User28 ', 'second_opponent' => 'User29'),
    11.           8 => array ( 'stage' => '2', 'first_opponent' => 'Vayass', 'second_opponent' => 'eSFo'),
    12.           9 => array ( 'stage' => '2', 'first_opponent' => 'F_B*', 'second_opponent' => 'User29'),
    13.           10 => array ( 'stage' => '2', 'first_opponent' => 'User20 ', 'second_opponent' => 'User24'),
    14.           11 => array ( 'stage' => '2', 'first_opponent' => 'Iv', 'second_opponent' => 'Marius'),
    15.           12 => array ( 'stage' => '3', 'first_opponent' => 'Vayass', 'second_opponent' => 'User20'),
    16.           13 => array ( 'stage' => '3', 'first_opponent' => 'User29', 'second_opponent' => 'Iv')
    17.       )
     
  14. BaranPHP

    BaranPHP Новичок

    С нами с:
    24 янв 2014
    Сообщения:
    356
    Симпатии:
    0
    Re: Как отсортировать данные турнирной таблицы(условия экзот

    Да что бы их отсортировать надо:
    1) привязать `id` где `stage`='$n' к `id` где `stage`='$n-1'

    `stage`=1
    бой №1: (User_1 VS User_2)
    бой №2: (User_3 VS User_4)
    бой №3: (User_5 VS User_6)
    бой №4: (User_7 VS User_8)

    `stage`=2
    бой №5: (бой №1 VS бой №4)
    бой №6: (бой №3 VS бой №2)

    `stage`=3
    бой №7: (бой №5 VS бой №6)

    Уж решай сам либо возится с проверкой имён юзеров, либо просто ввести в таблицу дополнительные поля `first_opponent_first_fight_id` и `second_opponent_first_fight_id`.

    2)долго-долго через кучу условий создать многомерный массив с видом
    Код (Text):
    1. Array
    2. (
    3.     [$id] => Array (бой №5 VS бой №6)
    4.         (
    5.             [$id] => Array (бой №3 VS бой №2)
    6.                 (
    7.                     (
    8.                     [$id] =>Array (User_5 VS User_6)
    9.                 (
    10.                     [$id] => (User_5)
    11.                     [$id] => (User_6)
    12.                 )
    13.                     [$id] =>Array (User_3 VS User_4)
    14.                 (
    15.                     [$id] => (User_3)
    16.                     [$id] => (User_4)
    17.                 )
    18.                 )
    19.             [$id] => Array (бой №1 VS бой №4)
    20.                 (
    21.                     [$id] =>Array (User_1 VS User_2)
    22.                 (
    23.                     [$id] => (User_1)
    24.                     [$id] => (User_2)
    25.                 )
    26.                     [$id] =>Array (User_7 VS User_8)
    27.                 (
    28.                     [$id] => (User_7)
    29.                     [$id] => (User_8)
    30.                 )
    31.                 )
    32. )
    Уж простите за скобки и структуру но думаю идея понятна.


    Но всё это будет работать пока количество участников равно 2 в степени равной количеству раундов.
    Скажем при условии что начальное количество участников равно ну пусть будет 12 по получается збой. Наверно и тут корифеи придумают хитрые формулы, но всё это настолько сложно. что простой вывод данных того не стоит.

    Я бы призадумался над структурой БД больше ячеек и таблиц, больше возможностей для настройки вывода и ввода информации.
     
  15. Chushkin

    Chushkin Активный пользователь

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    Re: Как отсортировать данные турнирной таблицы(условия экзот

    Насколько я понял задачу...
    Запись уникальна по: Раунд, Игрок, Противник.
    1) Если число раундов ограничено, используйте LEFT JOIN по связи "Игрок, Противник"
    2) Если не хотите ограничивать число раундов, тогда типичное дерево, где Раунд это уровень. Дерево надо строить перед выводом.
    К сожалению на mySQL нет рекурсивного запроса, поэтому проще на клиенте, с использованием массива.
    Что-то вроде:
    Код (Text):
    1. $array[Раунд]["Игрок, Противник"]
    Далее foreach() + isset() при построении таблицы.
     
  16. dapperkop

    dapperkop Активный пользователь

    С нами с:
    26 сен 2013
    Сообщения:
    890
    Симпатии:
    0
    Re: Как отсортировать данные турнирной таблицы(условия экзот

    Хм... Интересная задачка... Только боюсь сортировкой тут и не пахнет.

    Тут нужно вывести что-то типа такой иерархии:

    [​IMG]

    Но есть много нюансов, которые нужно решать помимо вывода данных, например, как такое дерево будет заполняться + что делать с другими системами проведения турниров (есь жи full double elimination или Play-off), а также как выводить данные, если в финалах учавствует 16 комманд (если такое, конечно, возможно)? Вот пример из 8 комманд: http://dota2.starladder.tv/news/4849. Как мы видим - дерево не такое уж и маленькое...

    Добавлено спустя 2 минуты 50 секунд:
    Re: Как отсортировать данные турнирной таблицы(условия экзотичес
    Как по мне, то сначала нужно разработать механизм создания турнира, дальше глядишь и на вывод информации светлые идеи придут...

    Добавлено спустя 39 минут 27 секунд:
    Re: Как отсортировать данные турнирной таблицы(условия экзотичес
    + помимо всего прочего существуют встречи команд по типу best of 1, best of 2, best of 3, best of 5. bo1, bo3 и bo5 - эти типы применимы к плей оф и фул дабл эл., но вот бо2 применимы к сводной таблице - это типа как в футболе (выиграл игру - получил очко, выиграл еще одну - получил два очка), ну и т. д.
     
  17. Ke1eth

    Ke1eth Активный пользователь

    С нами с:
    16 мар 2012
    Сообщения:
    1.073
    Симпатии:
    11
    Адрес:
    заблудилса
    Re: Как отсортировать данные турнирной таблицы(условия экзот

    Еси чо, вот правила от сноуборда (посмотрел, как для них я городил таблицу по международным правилам, для чемпионата России).
    Полу финал:
    1 , 4
    2 , 3

    1/4:
    1, 8
    4, 5
    3, 6
    2, 7

    1/8:
    1, 16
    8, 9
    5, 12
    4, 13
    3, 14
    6, 11
    7, 10
    2, 15

    т.е. первый всегда с последним, второй с прдпоследним и т.д.
     
  18. sobachnik

    sobachnik Старожил

    С нами с:
    20 апр 2007
    Сообщения:
    3.380
    Симпатии:
    13
    Адрес:
    Дмитров, МО
    Стало интересно попробовать решить эту задачу. Получилось такое решение, если я правильно понял условие:

    Код (PHP):
    1. <?php
    2. $data = array(
    3.     0 => array('stage' => '1', 'first_opponent' => 'Vayass', 'second_opponent' => 'tima', 'game_over' => '2'),
    4.     1 => array('stage' => '1', 'first_opponent' => 'F_B*', 'second_opponent' => 'User16', 'game_over' => '2'),
    5.     2 => array('stage' => '1', 'first_opponent' => 'User17', 'second_opponent' => 'eSFo', 'game_over' => '1'),
    6.     3 => array('stage' => '1', 'first_opponent' => 'User19', 'second_opponent' => 'User20', 'game_over' => '1'),
    7.     4 => array('stage' => '1', 'first_opponent' => 'User21', 'second_opponent' => 'Iv', 'game_over' => '1'),
    8.     5 => array('stage' => '1', 'first_opponent' => 'User23', 'second_opponent' => 'User24', 'game_over' => '1'),
    9.     6 => array('stage' => '1', 'first_opponent' => 'Marius', 'second_opponent' => 'NaZZg001', 'game_over' => '2'),
    10.     7 => array('stage' => '1', 'first_opponent' => 'User28', 'second_opponent' => 'User29', 'game_over' => '1'),
    11.     8 => array('stage' => '2', 'first_opponent' => 'Vayass', 'second_opponent' => 'eSFo', 'game_over' => '2'),
    12.     9 => array('stage' => '2', 'first_opponent' => 'F_B*', 'second_opponent' => 'User29', 'game_over' => '1'),
    13.     10 => array('stage' => '2', 'first_opponent' => 'User20', 'second_opponent' => 'User24', 'game_over' => '2'),
    14.     11 => array('stage' => '2', 'first_opponent' => 'Iv', 'second_opponent' => 'Marius', 'game_over' => '2'),
    15.     12 => array('stage' => '3', 'first_opponent' => 'Vayass', 'second_opponent' => 'User20', 'game_over' => '0'),
    16.     13 => array('stage' => '3', 'first_opponent' => 'User29', 'second_opponent' => 'Iv', 'game_over' => '0')
    17. );
    18. $win = array(1 => 'second_opponent', 2 => 'first_opponent');
    19. $winColor = '008F00';
    20. $lossColor = 'BF0000';
    21. $drawColor = '000000';
    22. $colors = array(
    23.     0 => array('first' => $drawColor, 'second' => $drawColor),
    24.     1 => array('first' => $lossColor, 'second' => $winColor),
    25.     2 => array('first' => $winColor, 'second' => $lossColor)
    26. );
    27.  
    28. function walkdesc($stage, $members = false, $html = array()) {
    29.     global $data, $win, $colors;
    30.     foreach($data as $key => $row) {
    31.         if($row['stage'] == $stage and ($members === false or in_array($row[$win[$row['game_over']]], $members))) {
    32.             unset($data[$key]);   // Сократим лишние итерации
    33.             $rowspan = $stage > 1 ? (' rowspan="' . pow(2, $stage - 1) . '"') : '';
    34.             $first = "<span style=\"color: #{$colors[$row['game_over']]['first']};\">{$row['first_opponent']}</span>";
    35.             $second = "<span style=\"color: #{$colors[$row['game_over']]['second']};\">{$row['second_opponent']}</span>";
    36.             $html[] = "<td{$rowspan}>{$first} -VS- {$second}</td>";
    37.             if($stage > 1) {
    38.                 walkdesc($stage - 1, array($row['first_opponent'], $row['second_opponent']), $html);
    39.             } else {
    40.                 echo '<tr>' . implode('', array_reverse($html)) . '</tr>';
    41.                 if(count($html) === 1) {
    42.                     return;   // Сократим лишние итерации
    43.                 }
    44.             }
    45.             $html = array();
    46.         }
    47.     }
    48. }
    49.  
    50. $stages = 3;
    51. echo '<table border="1"><tr>';
    52. for($i = 1; $i <= $stages; ++$i) {
    53.     echo "<th>Раунд {$i}</th>";
    54. }
    55. echo '</tr>';
    56. walkdesc($stages);
    57. echo '</table>';
    58. ?>
     
  19. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    Re: Как отсортировать данные турнирной таблицы(условия экзот

    ты всё еще сидишь на старом пхп? =)
     
  20. sobachnik

    sobachnik Старожил

    С нами с:
    20 апр 2007
    Сообщения:
    3.380
    Симпатии:
    13
    Адрес:
    Дмитров, МО
    Re: Как отсортировать данные турнирной таблицы(условия экзот

    Это ты про использование global вместо того, чтобы создать объект с нужными свойствами? Ну, привычка, наверно... :) Да и меньше букв.

    Если бы писал этот код для какого-то работающего движка, толком не зная, что там есть и какие переменные объявлены уже где-то в коде - сделал бы объект, наверно.
     
  21. BaranPHP

    BaranPHP Новичок

    С нами с:
    24 янв 2014
    Сообщения:
    356
    Симпатии:
    0
    Re: Как отсортировать данные турнирной таблицы(условия экзот

    Ну уважаемый Вы просто монстр.
    Жаль только всё рушится если убрать из массива третий раунд или добавить четвёртый.
     
  22. sobachnik

    sobachnik Старожил

    С нами с:
    20 апр 2007
    Сообщения:
    3.380
    Симпатии:
    13
    Адрес:
    Дмитров, МО
    Re: Как отсортировать данные турнирной таблицы(условия экзот

    Проверял - вроде работало.
    Там переменную $stages - менял при добавлении/убирании раундов? Она в нижней части кода. Если добавляешь раунд - то $stages = 4 напиши. Убираешь - соответственно, $stages = 2.
    В принципе, можно пройтись циклом по массиву, определить максимальный stage и присвоить эту циферку переменной $stages
     
  23. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    Re: Как отсортировать данные турнирной таблицы(условия экзот

    Не, про массивы.
     
  24. sobachnik

    sobachnik Старожил

    С нами с:
    20 апр 2007
    Сообщения:
    3.380
    Симпатии:
    13
    Адрес:
    Дмитров, МО
    Re: Как отсортировать данные турнирной таблицы(условия экзот

    Хм... А что в новом php что-то другое теперь вместо массивов? Что-то не догоняю, что не так с массивами :D

    Добавлено спустя 1 минуту 39 секунд:
    Re: Как отсортировать данные турнирной таблицы(условия экзотичес
    А, кажется понял. Ты про то, что их можно было в виде json написать, видимо. Ну это тоже привычка.
     
  25. BaranPHP

    BaranPHP Новичок

    С нами с:
    24 янв 2014
    Сообщения:
    356
    Симпатии:
    0
    Да всё верно с 2 работает. Не заметил переменную. А вот с 4 отказывается.
    Но всё равно круто.
    Код (PHP):
    1.  <?php
    2.     $data = array(
    3.         7 => array('stage' => '1', 'first_opponent' => 'User28', 'second_opponent' => 'User29', 'game_over' => '1'),
    4.         5 => array('stage' => '1', 'first_opponent' => 'User23', 'second_opponent' => 'User24', 'game_over' => '1'),
    5.         0 => array('stage' => '1', 'first_opponent' => 'Vayass', 'second_opponent' => 'tima', 'game_over' => '2'),
    6.         1 => array('stage' => '1', 'first_opponent' => 'F_B*', 'second_opponent' => 'User16', 'game_over' => '2'),
    7.         2 => array('stage' => '1', 'first_opponent' => 'User17', 'second_opponent' => 'eSFo', 'game_over' => '1'),
    8.         3 => array('stage' => '1', 'first_opponent' => 'User19', 'second_opponent' => 'User20', 'game_over' => '1'),
    9.         4 => array('stage' => '1', 'first_opponent' => 'User21', 'second_opponent' => 'Iv', 'game_over' => '1'),
    10.         6 => array('stage' => '1', 'first_opponent' => 'Marius', 'second_opponent' => 'NaZZg001', 'game_over' => '2'),
    11.         8 => array('stage' => '2', 'first_opponent' => 'Vayass', 'second_opponent' => 'eSFo', 'game_over' => '2'),
    12.         9 => array('stage' => '2', 'first_opponent' => 'F_B*', 'second_opponent' => 'User29', 'game_over' => '1'),
    13.         10 => array('stage' => '2', 'first_opponent' => 'User20', 'second_opponent' => 'User24', 'game_over' => '2'),
    14.         11 => array('stage' => '2', 'first_opponent' => 'Iv', 'second_opponent' => 'Marius', 'game_over' => '2'),
    15.         12 => array('stage' => '3', 'first_opponent' => 'Vayass', 'second_opponent' => 'User20', 'game_over' => '1'),
    16.         13 => array('stage' => '3', 'first_opponent' => 'User29', 'second_opponent' => 'Iv', 'game_over' => '2'),
    17.         14 => array('stage' => '4', 'first_opponent' => 'Vayass', 'second_opponent' => 'Iv', 'game_over' => '0')
    18.     );
    19.     $win = array(1 => 'second_opponent', 2 => 'first_opponent');
    20.     $winColor = '008F00';
    21.     $lossColor = 'BF0000';
    22.     $drawColor = '000000';
    23.     $colors = array(
    24.         0 => array('first' => $drawColor, 'second' => $drawColor),
    25.         1 => array('first' => $lossColor, 'second' => $winColor),
    26.         2 => array('first' => $winColor, 'second' => $lossColor)
    27.     );
    28.  
    29.     function walkdesc($stage, $members = false, $html = array()) {
    30.         global $data, $win, $colors;
    31.         foreach($data as $key => $row) {
    32.             if($row['stage'] == $stage and ($members === false or in_array($row[$win[$row['game_over']]], $members))) {
    33.                 unset($data[$key]);   // Сократим лишние итерации
    34.                 $rowspan = $stage > 1 ? (' rowspan="' . pow(2, $stage - 1) . '"') : '';
    35.                 $first = "<span style=\"color: #{$colors[$row['game_over']]['first']};\">{$row['first_opponent']}</span>";
    36.                 $second = "<span style=\"color: #{$colors[$row['game_over']]['second']};\">{$row['second_opponent']}</span>";
    37.                 $html[] = "<td{$rowspan}>{$first} -VS- {$second}</td>";
    38.                 if($stage > 1) {
    39.                     walkdesc($stage - 1, array($row['first_opponent'], $row['second_opponent']), $html);
    40.                 } else {
    41.                     echo '<tr>' . implode('', array_reverse($html)) . '</tr>';
    42.                     if(count($html) === 1) {
    43.                         return;   // Сократим лишние итерации
    44.                     }
    45.                 }
    46.                 $html = array();
    47.             }
    48.         }
    49.     }
    50.  
    51.     $stages = 4;
    52.     echo '<table border="1"><tr>';
    53.     for($i = 1; $i <= $stages; ++$i) {
    54.         echo "<th>Раунд {$i}</th>";
    55.     }
    56.     echo '</tr>';
    57.     walkdesc($stages);
    58.     echo '</table>';
    59.     ?>