Всем привет! Есть проблема, как отсортировать данные турнирной таблицы, на каком этапе сортировать, даже не знаю, или в SQL, или в PHP, надеюсь кто-нибудь подскажет как решить проблему. Есть следующий вывод данных таблицы: ник зеленый = выйграл, красный = проиграл, чёрный = ещё не играли. одна строка турнирной таблицы(юзер1 вс юзер2) = массив('юзер1', 'юзер2', 'другая информация...') Проблема в следующем: на скрине видно, что вывод пар оппонентов не соответствует логике. Например, первая ячейка оппонентов во втором раунде "Vayass -vs- eSFo" сформирована из двух победителей ячеек оппонентов первого раунда "Vayass -vs- tima" и "User17 -vs- eSFo", в данном случае, надо чтоб в первом раунде ячейки выводились в таком порядке "Vayass -vs- tima"; "User17 -vs- eSFo" и т.д., как это сделать? Данные хранятся в БД, где одна строка = 'юзер1', 'юзер2', 'раунд', 'другая информация...'.
Re: Как отсортировать данные турнирной таблицы(условия экзот Бред. В БД не достаточно данных для такого вывода как ты хочешь. По уму так на каждый раунд в БД должна быть своя таблица и на участников отдельная.
Re: Как отсортировать данные турнирной таблицы(условия экзот надо просто танцевать от последнего раунда и всё.
Re: Как отсортировать данные турнирной таблицы(условия экзот Это называется через *опу и то только для людей с даром предвидения. В таблице нет никаких указаний на победителя соответственно пока не внесут результаты жеребьёвки(кто VS кого) просчитать не возможно. А если более грамотно организовать базу, будет всё гораздо проще и функциональние. Ведь там явно ещё и 4 раунд намечается.
Re: Как отсортировать данные турнирной таблицы(условия экзот BaranPHP, а когда раундов станет больше будете n-ю таблицу лепить?
Re: Как отсортировать данные турнирной таблицы(условия экзот Ну для меня так было бы удобнее. Но я не об этом а о том что надо менять структуру БД. С существующей структурой на мой взгляд сложно не только выводить но и вносить данные. Я конечно могу предположить что написав кучу кода со сложными условиями можно таки вывести то что надо автору при условии что в последний не существующий раунд будет вписан только один участник.
Re: Как отсортировать данные турнирной таблицы(условия экзот ты бабушке своей на кухне хами, понял? если мы знаем победителей раундов и их последний раунд назначен - жеребьёвка прошла и пары определились, то мы можем выстроить любое дерево назад. если ты не понимаешь задачу, и не понимаешь решение, то не надо хамить. просто начни уже включать мозг. Добавлено спустя 2 минуты 30 секунд: Re: Как отсортировать данные турнирной таблицы(условия экзотичес структура бд тут не при чем - раз. два - о ней мы ничего не знаем. чего ты там себе напридумывал - это твоё личное дело. Добавлено спустя 1 минуту 36 секунд: Re: Как отсортировать данные турнирной таблицы(условия экзотичес это решение на первой же итерации скатывается к универсальному решению с двумя участниками, которое не имеет никаких ограничений на размер дерева. ты собственные мысли не понял.
Re: Как отсортировать данные турнирной таблицы(условия экзот Я и не пытался хамить. Прощу прощения если мой ответ таковым показался. Ветка для новичков и если для тебя это не проблема охотно верю. Но посмотри на развитие событий раунд 4 остаётся последняя пара. При такой структуре БД они останутся серыми. Как ты ты их покрасишь при выводе? Как будет отмечен победитель? Ну и самое главное сложность такого запроса, как ты оцениваешь даже для себя, не говоря уже о начинающих. Добавлено спустя 1 минуту 43 секунды: Re: Как отсортировать данные турнирной таблицы(условия экзотичес я исхожу из того что написанно
Re: Как отсортировать данные турнирной таблицы(условия экзот Что с тобой? =) ладно. ну пара-то есть дык они не сыграли ещё. задача стоит не в том, чтобы покрасить. они уже покрашены верно. надо просто выстроить строчки в правильном порядке. Выстраивать их надо с конца. Вот и всё. Берём пару после жеребьёвки, потом берём их предыдущий раунд, и потом предыдущие раунды всех участников и так далее. У него нет проблемы с покрасом. Только с правильным порядком строк. Добавлено спустя 1 минуту 29 секунд: Re: Как отсортировать данные турнирной таблицы(условия экзотичес Выбирать всех и в массиве на стороне пхп перебирать. да пофик. где-то есть данные о том, кто в каком раунде играл и победил. он же откуда-то берёт эту инфу для раскраса. так что не важно откуда и как. инфа есть и от неё можно отталкиваться.
Re: Как отсортировать данные турнирной таблицы(условия экзот Ну вот вот. А я о чём, но по условиям задачи нам это не известно. Исходя из условий он красит исключительно по одной таблице: 1) выбирает все значения "юзер1" и "юзер2" где "раунд" =3 2) выбирает все значения "юзер1" и "юзер2" где "раунд" =2 3) перебирает, сравнивает те что есть и в 3 и в 2 красит одним цветом, остальные другим. Соответственно из заданных условий точно так же можно построить вычисления порядка наследования ячеек в таблице. Но это уже такие расписные узоры, что на мой взгляд ни как не тянут на ветку для новичков. Соответственно и мой совет изменить структуру БД. Конечно же если структура БД не полностью описана автором то спорить тут не о чем.
Re: Как отсортировать данные турнирной таблицы(условия экзот Подождём че автор скажет. И структуру покажет.
Re: Как отсортировать данные турнирной таблицы(условия экзот Турнир по компьютерным играм. Структура БД следующая: id/first_opponent/second_opponent/stage/tournament/game_over(0=не играли; 1=проиграл первый оппонент; 2=проиграл второй оппонент) Данные из БД выбираются по tournament и сортируются по stage(в SQL запросе), вопрос не стоит как окрашивать данные, как их туда заносить, а как отсортировать, чтобы таблица визуально выглядела правильной, если кто-то предложит другую структуру данных - буду рад почитать разные мнения. Сейчас таблица выводится в цикле(сначала 1 раунд, потом 2 раунд и т.д.) Как сказал igordata, мне тоже кажется, надо плясать с последнего раунда, но как это реализовать - не представляю. Количество участников неизвестно, но всегда равно (2 в степени n) (n=целое число). Вообще igordata правильно понял мысль заданного вопроса, может вы подскажите, как отсортировать эти данные? Код (Text): array ( 0 => array ( 'stage' => '1', 'first_opponent' => 'Vayass', 'second_opponent' => 'tima'), 1 => array ( 'stage' => '1', 'first_opponent' => 'F_B*', 'second_opponent' => 'User16'), 2 => array ( 'stage' => '1', 'first_opponent' => 'User17 ', 'second_opponent' => 'eSFo'), 3 => array ( 'stage' => '1', 'first_opponent' => 'User19 ', 'second_opponent' => 'User20'), 4 => array ( 'stage' => '1', 'first_opponent' => 'User21 ', 'second_opponent' => 'Iv'), 5 => array ( 'stage' => '1', 'first_opponent' => 'User23 ', 'second_opponent' => 'User24'), 6 => array ( 'stage' => '1', 'first_opponent' => 'Marius', 'second_opponent' => 'NaZZg001'), 7 => array ( 'stage' => '1', 'first_opponent' => 'User28 ', 'second_opponent' => 'User29'), 8 => array ( 'stage' => '2', 'first_opponent' => 'Vayass', 'second_opponent' => 'eSFo'), 9 => array ( 'stage' => '2', 'first_opponent' => 'F_B*', 'second_opponent' => 'User29'), 10 => array ( 'stage' => '2', 'first_opponent' => 'User20 ', 'second_opponent' => 'User24'), 11 => array ( 'stage' => '2', 'first_opponent' => 'Iv', 'second_opponent' => 'Marius'), 12 => array ( 'stage' => '3', 'first_opponent' => 'Vayass', 'second_opponent' => 'User20'), 13 => array ( 'stage' => '3', 'first_opponent' => 'User29', 'second_opponent' => 'Iv') )
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): Array ( [$id] => Array (бой №5 VS бой №6) ( [$id] => Array (бой №3 VS бой №2) ( ( [$id] =>Array (User_5 VS User_6) ( [$id] => (User_5) [$id] => (User_6) ) [$id] =>Array (User_3 VS User_4) ( [$id] => (User_3) [$id] => (User_4) ) ) [$id] => Array (бой №1 VS бой №4) ( [$id] =>Array (User_1 VS User_2) ( [$id] => (User_1) [$id] => (User_2) ) [$id] =>Array (User_7 VS User_8) ( [$id] => (User_7) [$id] => (User_8) ) ) ) Уж простите за скобки и структуру но думаю идея понятна. Но всё это будет работать пока количество участников равно 2 в степени равной количеству раундов. Скажем при условии что начальное количество участников равно ну пусть будет 12 по получается збой. Наверно и тут корифеи придумают хитрые формулы, но всё это настолько сложно. что простой вывод данных того не стоит. Я бы призадумался над структурой БД больше ячеек и таблиц, больше возможностей для настройки вывода и ввода информации.
Re: Как отсортировать данные турнирной таблицы(условия экзот Насколько я понял задачу... Запись уникальна по: Раунд, Игрок, Противник. 1) Если число раундов ограничено, используйте LEFT JOIN по связи "Игрок, Противник" 2) Если не хотите ограничивать число раундов, тогда типичное дерево, где Раунд это уровень. Дерево надо строить перед выводом. К сожалению на mySQL нет рекурсивного запроса, поэтому проще на клиенте, с использованием массива. Что-то вроде: Код (Text): $array[Раунд]["Игрок, Противник"] Далее foreach() + isset() при построении таблицы.
Re: Как отсортировать данные турнирной таблицы(условия экзот Хм... Интересная задачка... Только боюсь сортировкой тут и не пахнет. Тут нужно вывести что-то типа такой иерархии: Но есть много нюансов, которые нужно решать помимо вывода данных, например, как такое дерево будет заполняться + что делать с другими системами проведения турниров (есь жи 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 применимы к сводной таблице - это типа как в футболе (выиграл игру - получил очко, выиграл еще одну - получил два очка), ну и т. д.
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 т.е. первый всегда с последним, второй с прдпоследним и т.д.
Стало интересно попробовать решить эту задачу. Получилось такое решение, если я правильно понял условие: Код (PHP): <?php $data = array( 0 => array('stage' => '1', 'first_opponent' => 'Vayass', 'second_opponent' => 'tima', 'game_over' => '2'), 1 => array('stage' => '1', 'first_opponent' => 'F_B*', 'second_opponent' => 'User16', 'game_over' => '2'), 2 => array('stage' => '1', 'first_opponent' => 'User17', 'second_opponent' => 'eSFo', 'game_over' => '1'), 3 => array('stage' => '1', 'first_opponent' => 'User19', 'second_opponent' => 'User20', 'game_over' => '1'), 4 => array('stage' => '1', 'first_opponent' => 'User21', 'second_opponent' => 'Iv', 'game_over' => '1'), 5 => array('stage' => '1', 'first_opponent' => 'User23', 'second_opponent' => 'User24', 'game_over' => '1'), 6 => array('stage' => '1', 'first_opponent' => 'Marius', 'second_opponent' => 'NaZZg001', 'game_over' => '2'), 7 => array('stage' => '1', 'first_opponent' => 'User28', 'second_opponent' => 'User29', 'game_over' => '1'), 8 => array('stage' => '2', 'first_opponent' => 'Vayass', 'second_opponent' => 'eSFo', 'game_over' => '2'), 9 => array('stage' => '2', 'first_opponent' => 'F_B*', 'second_opponent' => 'User29', 'game_over' => '1'), 10 => array('stage' => '2', 'first_opponent' => 'User20', 'second_opponent' => 'User24', 'game_over' => '2'), 11 => array('stage' => '2', 'first_opponent' => 'Iv', 'second_opponent' => 'Marius', 'game_over' => '2'), 12 => array('stage' => '3', 'first_opponent' => 'Vayass', 'second_opponent' => 'User20', 'game_over' => '0'), 13 => array('stage' => '3', 'first_opponent' => 'User29', 'second_opponent' => 'Iv', 'game_over' => '0') ); $win = array(1 => 'second_opponent', 2 => 'first_opponent'); $winColor = '008F00'; $lossColor = 'BF0000'; $drawColor = '000000'; $colors = array( 0 => array('first' => $drawColor, 'second' => $drawColor), 1 => array('first' => $lossColor, 'second' => $winColor), 2 => array('first' => $winColor, 'second' => $lossColor) ); function walkdesc($stage, $members = false, $html = array()) { global $data, $win, $colors; foreach($data as $key => $row) { if($row['stage'] == $stage and ($members === false or in_array($row[$win[$row['game_over']]], $members))) { unset($data[$key]); // Сократим лишние итерации $rowspan = $stage > 1 ? (' rowspan="' . pow(2, $stage - 1) . '"') : ''; $first = "<span style=\"color: #{$colors[$row['game_over']]['first']};\">{$row['first_opponent']}</span>"; $second = "<span style=\"color: #{$colors[$row['game_over']]['second']};\">{$row['second_opponent']}</span>"; $html[] = "<td{$rowspan}>{$first} -VS- {$second}</td>"; if($stage > 1) { walkdesc($stage - 1, array($row['first_opponent'], $row['second_opponent']), $html); } else { echo '<tr>' . implode('', array_reverse($html)) . '</tr>'; if(count($html) === 1) { return; // Сократим лишние итерации } } $html = array(); } } } $stages = 3; echo '<table border="1"><tr>'; for($i = 1; $i <= $stages; ++$i) { echo "<th>Раунд {$i}</th>"; } echo '</tr>'; walkdesc($stages); echo '</table>'; ?>
Re: Как отсортировать данные турнирной таблицы(условия экзот Это ты про использование global вместо того, чтобы создать объект с нужными свойствами? Ну, привычка, наверно... Да и меньше букв. Если бы писал этот код для какого-то работающего движка, толком не зная, что там есть и какие переменные объявлены уже где-то в коде - сделал бы объект, наверно.
Re: Как отсортировать данные турнирной таблицы(условия экзот Ну уважаемый Вы просто монстр. Жаль только всё рушится если убрать из массива третий раунд или добавить четвёртый.
Re: Как отсортировать данные турнирной таблицы(условия экзот Проверял - вроде работало. Там переменную $stages - менял при добавлении/убирании раундов? Она в нижней части кода. Если добавляешь раунд - то $stages = 4 напиши. Убираешь - соответственно, $stages = 2. В принципе, можно пройтись циклом по массиву, определить максимальный stage и присвоить эту циферку переменной $stages
Re: Как отсортировать данные турнирной таблицы(условия экзот Хм... А что в новом php что-то другое теперь вместо массивов? Что-то не догоняю, что не так с массивами Добавлено спустя 1 минуту 39 секунд: Re: Как отсортировать данные турнирной таблицы(условия экзотичес А, кажется понял. Ты про то, что их можно было в виде json написать, видимо. Ну это тоже привычка.
Да всё верно с 2 работает. Не заметил переменную. А вот с 4 отказывается. Но всё равно круто. Код (PHP): <?php $data = array( 7 => array('stage' => '1', 'first_opponent' => 'User28', 'second_opponent' => 'User29', 'game_over' => '1'), 5 => array('stage' => '1', 'first_opponent' => 'User23', 'second_opponent' => 'User24', 'game_over' => '1'), 0 => array('stage' => '1', 'first_opponent' => 'Vayass', 'second_opponent' => 'tima', 'game_over' => '2'), 1 => array('stage' => '1', 'first_opponent' => 'F_B*', 'second_opponent' => 'User16', 'game_over' => '2'), 2 => array('stage' => '1', 'first_opponent' => 'User17', 'second_opponent' => 'eSFo', 'game_over' => '1'), 3 => array('stage' => '1', 'first_opponent' => 'User19', 'second_opponent' => 'User20', 'game_over' => '1'), 4 => array('stage' => '1', 'first_opponent' => 'User21', 'second_opponent' => 'Iv', 'game_over' => '1'), 6 => array('stage' => '1', 'first_opponent' => 'Marius', 'second_opponent' => 'NaZZg001', 'game_over' => '2'), 8 => array('stage' => '2', 'first_opponent' => 'Vayass', 'second_opponent' => 'eSFo', 'game_over' => '2'), 9 => array('stage' => '2', 'first_opponent' => 'F_B*', 'second_opponent' => 'User29', 'game_over' => '1'), 10 => array('stage' => '2', 'first_opponent' => 'User20', 'second_opponent' => 'User24', 'game_over' => '2'), 11 => array('stage' => '2', 'first_opponent' => 'Iv', 'second_opponent' => 'Marius', 'game_over' => '2'), 12 => array('stage' => '3', 'first_opponent' => 'Vayass', 'second_opponent' => 'User20', 'game_over' => '1'), 13 => array('stage' => '3', 'first_opponent' => 'User29', 'second_opponent' => 'Iv', 'game_over' => '2'), 14 => array('stage' => '4', 'first_opponent' => 'Vayass', 'second_opponent' => 'Iv', 'game_over' => '0') ); $win = array(1 => 'second_opponent', 2 => 'first_opponent'); $winColor = '008F00'; $lossColor = 'BF0000'; $drawColor = '000000'; $colors = array( 0 => array('first' => $drawColor, 'second' => $drawColor), 1 => array('first' => $lossColor, 'second' => $winColor), 2 => array('first' => $winColor, 'second' => $lossColor) ); function walkdesc($stage, $members = false, $html = array()) { global $data, $win, $colors; foreach($data as $key => $row) { if($row['stage'] == $stage and ($members === false or in_array($row[$win[$row['game_over']]], $members))) { unset($data[$key]); // Сократим лишние итерации $rowspan = $stage > 1 ? (' rowspan="' . pow(2, $stage - 1) . '"') : ''; $first = "<span style=\"color: #{$colors[$row['game_over']]['first']};\">{$row['first_opponent']}</span>"; $second = "<span style=\"color: #{$colors[$row['game_over']]['second']};\">{$row['second_opponent']}</span>"; $html[] = "<td{$rowspan}>{$first} -VS- {$second}</td>"; if($stage > 1) { walkdesc($stage - 1, array($row['first_opponent'], $row['second_opponent']), $html); } else { echo '<tr>' . implode('', array_reverse($html)) . '</tr>'; if(count($html) === 1) { return; // Сократим лишние итерации } } $html = array(); } } } $stages = 4; echo '<table border="1"><tr>'; for($i = 1; $i <= $stages; ++$i) { echo "<th>Раунд {$i}</th>"; } echo '</tr>'; walkdesc($stages); echo '</table>'; ?>