PHP单淘汰赛桌 [英] PHP Single Elimination Tournament Table

查看:70
本文介绍了PHP单淘汰赛桌的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看过其他几篇与此类似的文章,但找不到适合我所要寻找的内容...

I've looked through several other posts similar to this but can't find anything that suits what I'm looking for...

我已经成功地为8支球队锦标赛中的括号表进行了硬编码,但我确实希望有一种方法可以根据输入的球队数使用for/if语句来草拟该表.

I've managed to hard code an 8 team tournament brackets table but I really want a way for the table to be drawn up using for/if statements based on the number of teams that are inputted.

以下是使用colspans和rowspans硬编码表格以创建空格的代码(在您说用CSS代替表格之前,我不太了解CSS,但对表格充满信心):

Here's the code for hard coding the table using colspans and rowspans to create the blank spaces (and before you say use CSS instead of tables, I don't know CSS that well but am confident with tables):

<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>

这是它产生的东西:

到目前为止,这是我尝试使用for和if语句创建上面的内容的时候,我已经说过了,它在第一列中列出了团队名称,但是我无法确定我该怎么做点...

And here's my attempt so far to create the above using for and if statements, I've got to the point where it lists the team names in the first column but I can't work out what I need to do from this point...

<?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>";
?>

这是下面的样子:

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

Ultimately the team names, scores and winners will be pulled from a DB so will need to incorporate that once I can get the structure laid out correctly.

我还希望它可以扩展到64个团队,并基于许多团队自动绘制表格,而无需使用手动的硬代码表,因为创建16、32和64个团队的表格需要花费很多时间.再加上考虑淘汰多达64个团队,这将使手动编码成为一项艰巨的工作!

I'd also like this to be scalable to 64 teams and to automatically draw the table based on that many teams without using manually hard code tables as this will takes ages to create tables for 16,32 and 64 teams. Coupled with considering double elimination for up to 64 teams which will make manually coding this a massive job!

任何对此的指点或帮助,将不胜感激!

Any pointers or assistance with this would be massively appreciated!

推荐答案

好的,我决定在凌晨2点之前解决这个问题.大约花了半个小时进行调试.我知道我没有更多的跨度,但我不想再花时间尝试做那件事,因为它需要更多地调整数学公式来正确地获得它们.屏幕截图如下.让我知道您是否需要任何解释.

Alright I decided to tackle this problem a little before 2AM in the morning. Took roughly half an hour to debug. I know I don't have more spanning but I don't want to spend anymore time trying to do that as it's more tweaking of the mathematical formulas to get those correctly. Screenshots follow. Let me know if you need explanation on anything.

<?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";

?>

欢呼

原件: 我没有时间编写脚本,但是从数学上来说,它应该可以遵循某种模式.如果您假设两队的力量始终是2(因此您总会有冠军),并且从第一轮开始就排4行,那么您就有了

Original: I don't have time to write up a script but mathematically speaking it should work to follow some sort of pattern. If you assume the teams are always a power of 2 (so you can always have a champion) and 4 rows in the beginning to start off the first round so you have

1| Empty Row
2| Team 1
3|    Score
4| Team 2

然后我们可以在数学上进行以下操作:

Then we can mathematically make the following:

$round为回合编号,$row为行号,$team为回合中的团队编号(将稍作解释).

Let $round be the round number and $row be the row number and $team be the team number in the round (will explain in a bit).

团队要打印在$row = [2^($round-1) + 1] + [2^($round)]*$team上以了解该公式,您需要将其绘制出来,但是基本上,因为团队是2的幂,并且您使用4行(2的幂)来表示在第一轮中,我们可以继续分解内容,并在数学上求解打印团队的行#.因此,该公式指出,对于在$round轮中编号为$team的团队,将在行$row中列出.由于淘汰了一半的团队,因此团队的数量总是除以2.正如您在代码中所做的那样,总回合数只是团队总数的基数2日志.接下来的分数会在两队之间发布,因此确定起来并不难.

Teams are printed on $row = [2^($round-1) + 1] + [2^($round)]*$team to understand this formula you'll need to draw it out, but basically because the teams are powers of 2 and you use 4 rows (power of 2) to represent each "game" in the first round, we can continuously split things down and mathematically solve for the row # where teams are printed. So the formula states that for team numbered $team in round $round will be listed in row $row The number of teams is always divided by 2 since half the teams are eliminated. Total number of rounds is just base 2 log of total teams as you've done in your code. Next scores are posted in between ever pair of teams so that isn't too bad to determine.

当然,最大的问题是您需要打印一张表,在打印时需要逐行而不是按列.最好的方法是有一个目标公式,然后测试您所在的行和列是否满足方程式,而方程式只需要一个简单的函数即可进行测试(因为生成的列总数是已知的,因为您知道有多少列回合).

The biggest issue of course is the fact that you need to print a table which requires going by row rather than column when printing it out. The best way is to have a target formula and you test whether the row and column you are at satisfies the equation which just requires a simple function to test (as you go across generating the total number of columns which you know since you know how many rounds).

我希望这可以帮助您达到我正在尝试设定的目标.如果有时间的话,我会稍后再尝试做一些事情.干杯.

I hope this helps lead you to the goal that I am trying to setup. I will try to make something later if I get the time. Cheers.

这篇关于PHP单淘汰赛桌的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆