我正在尝试创建一些逻辑来生成双淘汰锦标赛括号中的事件时间表。
这是一个示例 8 队括号:
rd1 quarter semi finals
A───┐
0 ├───────A┐
B───┘ │
4 ├────────A┐
C───┐ │ │
1 ├───────C┘ │
D───┘ │
10 ├──────A┐
E───┐ │ │
2 ├───────E┐ │ │
F───┘ │ │ │
5 ├────────E┘ │
G───┐ │ 13 ├───= Champ
3 ├───────G┘ │
H───┘ │
E────┐ │
C───┐ │ │
B───┐ 8 ├────C┐ 12 ├────E┘
6 ├B───┘ │ │
D───┘ 11 ├C────┘
G───┐ │
F───┐ 9 ├────G┘
7 ├F───┘
H───┘
这些数字代表匹配数组中的索引,这是所需的输出。例如,索引 0 将代表团队 1 与团队 8(使用种子系统),索引 4 将代表索引 0 的获胜者与索引 1 的获胜者。
失败者的括号由获胜者括号的失败者填充,其中索引 6 是索引 0 的失败者与索引 1 的失败者,索引 8 是索引 4 的失败者与索引 6 的获胜者。
在视觉示例中,您可以看到用字母标记的团队,并清楚地显示获胜团队每次都在顶部分支,而失败团队在底部分支的清晰示例。指数 0 代表 A 队对 B,指数 4 代表指数 0 (A) 的获胜者对指数 1 (C) 的获胜者。指数 6 是指数 0 (B) 的输家与指数 1 (D) 的输家,指数 8 是指数 4 (C) 的输家与指数 6 (B) 的赢家
出现了一个明显的模式,但是当我尝试适应不同数量的竞争对手时,我的逻辑变得混乱和混乱。为简单起见,我将支架固定为只有 2 个团队的幂。我能够编写所有内容来为 8 队括号创建一系列匹配项,但我什至对自己的代码也失去了理解,因为它似乎不可扩展。
// round one
for( $i = 0; $i < log( count( $competitors ), 2 ); $i++ )
{
$seeded = array( );
foreach( $competitors as $competitor )
{
$splice = pow( 2, $i );
$seeded = array_merge( $seeded, array_splice( $competitors, 0, $splice ) );
$seeded = array_merge( $seeded, array_splice( $competitors, -$splice ) );
}
$competitors = $seeded;
}
$events = array_chunk( $seeded, 2 );
// quarter finals
for( $i = 0; $i < count( $competitors ) / 2; $i++ )
{
array_push( $events, array(
array( 'from_event_index' => $i, 'from_event_rank' => 1 ), // rank 1 = winner
array( 'from_event_index' => ++$i, 'from_event_rank' => 1 )
) );
}
$round_matchups = array( );
for( $i = 0; $i < count( $competitors ) / 2; $i++ )
{
array_push( $round_matchups, array(
array( 'from_event_index' => $i, 'from_event_rank' => 2 ), // rank 2 = loser
array( 'from_event_index' => ++$i, 'from_event_rank' => 2 )
) );
}
$events = array_merge( $events, $round_matchups );
for( $i = 0; $i < count( $round_matchups ); $i++ )
{
array_push( $events, array(
array( 'from_event_index' => $i + count( $competitors ) / 2, 'from_event_rank' => 2 ),
array( 'from_event_index' => $i + count( $competitors ) / 2 + count( $competitors ) / 2 / 2, 'from_event_rank' => 1 )
) );
}
// semi finals
for( $i = 0; $i < count( $competitors ) / 2 / 2; $i++ )
{
array_push( $events, array(
array( 'from_event_index' => $i + count( $competitors ) / 2, 'from_event_rank' => 1 ),
array( 'from_event_index' => ++$i + count( $competitors ) / 2, 'from_event_rank' => 1 )
) );
}
$round_matchups = array( );
for( $i = 0; $i < count( $competitors ) / 2 / 2; $i++ )
{
array_push( $round_matchups, array(
array( 'from_event_index' => $i + count( $competitors ), 'from_event_rank' => 1 ),
array( 'from_event_index' => ++$i + count( $competitors ), 'from_event_rank' => 1 )
) );
}
$events = array_merge( $events, $round_matchups );
for( $i = 0; $i < count( $round_matchups ); $i++ )
{
array_push( $events, array(
array( 'from_event_index' => $i + count( $competitors ) + count( $competitors ) / 2 - 2, 'from_event_rank' => 2 ),
array( 'from_event_index' => $i + count( $competitors ) + count( $competitors ) / 2 - 1, 'from_event_rank' => 1 )
) );
}
// finals
for( $i = 0; $i < count( $competitors ) / 2 / 2 / 2; $i++ )
{
array_push( $events, array(
array( 'from_event_index' => $i + count( $competitors ) / 2 * 3 - 2, 'from_event_rank' => 1 ),
array( 'from_event_index' => ++$i + count( $competitors ) / 2 * 3 - 1, 'from_event_rank' => 1 )
) );
}
上面代码的输出:
$events = array(14) {
[0]=>
array(2) {
[0]=>
array(4) {
["team"]=>int(1)
}
[1]=>
array(4) {
["team"]=>int(8)
}
}
[1]=>
array(2) {
[0]=>
array(4) {
["team"]=>int(4)
}
[1]=>
array(4) {
["team"]=>int(5)
}
}
[2]=>
array(2) {
[0]=>
array(4) {
["team"]=>int(2)
}
[1]=>
array(4) {
["team"]=>int(7)
}
}
[3]=>
array(2) {
[0]=>
array(4) {
["team"]=>int(3)
}
[1]=>
array(4) {
["team"]=>int(6)
}
}
[4]=>
array(2) {
[0]=>
array(2) {
["from_event_index"]=>int(0)
["from_event_rank"]=>int(1)
}
[1]=>
array(2) {
["from_event_index"]=>int(1)
["from_event_rank"]=>int(1)
}
}
[5]=>
array(2) {
[0]=>
array(2) {
["from_event_index"]=>int(2)
["from_event_rank"]=>int(1)
}
[1]=>
array(2) {
["from_event_index"]=>int(3)
["from_event_rank"]=>int(1)
}
}
[6]=>
array(2) {
[0]=>
array(2) {
["from_event_index"]=>int(0)
["from_event_rank"]=>int(2)
}
[1]=>
array(2) {
["from_event_index"]=>int(1)
["from_event_rank"]=>int(2)
}
}
[7]=>
array(2) {
[0]=>
array(2) {
["from_event_index"]=>int(2)
["from_event_rank"]=>int(2)
}
[1]=>
array(2) {
["from_event_index"]=>int(3)
["from_event_rank"]=>int(2)
}
}
[8]=>
array(2) {
[0]=>
array(2) {
["from_event_index"]=>int(4)
["from_event_rank"]=>int(2)
}
[1]=>
array(2) {
["from_event_index"]=>int(6)
["from_event_rank"]=>int(1)
}
}
[9]=>
array(2) {
[0]=>
array(2) {
["from_event_index"]=>int(5)
["from_event_rank"]=>int(2)
}
[1]=>
array(2) {
["from_event_index"]=>int(7)
["from_event_rank"]=>int(1)
}
}
[10]=>
array(2) {
[0]=>
array(2) {
["from_event_index"]=>int(4)
["from_event_rank"]=>int(1)
}
[1]=>
array(2) {
["from_event_index"]=>int(5)
["from_event_rank"]=>int(1)
}
}
[11]=>
array(2) {
[0]=>
array(2) {
["from_event_index"]=>int(8)
["from_event_rank"]=>int(1)
}
[1]=>
array(2) {
["from_event_index"]=>int(9)
["from_event_rank"]=>int(1)
}
}
[12]=>
array(2) {
[0]=>
array(2) {
["from_event_index"]=>int(10)
["from_event_rank"]=>int(2)
}
[1]=>
array(2) {
["from_event_index"]=>int(11)
["from_event_rank"]=>int(1)
}
}
[13]=>
array(2) {
[0]=>
array(2) {
["from_event_index"]=>int(10)
["from_event_rank"]=>int(1)
}
[1]=>
array(2) {
["from_event_index"]=>int(12)
["from_event_rank"]=>int(1)
}
}
}
关于如何修改它以适用于 4 队、16 队或 2^n 队支架的任何想法?我觉得“半决赛”标题下的逻辑是应该重复 0+ 次,但每次我尝试根据总轮数循环它时,它只是重复与上一轮相同的匹配。