PHP单淘汰比赛表
我已经浏览了其他几篇类似的帖子,但是找不到任何适合我的 我已经设法硬编码了一个8队比赛括号表,但我真的希望有一种方法,可以使用基于输入的队数的for/if语句来绘制该表PHP单淘汰比赛表,php,html-table,Php,Html Table,我已经浏览了其他几篇类似的帖子,但是找不到任何适合我的 我已经设法硬编码了一个8队比赛括号表,但我真的希望有一种方法,可以使用基于输入的队数的for/if语句来绘制该表 这是使用COLSPANS和ROWSPANS硬编码表创建空白空间的代码(在使用CSS而不是表之前,我不太清楚CSS,但对表有信心): 第1轮第2轮最终获胜者 第一组 得分1分1胜 第2组核心5 第二轮优胜者 第3组核心7 得分2分1胜 第4组 冠军 第5组 得分3分,第一轮获胜 第6组得分6分 第二轮优胜者 第7组 第1轮得分4
这是使用COLSPANS和ROWSPANS硬编码表创建空白空间的代码(在使用CSS而不是表之前,我不太清楚CSS,但对表有信心):
第1轮第2轮最终获胜者
第一组
得分1分1胜
第2组核心5
第二轮优胜者
第3组核心7
得分2分1胜
第4组
冠军
第5组
得分3分,第一轮获胜
第6组得分6分
第二轮优胜者
第7组
第1轮得分4分
第8组
这就是它产生的结果:
到目前为止,我一直在尝试使用for和if语句创建上面的语句,我已经到了第一列列出了团队名称的地步,但从这一点上我无法确定我需要做什么
<?php
echo "<table border='1' cellspacing='1' cellpadding='1'>";
$num_teams = 8;
$nRounds = floor(log($num_teams,2));
$max_rows = $num_teams*2;
for ($row = 0; $row <= $max_rows; $row++)
{
echo "<tr>";
if ($row == 0)
{
for ($i = 1; $i <= $nRounds+1; $i++)
{
if($i < $nRounds)
{
echo "<td width='120'><b>Round ".$i."</b></td>";
echo "<td width='20'></td>";
}
elseif($i == $nRounds)
{
echo "<td width='120'><b>Final</b></td>";
echo "<td width='20'></td>";
}
else
{
echo "<td width='120'><b>Winner</b></td>";
}
}
}
elseif($row == 1)
{
$rowwhitespace = ($nRounds*2)+1;
echo "<td colspan='".$rowwhitespace."'> </td>";
}
else
{
$rowwhitespace = ($nRounds*2);
for ($i = 1; $i <= $num_teams; $i++)
{
if($i == $row/2)
{
echo "<td>Group ".$i."</td>";
echo "<td colspan='".$rowwhitespace."'></td>";
}
}
}
echo "</tr>";
}
echo "</table>";
?>
最快、最简单的方法是,将手动编码的html保存到某种模板文件中。比如说,锦标赛表.html
接下来,将保存的模板文件中的动态数据的每个实例更改为模板标记,例如:
- 组1=>{#组1名称}
- 组2=>{#组2名称}
- 分数1=>{#分数1名称}
- 冠军=>{#冠军名}
您的模板将如下所示:
<tr><td>{#group1-name}</td><td width='20'></td></tr>
<tr><td align='center'>{#score1-name}</td><td></td><td>{#round1-winner}</td><td width='20'></td></tr>
$raw_template = file_get_contents('/path/to/your/template/tournament-table.html');
将所需数据填入变量:
//do the needed queries
//after that, fill variable with query and processes result
$group1_name = "Group 1";
$group2_name = "Group 2";
$Score1_name = "Score 1";
下一步是执行字符串替换:
$raw_template = str_replace('{#group1-name}', $group1_name, $raw_template, 1);
最后,回应结果:
echo $raw_template;
编辑:
好的,我决定在凌晨2点前解决这个问题。调试大约花了半个小时。我知道我并没有更多的跨度,但我不想再花更多的时间去尝试,因为它更多的是调整数学公式来获得正确的结果。屏幕截图如下。如果你需要任何解释,请告诉我
<?php
function is_player($round, $row, $team) {
return $row == pow(2, $round-1) + 1 + pow(2, $round)*($team - 1);
}
$num_teams = 16;
$total_rounds = floor(log($num_teams, 2)) + 1;
$max_rows = $num_teams*2;
$team_array = array();
$unpaired_array = array();
$score_array = array();
for ($round = 1; $round <= $total_rounds; $round++) {
$team_array[$round] = 1;
$unpaired_array[$round] = False;
$score_array[$round] = False;
}
echo "<table border=\"1\" cellspacing=\"1\" cellpadding=\"1\">\n";
echo "\t<tr>\n";
for ($round = 1; $round <= $total_rounds; $round++) {
echo "\t\t<td colspan=\"2\"><strong>Round $round</strong></td>\n";
}
echo "\t</tr>\n";
for ($row = 1; $row <= $max_rows; $row++) {
echo "\t<tr>\n";
for ($round = 1; $round <= $total_rounds; $round++) {
$score_size = pow(2, $round)-1;
if (is_player($round, $row, $team_array[$round])) {
$unpaired_array[$round] = !$unpaired_array[$round];
echo "\t\t<td>Team</td>\n";
echo "\t\t<td width=\"20\"> </td>\n";
$team_array[$round]++;
$score_array[$round] = False;
} else {
if ($unpaired_array[$round] && $round != $total_rounds) {
if (!$score_array[$round]) {
echo "\t\t<td rowspan=\"$score_size\">Score</td>\n";
echo "\t\t<td rowspan=\"$score_size\" width=\"20\">$round</td>\n";
$score_array[$round] = !$score_array[$round];
}
} else {
echo "\t\t<td colspan=\"2\"> </td>\n";
}
}
}
echo "\t</tr>\n";
}
echo "</table>\n";
?>
然后我们可以从数学上得出以下结论:
将$round
设为轮号,$row
设为行号,$team
设为该轮中的队号(稍后解释)
团队打印在$row=[2^($round-1)+[1]+[2^($round)]*$team
上,要理解这个公式,你需要把它画出来,但基本上因为团队是2的幂,你在第一轮中使用4行(2的幂)来代表每个“游戏”,我们可以不断地将事情分解,并对打印团队的行进行数学求解。因此,公式表明,对于第轮中编号为$team
的团队$round
将列在第行$row
中,团队数量始终除以2,因为有一半团队被淘汰。总轮次数只是团队总数的基数2,正如您在代码中所做的那样。下一个分数是在任何一对球队之间公布的,所以这并不太糟糕
当然,最大的问题是您需要打印一个表,这需要在打印时按行而不是按列进行。最好的方法是有一个目标公式,然后测试所处的行和列是否满足只需要一个简单函数即可测试的等式(因为您知道有多少轮,所以需要生成列的总数)
我希望这有助于引导您实现我试图设定的目标。如果我有时间的话,我会试着晚些时候做点什么。干杯。不是关于你的问题,但是你不需要所有的回音,只要把html放在页面上就行了。公平的评论,谢谢,编辑。我认为这绝对是学习CSS的一个原因,因为他们可以用很少的行来解决这个问题。有趣的方法,这意味着必须为更多的团队手动创建表格,但仍然有可能。在$row的等式中,方括号做了什么?对不起,我写它更像是一个等式,用代码语言,我想这会把事情搞砸,但只是在逻辑上强调不同的部分。真的,你可以对它造成的任何混乱感到抱歉。好的,使用这个公式(用普通括号代替方括号)并不能给出正确的行号,例如:如果Round=1,Team=1,行号在应该是2时返回为4。假设行开始为零,然后是一个空白行。哦,是的,很抱歉,我很快就抵消了它应该是$row=(2^($round-1)+1)+(2^($round))*($team-1)好的,这很好,现在可以完美地在所有回合中输出正确的行,用于团队名称应该输出到的位置,包括获胜者。现在只需要把它发展成表格。
<?php
function is_player($round, $row, $team) {
return $row == pow(2, $round-1) + 1 + pow(2, $round)*($team - 1);
}
$num_teams = 16;
$total_rounds = floor(log($num_teams, 2)) + 1;
$max_rows = $num_teams*2;
$team_array = array();
$unpaired_array = array();
$score_array = array();
for ($round = 1; $round <= $total_rounds; $round++) {
$team_array[$round] = 1;
$unpaired_array[$round] = False;
$score_array[$round] = False;
}
echo "<table border=\"1\" cellspacing=\"1\" cellpadding=\"1\">\n";
echo "\t<tr>\n";
for ($round = 1; $round <= $total_rounds; $round++) {
echo "\t\t<td colspan=\"2\"><strong>Round $round</strong></td>\n";
}
echo "\t</tr>\n";
for ($row = 1; $row <= $max_rows; $row++) {
echo "\t<tr>\n";
for ($round = 1; $round <= $total_rounds; $round++) {
$score_size = pow(2, $round)-1;
if (is_player($round, $row, $team_array[$round])) {
$unpaired_array[$round] = !$unpaired_array[$round];
echo "\t\t<td>Team</td>\n";
echo "\t\t<td width=\"20\"> </td>\n";
$team_array[$round]++;
$score_array[$round] = False;
} else {
if ($unpaired_array[$round] && $round != $total_rounds) {
if (!$score_array[$round]) {
echo "\t\t<td rowspan=\"$score_size\">Score</td>\n";
echo "\t\t<td rowspan=\"$score_size\" width=\"20\">$round</td>\n";
$score_array[$round] = !$score_array[$round];
}
} else {
echo "\t\t<td colspan=\"2\"> </td>\n";
}
}
}
echo "\t</tr>\n";
}
echo "</table>\n";
?>
1| Empty Row
2| Team 1
3| Score
4| Team 2