За последние 24 часа нас посетили 16723 программиста и 1643 робота. Сейчас ищут 995 программистов ...

генерация турнирной сетки

Тема в разделе "PHP для новичков", создана пользователем ridvik, 10 янв 2015.

  1. ridvik

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

    С нами с:
    7 июл 2012
    Сообщения:
    64
    Симпатии:
    0
    Добрый день уважаемые пользователи данного портала. Пишу вам с просьбой помочь мне доделать алгоритм распределения матчей и генерации данной сетки. Суть проблемы: если при регистрации турнира указать максимум 16 команд и в процессе регистрации на турнир зарегистрируются 16 команд, то всё норм, а если хотя бы на одну команду меньше, то вот здесь уже начинается проблемос. Вот как должно работать, если хотя бы на 1 команду меньше. Ниже описывается сколько участников всупят в первый день, у меня же это считается первая стадия, точнее максимальная(Стадия - Круг, в котором встречаются четыре игрока, называется полуфиналом. При числе участников свыше 16 круг, ему предшествующий, т. е. в котором встречаются восемь игроков, называется четвертьфиналом.)
    Теперь что у меня не получается: я могу расчитать количество команд, которые должны начать играть в первый день, и вот тут начинается проблемос. Возьмем например максимум 16 команд, это 4 стадии. У меня зарегистрировались всего 9, получается на 4 стадии играют 2 команды(рассчитывая по формуле), а остальные 7 начинают с третьей стадии. Сетка генерируется по матчам, таблица матчей выглядит так:
    Так вот как мне сделать, чтобы скрипт правильно понимал, сколько команд в первой стадии, а остальных кидал на предыдущую стадию. Если нужен скрипт, который генерирует данный запрос, выложу. Помогите пожалуйста. Третий день голову ломаю, ничего придумать не могу(
     
  2. ridvik

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

    С нами с:
    7 июл 2012
    Сообщения:
    64
    Симпатии:
    0
  3. denis01

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

    С нами с:
    9 дек 2014
    Сообщения:
    12.227
    Симпатии:
    1.714
    Адрес:
    Молдова, г.Кишинёв
    Портянка непонятная. По этому похоже никто не пишет. А ну и азартные игры не любят.
     
  4. artoodetoo

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

    С нами с:
    11 июн 2010
    Сообщения:
    11.131
    Симпатии:
    1.250
    Адрес:
    там-сям
    Как должна строиться сетка, если собралось нечетное количество команд, например 3?

    Добавлено спустя 5 минут 58 секунд:
    Отставить, вопрос снят ))) Просто начни писать код и покажи. Если хочешь чтобы за тебя всё целиком сделали, то тебе в другой раздел — "Фриланс", там за деньги договариваются.
     
  5. ridvik

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

    С нами с:
    7 июл 2012
    Сообщения:
    64
    Симпатии:
    0
    Код у меня есть и работает. Я же написал, если регистрируется команд столько, сколько заявлено на турнир, то все норм, а если хотя бы на одну меньше, то тут уже нужно рассчитывать по формуле, приведенной выше. Код, которым я генерирую сетку:
    Контроллер
    Код (Text):
    1. public function tournament_grid ($tour_id = NULL) {
    2.         // Получаем данные турнира
    3.         $query = $this->dyn_tournaments->info_tournament($tour_id);
    4.         // Получаем список матчей турнира
    5.         $matches = $this->dyn_tournaments->get_all_matchs_in_tour_user($tour_id)->result_array();
    6.         // Список участников
    7.         if($query[0]['type_register'] == 1) {
    8.             $teams_players = $this->dyn_tournaments->get_all_teams_in_tour($tour_id)->result_array();
    9.         } elseif ($query[0]['type_register'] == 2) {
    10.             $teams_players = $this->dyn_tournaments->get_all_players_in_tour($tour_id)->result_array();
    11.         }
    12.         // Расчитываем количество стадий
    13.         $stage = ceil(log($query[0]['numbers_teams'])/log(2));
    14.         $count = $query[0]['numbers_teams'] / 2;
    15.         $counts = $count;
    16.        
    17.         $datas = array("8" => array(), "7" => array(), "6" => array(), "5" => array(), "4" => array(), "3" => array(), "2" => array(), "1" => array());
    18.         foreach ($matches as $key=>$value) {
    19.             if      ($matches[$key]['stage'] == '8') {
    20.                 $datas['8'][] = array(
    21.                     'team_id_1' =>  $matches[$key]['name_1'],
    22.                     'team_id_2' =>  $matches[$key]['name_2'],
    23.                     'stage'     =>  $matches[$key]['stage'],
    24.                     'cell'      =>  $matches[$key]['cell'],
    25.                     'score'     =>  $matches[$key]['score_1'].':'.$matches[$key]['score_2'],
    26.                     'date'      =>  $matches[$key]['date_match'],
    27.                     );
    28.             }
    29.             elseif  ($matches[$key]['stage'] == '7')  {
    30.                 $datas['7'][] = array(
    31.                     'team_id_1' =>  $matches[$key]['name_1'],
    32.                     'team_id_2' =>  $matches[$key]['name_2'],
    33.                     'stage'     =>  $matches[$key]['stage'],
    34.                     'cell'      =>  $matches[$key]['cell'],
    35.                     'score'     =>  $matches[$key]['score_1'].':'.$matches[$key]['score_2'],
    36.                     'date'      =>  $matches[$key]['date_match'],
    37.                 );
    38.             }  
    39.             elseif  ($matches[$key]['stage'] == '6')  {
    40.                 $datas['6'][] = array(
    41.                     'team_id_1' =>  $matches[$key]['name_1'],
    42.                     'team_id_2' =>  $matches[$key]['name_2'],
    43.                     'stage'     =>  $matches[$key]['stage'],
    44.                     'cell'      =>  $matches[$key]['cell'],
    45.                     'score'     =>  $matches[$key]['score_1'].':'.$matches[$key]['score_2'],
    46.                     'date'      =>  $matches[$key]['date_match'],
    47.                 );
    48.             }  
    49.             elseif  ($matches[$key]['stage'] == '5')  {
    50.                 $datas['5'][] = array(
    51.                     'team_id_1' =>  $matches[$key]['name_1'],
    52.                     'team_id_2' =>  $matches[$key]['name_2'],
    53.                     'stage'     =>  $matches[$key]['stage'],
    54.                     'cell'      =>  $matches[$key]['cell'],
    55.                     'score'     =>  $matches[$key]['score_1'].':'.$matches[$key]['score_2'],
    56.                     'date'      =>  $matches[$key]['date_match'],
    57.                 );
    58.             }  
    59.             elseif  ($matches[$key]['stage'] == '4')  {
    60.                 $datas['4'][] = array(
    61.                     'team_id_1' =>  $matches[$key]['name_1'],
    62.                     'team_id_2' =>  $matches[$key]['name_2'],
    63.                     'stage'     =>  $matches[$key]['stage'],
    64.                     'cell'      =>  $matches[$key]['cell'],
    65.                     'score'     =>  $matches[$key]['score_1'].':'.$matches[$key]['score_2'],
    66.                     'date'      =>  $matches[$key]['date_match'],
    67.                 );
    68.             }  
    69.             elseif  ($matches[$key]['stage'] == '3')  {
    70.                 $datas['3'][] = array(
    71.                     'team_id_1' =>  $matches[$key]['name_1'],
    72.                     'team_id_2' =>  $matches[$key]['name_2'],
    73.                     'stage'     =>  $matches[$key]['stage'],
    74.                     'cell'      =>  $matches[$key]['cell'],
    75.                     'score'     =>  $matches[$key]['score_1'].':'.$matches[$key]['score_2'],
    76.                     'date'      =>  $matches[$key]['date_match'],
    77.                 );
    78.             }
    79.             elseif  ($matches[$key]['stage'] == '2')  {
    80.                 $datas['2'][] = array(
    81.                     'team_id_1' =>  $matches[$key]['name_1'],
    82.                     'team_id_2' =>  $matches[$key]['name_2'],
    83.                     'stage'     =>  $matches[$key]['stage'],
    84.                     'cell'      =>  $matches[$key]['cell'],
    85.                     'score'     =>  $matches[$key]['score_1'].':'.$matches[$key]['score_2'],
    86.                     'date'      =>  $matches[$key]['date_match'],
    87.                 );
    88.             }
    89.             elseif  ($matches[$key]['stage'] == '1')  {
    90.                 $datas['1'][] = array(
    91.                     'team_id_1' =>  $matches[$key]['name_1'],
    92.                     'team_id_2' =>  $matches[$key]['name_2'],
    93.                     'stage'     =>  $matches[$key]['stage'],
    94.                     'cell'      =>  $matches[$key]['cell'],
    95.                     'score'     =>  $matches[$key]['score_1'].':'.$matches[$key]['score_2'],
    96.                     'date'      =>  $matches[$key]['date_match'],
    97.                     'win'       =>  $query[0]['win'],
    98.                 );
    99.             }          
    100.         }
    101.        
    102.         // вывод в шаблон
    103.         $data = array(
    104.             'stage'         =>  $stage,
    105.             'count'         =>  $count,
    106.             'counts'        =>  $counts,
    107.             'matches'       =>  $matches,
    108.             'datas'         =>  $datas,
    109.             'teams_players' =>  $teams_players
    110.         );
    111.        
    112.         $this->template->load_view('grid', $data);     
    113.     }
    Вывод
    Код (Text):
    1. <?php
    2. $pixel = 20;
    3. $pixel_b = 20;
    4. $height = 60;
    5. $height2 = 20;
    6. $height3 = 20;
    7. $px = 2;
    8. $px_1 = 1;
    9. $margin = 0;
    10. $margin_top = 0;
    11. $width = 0;
    12. $text = "<div class='table_teams' style='text-align:center'>";
    13. $text .= "<div class='table_matchs'>";
    14. for($x=$stage+1;$x>0;$x--) {
    15.             if ($x == 1) {
    16.                 $text_stage = "Победитель";
    17.             } else if ($x == 2 ) {
    18.                 $text_stage = "Финал";
    19.             } else if ($x == 3) {
    20.                 $text_stage = "Полуфинал";
    21.             } else {
    22.                 $text_stage = '1/'.$counts;
    23.             }
    24.     $text .= "<div style='float:left; margin-left:10px; width:100px; margin-right:10px;'><div class='table_text first'>".$text_stage."</div></div>";
    25.     $counts = $counts / 2;
    26. }
    27. $text .= "</div>";
    28. $text .= "<div class='table_teams'>";
    29. $teams = array("8" => array(), "7" => array(), "6" => array(), "5" => array(), "4" => array(), "3" => array(), "2" => array(), "1" => array());
    30. for ($x=$stage;$x>0;$x--) {
    31.     $text .= "<div class='table_team'>";
    32.         for ($i=0; $i<$count;$i++) {
    33.             if(!empty($data)) {if ($datas[$x][$i]['score'] == ':') $datas[$x][$i]['score'] = "Нет информации";}
    34.             $text .= $teams[$x][] =
    35.             "<div class='table_tr' style='margin-top:".$pixel."px; margin-bottom:".$pixel_b."px;' match_id='".$i."'><a href='#'>".
    36.                 "<div class='table_text first'><div class = 'lcenter' style='float:left;width:".$width."px;height:20px'></div>".(empty($datas[$x][$i]['team_id_1']) ? "&nbsp;" : $datas[$x][$i]['team_id_1'])."<div class = 'tr_corner' style = 'float:right; width:10px; height:20px;'></div></div>".
    37.                 "<div class='table_text2' style='height:".$height2."px; line-height:".$height2."px;'><div class = 'line_vertical_corner' style = 'float:right; width:10px; height:".$height2."px;'></div><div style = 'float:right;margin-right:20'>".(empty($datas[$x][$i]['score']) ? "&nbsp;" : $datas[$x][$i]['score'])."</div></div>".
    38.                 "<div class='table_text last'><div class = 'lcenter' style='float:left;width:".$width."px;height:20px'></div>".(empty($datas[$x][$i]['team_id_2']) ? "&nbsp;" : $datas[$x][$i]['team_id_2'])."<div class = 'br_corner' style = 'float:right; width:10px; height:20px;'></div></div>".
    39.             "</a></div>";
    40.         }
    41.     $px = $px * 2;
    42.     $px_1 = $px - 1;
    43.     $pixel = $pixel  * 2;
    44.     $pixel_b = $pixel_b * 2 + 20;
    45.     $height = 20 + $pixel + 20;
    46.     $height2 = $height3 * $px_1;
    47.     $count = $count / 2;
    48.     $text .= "</div>";
    49.     if( $x == 1 ) {
    50.         $text .= $teams[$x][] =
    51.         "<div class='table_team'>
    52.             <div class='table_tr' style='margin-top:".$pixel."px; margin-bottom:".$pixel_b."px;' match_id='".$i."'>".
    53.                 "<div class='table_text first'><div class = 'lcenter' style='float:left;width:".$width."px;height:20px'></div>".(empty($datas[$x][$i-1]['win']) ? "&nbsp;" : $datas[$x][$i-1]['win'])."</div>".
    54.             "</div>
    55.         </div>";
    56.             }
    57.     $width = 10;
    58. }
    59. $text .= "</div>";
    60. $text .= "</div>";
    61. echo $text;
    62.  
    63. ?>
    В таблицу матчей заносятся вот такой запрос:
    Код (Text):
    1. INSERT `matchs` (id_tour,stage,cell,next_stage,next_cell,next_team_id,team_id_1,team_id_2) VALUES
    2. (1, 4, 1, 3, 1, 'team_id_1', '5', '3'),
    3. (1, 4, 2, 3, 1, 'team_id_2', '1', '8'),
    4. (1, 4, 3, 3, 2, 'team_id_1', '6', '2'),
    5. (1, 4, 4, 3, 2, 'team_id_2', '4', '7'),
    6. (1, 4, 5, 3, 3, 'team_id_1', '', '9'),
    7. (1, 4, 6, 3, 3, 'team_id_2', '', ''),
    8. (1, 4, 7, 3, 4, 'team_id_1', '', ''),
    9. (1, 4, 8, 3, 4, 'team_id_2', '', ''),
    10. (1, 3, 1, 2, 1, 'team_id_1', '', ''),
    11. (1, 3, 2, 2, 1, 'team_id_2', '', ''),
    12. (1, 3, 3, 2, 2, 'team_id_1', '', ''),
    13. (1, 3, 4, 2, 2, 'team_id_2', '', ''),
    14. (1, 2, 1, 1, 1, 'team_id_1', '', ''),
    15. (1, 2, 2, 1, 1, 'team_id_2', '', ''),
    16. (1, 1, 1, 0, 1, 'team_id_1', '', '');
    Как видите у меня все написано, только вот переделать немного нужно, чтобы работало как я описал выше, а на это у меня уже знаний не хватает
     
  6. artoodetoo

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

    С нами с:
    11 июн 2010
    Сообщения:
    11.131
    Симпатии:
    1.250
    Адрес:
    там-сям
    Не понял про "регистрируется меньше, чем заявлено на турнир". Ты должен просто работать с тем числом команд, которое регистрируется, сколько бы ни было. Не?
    Правила расписывают сколько команд должно соревноваться в этот день, в зависимости от того, сколько их всего. Это формула. И в чем твоя заминка?
     
  7. ridvik

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

    С нами с:
    7 июл 2012
    Сообщения:
    64
    Симпатии:
    0
    сейчас объясню что я не могу сделать, когда создаю турнир, указываю сколько команд максимум может принять участие, например возьмем 16, но на турнир зарегистрировалось 9 команд. Чтобы сетка выводила всё правильно, нужно создать вот такой запрос на 15 матчей:
    Код (Text):
    1. INSERT `matchs` (id_tour,stage,cell,next_stage,next_cell,next_team_id,team_id_1,team_id_2) VALUES
    2. (1, 4, 1, 3, 1, 'team_id_1', '5', '3'),
    3. (1, 4, 2, 3, 1, 'team_id_2', '1', '8'),
    4. (1, 4, 3, 3, 2, 'team_id_1', '6', '2'),
    5. (1, 4, 4, 3, 2, 'team_id_2', '4', '7'),
    6. (1, 4, 5, 3, 3, 'team_id_1', '', '9'),
    7. (1, 4, 6, 3, 3, 'team_id_2', '', ''),
    8. (1, 4, 7, 3, 4, 'team_id_1', '', ''),
    9. (1, 4, 8, 3, 4, 'team_id_2', '', ''),
    10. (1, 3, 1, 2, 1, 'team_id_1', '', ''),
    11. (1, 3, 2, 2, 1, 'team_id_2', '', ''),
    12. (1, 3, 3, 2, 2, 'team_id_1', '', ''),
    13. (1, 3, 4, 2, 2, 'team_id_2', '', ''),
    14. (1, 2, 1, 1, 1, 'team_id_1', '', ''),
    15. (1, 2, 2, 1, 1, 'team_id_2', '', ''),
    16. (1, 1, 1, 0, 1, 'team_id_1', '', '');
    То есть матчей по такой системе всегда на 1 меньше чем команд. так вот как мне сформировать такой запрос в базу чтобы матчи правильно рассчитались, сколько в первой стадии, сколько во второй. Если не совсем понятно и сейчас(нету у меня дара хорошо и понятно описывать), могу постараться с сделать скриншоты и с ними объяснить.
     
  8. artoodetoo

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

    С нами с:
    11 июн 2010
    Сообщения:
    11.131
    Симпатии:
    1.250
    Адрес:
    там-сям
  9. ridvik

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

    С нами с:
    7 июл 2012
    Сообщения:
    64
    Симпатии:
    0
    да)) эта самая ссылка))) помогите мне)) просто знаний в пхп не хватает чтобы провернуть такое)))
     
  10. artoodetoo

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

    С нами с:
    11 июн 2010
    Сообщения:
    11.131
    Симпатии:
    1.250
    Адрес:
    там-сям
    PHP это всего лишь язык. Если бы ты представил четко алгоритм, не было бы проблемы выразить его хоть на PHP, хоть на чём.

    Я могу написать программу (уже написал), но чем это тебе поможет? Ты ничему не научишся. Давай-ка сам делай. У тебя должны быть маленькие конкретные вопросы, а не "напишите всё за меня".

    Подсказка 1: забудь на время про HTML и всякие таблицы. Тебе нужно написать функцию, дающую число n == степень двойки, ближайшую к A.

    Добавлено спустя 5 минут 38 секунд:
    Моя эмуляция турнира:
    Код (Text):
    1. Starts from 12 teams
    2. Day: 1, 8 teams: (3, 4, 5, 6, 7, 8, 9, 10), Off: 4, 5, 8, 10,
    3. Day: 2, 8 teams: (1, 2, 3, 6, 7, 9, 11, 12), Off: 2, 6, 7, 11,
    4. Day: 3, 4 teams: (1, 3, 9, 12), Off: 3, 9,
    5. Day: 4, 2 teams: (1, 12), Off: 12,
    6. Team #1 wins!!!
     
  11. ridvik

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

    С нами с:
    7 июл 2012
    Сообщения:
    64
    Симпатии:
    0
    $k = ($count_teams - $out)*2; прошу) есть такая функция)) только выводит не степень, а число 2,4,8,16,32 и ид))

    Добавлено спустя 1 минуту 1 секунду:
    Код (Text):
    1. $out = 0;
    2. if($count_teams == 4) {
    3.     $out = 2;
    4. } else if ($count_teams > 4 AND $count_teams < 8) {
    5.     $out = 4;
    6. } else if ($count_teams == 8) {
    7.     $out = 4;
    8. } else if ($count_teams > 8 AND $count_teams < 16) {
    9.     $out = 8;
    10. } else if ($count_teams == 16) {
    11.     $out = 8;
    12. } else if ($count_teams > 16 AND $count_teams < 32) {
    13.     $out = 16;
    14. } else if ($count_teams == 32) {
    15.     $out = 16;
    16. } else if ($count_teams > 32 AND $count_teams < 64) {
    17.     $out = 32;
    18. } else if ($count_teams == 64) {
    19.     $out = 32;
    20. } else if ($count_teams > 64 AND $count_teams < 128) {
    21.     $out = 64;
    22. } else if ($count_teams == 128) {
    23.     $out = 64;
    24. }
    и вот ещё
     
  12. artoodetoo

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

    С нами с:
    11 июн 2010
    Сообщения:
    11.131
    Симпатии:
    1.250
    Адрес:
    там-сям
    О_о. некрасиво. точнее это ЧУДОВИЩНО БУЭ!
     
  13. ridvik

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

    С нами с:
    7 июл 2012
    Сообщения:
    64
    Симпатии:
    0
    знаю) но это работает))
     
  14. artoodetoo

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

    С нами с:
    11 июн 2010
    Сообщения:
    11.131
    Симпатии:
    1.250
    Адрес:
    там-сям
    ага, возможно. на коротком диапазоне чисел. но за такое карают анально. причём дважды — ты заметил, что каждый ответ повторяется по два раза? зачем????????????????
    не показывай такое никому!

    Добавлено спустя 1 минуту 33 секунды:
    Подсказка 2: чтобы вычислить это самое ближайшее к А число, ты можешь сделать цикл.
     
  15. ridvik

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

    С нами с:
    7 июл 2012
    Сообщения:
    64
    Симпатии:
    0
    ты мне подскажи как мне с матчами разобраться) в будущем я всё равно буду код улучшать, а сейчас нужно сделать его чтобы он вообще работал))
     
  16. artoodetoo

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

    С нами с:
    11 июн 2010
    Сообщения:
    11.131
    Симпатии:
    1.250
    Адрес:
    там-сям
    Ну так там же формула. Она всегда работает!
    Через эту степень двойки вычисляешь кол-во команд в текущем розыгрыше, берешь из середины списка это число команд и собственно всё! Каждый второй из этих избранных вылетит, а с оставшимися итерация повторится на следующем розыгрыше.

    Добавлено спустя 7 минут 20 секунд:
    Подсказка 3: раз ты новичек, расскажу про полезную встроенную функцию PHP "взять из массива кусочек, начиная с какого-то отступа":
    Код (PHP):
    1. $today_teams = array_slice($teams, $offset, $n); 
     
  17. ridvik

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

    С нами с:
    7 июл 2012
    Сообщения:
    64
    Симпатии:
    0
    ну так а до этого то массив как-то сформировать нужно с матчами, я так понимаю, прежде чем выбирать то
     
  18. artoodetoo

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

    С нами с:
    11 июн 2010
    Сообщения:
    11.131
    Симпатии:
    1.250
    Адрес:
    там-сям
    не может у тебя быть массива с матчами. ты что, знаешь заранее кто выиграет?
    у тебя может (должен) быть массив с командами. из них в розыгрыше какие-то выбывают.
    выражаясь на PHP это
    Код (PHP):
    1. $index_to_off = array_search($number, $teams);
    2. unset($teams[$index_to_off]);
    выражаясь на SQL это
    Код (Text):
    1. DELETE FROM `teams` WHERE `number`=:number
    оставшийся список команд это точно такой же список как в самом начале, только короче ;)

    ну же! неужели еще не всё понятно?
     
  19. ridvik

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

    С нами с:
    7 июл 2012
    Сообщения:
    64
    Симпатии:
    0
    ну теоретически понятно, а так что-то туплю)) без обид))) просто в голове по другому сформирована идея, поэтому трудно немного понять, как ты объясняешь))
     
  20. artoodetoo

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

    С нами с:
    11 июн 2010
    Сообщения:
    11.131
    Симпатии:
    1.250
    Адрес:
    там-сям
    да какие обиды, ты же тупишь, не я :)
    раздупляйся и делай. завтра. а сейчас пора спать.
     
  21. ridvik

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

    С нами с:
    7 июл 2012
    Сообщения:
    64
    Симпатии:
    0
    стой) не уходи)) покажи пример массива, как ты там предполагаешь) просто я не пойму как это все по стадиям раскинуть))
     
  22. ridvik

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

    С нами с:
    7 июл 2012
    Сообщения:
    64
    Симпатии:
    0
    ап, хелп ми(