Perl - как создать HTML-таблицу турнирной таблицы
Хорошо, я создаю генератор турнирной сетки, и до сих пор у меня есть следующее, которое генерирует массив конкурентов в определенной весовой категории, отсортированной по семени.
У меня проблема в том, что я не могу получить его для вывода в HTML в формате скобок.
Итак, перед следующим кодом я ищу базу данных, выбираю конкурентов в определенной весовой категории и сохраняю их в массиве @result. Затем:
#place the competitors into the @sortBySeed array highest seed to lowest.
my @sortBySeed = sort { $b->[5] <=> $a->[5] } @$result;
# this is an array which contains the arrays of the individual bouts
i.e competitors/2 bouts, each array holding the names of the two competitors.
my $numberStartingBouts = scalar(@sortBySeed) / 2;
# if there are an even amount of competitors then a bye isn't needed
if ( isint $numberStartingBouts) {
for ( my $i = 0 ; $i < scalar(@sortBySeed) ; $i++ )
{
#remove the top seed from the array and return, remove the bottom seed and return
my $competitor1 = pop(@sortBySeed);
my $competitor2 = shift(@sortBySeed);
# place them into the knockout array in a bout
push(@knockoutArray, $competitor1);
push(@knockoutArray, $competitor2);
}
}
else
{
# remove the top seed and give them a bye
my $competitor1 = shift(@sortBySeed);
my $competitor2 = 'Bye';
push(@knockoutArray, $competitor1);
push(@knockoutArray, $competitor2);
# process the rest as above
for (my $i = 0 ; $i < scalar(@sortBySeed) ; $i++ )
{
my $competitor1 = shift(@sortBySeed);
my $competitor2 = pop(@sortBySeed);
push(@knockoutArray, $competitor1);
push(@knockoutArray, $competitor2);
}
}
# flatten the first part of the array so that it's a scalar and not an array within the array
map{$_=join(" ",@$_[1..3]) if(ref $_ eq 'ARRAY');} @knockoutArray;
Итак, теперь у меня есть массив @knockoutArray, который содержит следующее (показано с использованием data::dumper):
$VAR1 = 'Seed 1';
$VAR2 = 'Bye';
$VAR3 = 'Seed 2';
$VAR4 = 'Seed 7';
$VAR5 = 'Seed 3';
$VAR6 = 'Seed 6';
$VAR7 = 'Seed 4';
$VAR8 = 'Seed 5';
У меня есть следующая статическая HTML-страница для вышеуказанного массива, и я могу поместить в нее детали
<!--
table {
border-collapse: collapse;
border: none;
font: small arial, helvetica, sans-serif;
}
td {
vertical-align: middle;
width: 10em;
margin: 0;
padding: 0;
}
td p {
border-bottom: solid 1px black;
margin: 0;
padding: 5px 5px 2px 5px;
}
-->
</style>
</head>
<body>
<table summary="Tournament Bracket">
<tr>
<td><p><% data.0 %></p></td>
<td rowspan="2"><p></p></td>
<td rowspan="4"><p></p></td>
<td rowspan="8"><p></p></td>
</tr>
<tr>
<td><p><%data.1%></p></td>
</tr>
<tr>
<td><p><% data.2 %></p></td>
<td rowspan="2"><p></p></td>
</tr>
<tr>
<td><p><% data.3 %></p></td>
</tr>
<tr>
<td><p><% data.4 %></p></td>
<td rowspan="2"><p></p></td>
<td rowspan="4"><p></p></td>
</tr>
<tr>
<td><p><% data.5 %></p></td>
</tr>
<tr>
<td><p><% data.6 %></p></td>
<td rowspan="2"><p></p></td>
</tr>
<tr>
<td><p><% data.7 %></p></td>
</tr>
</table>
</body>
</html>
Как я могу вывести это, используя HTML, где таблица будет динамически увеличиваться или уменьшаться в зависимости от размера массива, который я передаю ей? Я использую Perl Dancer и Template Toolkit, поэтому все, что связано с ними, будет полезно!
Любой метод, который также включает в себя сохранение массива в скобках турнира в файле, который будет вызван позже, был бы чрезвычайно полезен.
Я бы хотел, чтобы скобка выглядела так:
http://www.jimyi.com/content/brackets/tournament4.html
Спасибо!
1 ответ
Если число конкурентов изменяется, то, очевидно, количество столбцов изменится, и размер строки для этих столбцов будет удваиваться для каждого столбца, движущегося вправо, пока не будет достигнуто округленное количество конкурентов. Итак <td>
ячейки, проходящие через страницу, должны быть объявлены динамически. Будучи HTML-таблицами, я бы сказал, что создание вертикальной презентации турнира значительно упростит эту логику.
Если бы я столкнулся с этой проблемой, я бы начал с HTML:: TableBracket, который, похоже, поможет вам в этом. Несмотря на то, что вывод не совсем то, что вам нужно (кажется, что вы отслеживаете результаты), логика вывода таблицы HTML все есть, и это должно быть достаточно просто, чтобы настроить as_html()
метод для ваших целей. Я буду добавлять к нему кучу отладочного кода, пока не пойму достаточно логику цикла.
В качестве бонуса, кажется, избавляет от необходимости рассчитывать бой противников - порядок передачи заявок new()
определяет, как они распределяются.
Если вы действительно хотите бросить свой собственный, я также могу представить сценарий, где у вас есть arrayref из arrayrefs. В 0-м ряду есть все конкуренты, например @knockoutArray
, В 1-й строке их вдвое меньше, во 2-й половине снова... пока у вас не будет массива с 1 элементом.
my $data = [
[ 'Seed 1','Bye','Seed 2','Seed 7','Seed 3','Seed 6','Seed 4','Seed 5' ],
[ 'Seed 1', '2 vs 7', '3 vs 6', '4 vs 5' ],
[ '1 vs 2/7', '3/6 vs 4/5' ],
[ '1/2/7 vs 3/6/4/5' ]
];
Я понятия не имею, как вы планируете представлять эти бои дальше в турнире, в котором вы идете, поэтому создание этого массива остается в качестве упражнения для читателя.
Код вашего шаблона, вероятно, будет выглядеть примерно так:
[%-
USE Perl;
SET rows = data.0.size;
SET cols = data.size;
SET elem = [];
FOREACH row IN data;
elem.push(0); # [ 0,0,0,0 ]
END;
'<table>';
SET row = 0;
WHILE row < rows;
'<tr>';
SET col = 0;
WHILE col < cols;
SET rowspan = Perl.pow(2, col);
IF row % rowspan == 0;
'<td rowspan='; rowspan; '>'; data.$col.item(elem.$col); '</td>';
SET elem.$col = elem.$col + 1;
END;
SET col = col + 1;
END;
'</tr>';
SET row = row + 1;
END;
'</table>';
-%]
Мне пришлось использовать https://metacpan.org/pod/Template::Plugin::Perl для этого кода, потому что TT из коробки не поддерживает математический показатель.
(Кстати, я не думаю, что ваша логика "четного числа записей" сработает, если у вас есть 6 участников. Если вы сохраняете свой исходный код, я думаю, что вам нужно добавлять записи Bye, пока вы не достигнете коэффициента 2.)