PHP单一消除锦标赛表

pmg*_*ace 2 php html-table

我已经浏览了几个与此类似的帖子,但找不到任何适合我正在寻找的内容......

我已经成功地编写了一个8队比赛括号表的硬编码,但我真的想要一种方法,根据输入的球队数量,使用for/if语句绘制表格.

这里是使用colspans和rowspans来硬编码表的代码来创建空格(在你说使用CSS代替表之前,我不太了解CSS,但对表有信心):

<table border='1' cellspacing='1' cellpadding='1'>
<tr><td colspan='2' width='120'><b>Round 1</b></td></td><td colspan='2' width='120'><b>Round 2</b></td></td><td colspan='2' width='120'><b>Final</b></td><td width='120'><b>Winner</b></td></tr>
<tr><td colspan='2'>&nbsp;</td><td colspan='2' rowspan='2'></td><td colspan='2' rowspan='4'></td><td rowspan='8'></td></tr>
<tr><td>Group 1</td><td width='20'></td></tr>
<tr><td align='center'>Score 1</td><td></td><td>Round 1 Winner</td><td width='20'></td></tr>
<tr><td>Group 2</td><td></td><td rowspan='3' align='center'>Score 5</td><td></td></tr>
<tr><td colspan='2'></td><td></td><td>Round 2 Winner</td><td width='20'></td></tr>
<tr><td>Group 3</td><td></td><td></td><td rowspan='7' align='center'>Score 7</td><td></td></tr>
<tr><td align='center'>Score 2</td><td></td><td>Round 1 Winner<td></td><td></td></tr>
<tr><td>Group 4</td><td></td><td colspan='2' rowspan='3'></td><td></td></tr>
<tr><td colspan='2'></td><td></td><td>Champion</td></tr>
<tr><td>Group 5</td><td></td><td></td><td rowspan='8'></td></tr>
<tr><td align='center'>Score 3</td><td></td><td>Round 1 Winner</td><td></td><td></td></tr>
<tr><td>Group 6</td><td></td><td rowspan='3' align='center'>Score 6</td><td></td><td></td></tr>
<tr><td colspan='2'></td><td></td><td>Round 2 Winner</td><td></td></tr>
<tr><td>Group 7</td><td></td><td></td><td colspan='2' rowspan='3'></td></tr>
<tr><td align='center'>Score 4</td><td></td><td>Round 1 Winner</td><td></td></tr>
<tr><td>Group 8</td><td></td><td colspan='2'></td></tr>
</table>
Run Code Online (Sandbox Code Playgroud)

这就是它产生的:

此搜索

到目前为止,我的尝试是使用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."'>&nbsp;</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>";
?>
Run Code Online (Sandbox Code Playgroud)

以下是这样的:

镜像2

最终,团队名称,分数和获胜者将从数据库中提取出来,因此一旦我能够正确地构建结构,就需要合并.

我也希望这可以扩展到64个团队,并根据很多团队自动绘制表而不使用手动硬代码表,因为这需要很长时间才能为16,32和64个团队创建表.考虑到多达64支球队的双重淘汰赛,这将使手动编码成为一项庞大的工作!

任何指针或协助将非常感谢!

ric*_*hsu 5

编辑:

好吧,我决定在凌晨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\">&nbsp;</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\">&nbsp;</td>\n";
            }
        }

    }

    echo "\t</tr>\n";

}

echo "</table>\n";

?>
Run Code Online (Sandbox Code Playgroud)

8支队伍

16支队伍

干杯


原文:我没有时间编写脚本,但从数学上讲它应该遵循某种模式.如果你认为球队总是2的力量(所以你总是可以有一个冠军)并且在开始的时候有4行从第一轮开始,所以你有

1| Empty Row
2| Team 1
3|    Score
4| Team 2
Run Code Online (Sandbox Code Playgroud)

然后我们可以在数学上做出以下内容:

我们$round是轮数和$row是行号,并$team在该轮组号(将在位解释).

打印团队是$row = [2^($round-1) + 1] + [2^($round)]*$team为了理解你需要绘制它的公式,但基本上因为团队是2的幂并且你使用4行(2的幂)代表第一轮中的每个"游戏",我们可以连续将事情分解并在数学上解决打印团队的行#.因此,该公式表明,对于$team在轮次中编号的队伍$round将被排$row在队列中.球队的数量总是除以2,因为一半队伍被淘汰.在您的代码中,总轮数总数仅为团队总数的2个对数.接下来的分数会在两队之间发布,因此确定并不算太糟糕.

当然,最大的问题是你需要打印一个表格,在打印出来时需要按行而不是列.最好的方法是有一个目标公式,然后测试你所在的行和列是否满足只需要一个简单函数来测试的公式(当你知道有多少列时,你会知道你知道的列总数)发).

我希望这有助于您实现我正在尝试设置的目标.如果我有时间,我会尝试做些什么.干杯.