我目前正在经历一个伟大的老脑屁并且动态地选择下一轮的获胜者将进行的下一轮“轮次比赛”:
上面的梯子是动态生成的,我想要做的就是找出下一个匹配ID。我目前已将此作为POC,但如果竞争阶梯达到64 /更多,则不可持续:
$ar = [
1 => [
['id' => 1,'name' => 'round1, pair 1'],
['id' => 2,'name' => 'round1, pair 2'],
['id' => 3,'name' => 'round1, pair 3'],
['id' => 4,'name' => 'round1, pair 4'],
],
2 => [
['id' => 5,'name' => 'round2, pair 1'],
['id' => 6,'name' => 'round2, pair 2'],
]
];
$cases = [0, 0, 1, 1, 2, 2];
foreach($ar as $i => $round) {
foreach($round as $_i => $r) {
echo $r['name'] . " & NEXT_MATCH_ID::> " . $ar[($i + 1)][$cases[$_i]]['id'] . "<br /> ";
}
}
例如,是否有更简化的方法可以实现上述没有硬编码变量( $cases
)的内容。
基本上,“匹配/对”的数量将减半,因为梯形图将是:4
- &gt; 2
- &gt; 1
。
上面会生成正确的ID,但它不可扩展或动态;
round1, pair 1 & NEXT_MATCH_ID::> 5
round1, pair 2 & NEXT_MATCH_ID::> 5
round1, pair 3 & NEXT_MATCH_ID::> 6
round1, pair 4 & NEXT_MATCH_ID::> 6
round2, pair 1 & NEXT_MATCH_ID::> ...
round2, pair 2 & NEXT_MATCH_ID::> ...
//......etc etc...
Demo/ Example上述代码(如果需要)。
备注
4, 6, 8, 10, 12, 14, 16, 18....32, 34...64...etc
。1
比赛),因为没有进一步的进展。 (很容易受if($i == count($rounds)) {.... do not continue...
限制。)lastId + 1
。答案 0 :(得分:1)
只是数学
请注意,每一轮都包含pow(2, Rounds - Round + 1)
个团队和pow(2, Rounds - Round)
个匹配项。把它总结为几何级数。
在$round
之前进行的匹配数是geometric progression 2^(rounds-1) + 2^(rounds-2) + ... 2^(rounds - round + 1)
与a=2^(rounds-1)
,r=1/2
,n=round-1
。它的总和是2^(rounds) - 2^(rounds+1-round)
。
所以匹配ID和下一个匹配ID只是三个参数的函数:pairnum
,round
,rounds
。我将其计算结果转换为函数getMatchId
和getNextId
。
示例强>
<?php
// just matchesInPreviousRounds + parnum
function getMatchId($pairnum, $round, $rounds) {
// matchesInPreviousRounds - is a sum of a geometric progression
// 2^(rounds-1) + 2^(rounds-2) + ... 2^(rounds - round + 1)
// with a=2^(rounds-1), r=1/2, n = round-1
// its sum is 2^(rounds) - 2^(rounds+1-round)
$inPreviousRounds = $round > 1 ? (pow(2, $rounds) - pow(2, $rounds + 1 - $round)) : 0;
$id = $inPreviousRounds + $pairnum;
return (int)$id;
}
// next id is last id of a round + half a pairnum.
function getNextId($pairnum, $round, $rounds) {
if($round === $rounds) {
return false;
}
$matchesInThisAndPreviousRounds = pow(2, $rounds) - pow(2, $rounds - $round);
$nextid = $matchesInThisAndPreviousRounds + ceil($pairnum / 2);
return (int)$nextid;
}
$divide = 64; // for 1/64 at the start
$power = round(log($divide) / log(2)); // get 6 for 64
$rounds = (int) $power + 1;
for($round = 1; $round <= $rounds; $round++) {
// every round contains 2^($rounds - $round + 1) of teams
// and has 2^($rounds - $round) of matches
$teamsLeft = pow(2, $rounds - $round + 1);
$pairsLeft = pow(2, $rounds - $round);
for($pairnum = 1; $pairnum <= $pairsLeft; $pairnum++) {
$id = getMatchId($pairnum, $round, $rounds);
$nextid = getNextId($pairnum, $round, $rounds);
echo "Round $round, pair $pairnum, id $id ";
echo "winner goes to " . $nextid ? $nextid : "A BAR" . "\n";
}
}
其结果
Round 1, pair 1, id 1, winner goes to 65
Round 1, pair 2, id 2, winner goes to 65
...
Round 1, pair 62, id 62, winner goes to 95
Round 1, pair 63, id 63, winner goes to 96
Round 1, pair 64, id 64, winner goes to 96
Round 2, pair 1, id 65, winner goes to 97
Round 2, pair 2, id 66, winner goes to 97
...
Round 2, pair 29, id 93, winner goes to 111
Round 2, pair 30, id 94, winner goes to 111
Round 2, pair 31, id 95, winner goes to 112
Round 2, pair 32, id 96, winner goes to 112
Round 3, pair 1, id 97, winner goes to 113
Round 3, pair 2, id 98, winner goes to 113
...
Round 3, pair 13, id 109, winner goes to 119
Round 3, pair 14, id 110, winner goes to 119
Round 3, pair 15, id 111, winner goes to 120
Round 3, pair 16, id 112, winner goes to 120
Round 4, pair 1, id 113, winner goes to 121
Round 4, pair 2, id 114, winner goes to 121
...
Round 4, pair 7, id 119, winner goes to 124
Round 4, pair 8, id 120, winner goes to 124
Round 5, pair 1, id 121, winner goes to 125
Round 5, pair 2, id 122, winner goes to 125
Round 5, pair 3, id 123, winner goes to 126
Round 5, pair 4, id 124, winner goes to 126
Round 6, pair 1, id 125, winner goes to 127
Round 6, pair 2, id 126, winner goes to 127
Round 7, pair 1, id 127, winner goes to A BAR