如何在循环赛中配对?

And*_*'me 3 php arrays combinations for-loop combinatorics

我正在制作一个锦标赛应用程序,其中将有4个,6个或8个玩家相互对战。

它是基于回合的。因此,例如,如果总共有6个玩家,那么将有5个回合,每个回合3对。每个玩家每轮只能出现一次。

我尝试了什么

我一直在使用for循环来获取所需的组合,但是如何将这些对分成几轮以免重复呢?到目前为止,这是我所做的事情(进行每种组合):

<?php
$players = [1,2,3,4,5,6];

for($i = 0; $i < count($players); $i++):
    for($j = 0; $j < $i; $j++):
         $pair1 = $players[$j];
         $pair2 = $players[$i];
         $pairs[] = $pair1.$pair2;          
    endfor;
endfor;
/* Output:
   [
     0 => "12"
     1 => "13"
     2 => "23"
     3 => "14"
     4 => "24"
     5 => "34"
     6 => "15"
     7 => "25"
     8 => "35"
     9 => "45"
     10 => "16"
     11 => "26"
     12 => "36"
     13 => "46"
     14 => "56"
   ]*/
Run Code Online (Sandbox Code Playgroud)

我的问题

是否有任何通用的方式将两对分配成几回合,而玩家却不在同一回合中出现多次?

例

  • 1 第一轮:12,34,56;
  • 2 第二轮:13,25,46 ...

tri*_*cot 5

您可以使用此代码。它基于循环调度算法:

$players = [1,2,3,4,5,6];

$n = count($players);
for ($r = 0; $r < $n - 1; $r++) {
    for ($i = 0; $i < $n / 2; $i++) {
        $rounds[$r][] = [$players[$i], $players[$n-1 - $i]];
    }
    // Perform round-robin shift, keeping first player in its spot:
    $players[] = array_splice($players, 1, 1)[0];
}
// shift once more to put array in its original sequence:
$players[] = array_splice($players, 1, 1)[0];
Run Code Online (Sandbox Code Playgroud)

请注意,这会将对放入子数组。将它们连接为字符串不是一个好主意,因为这只会使再次从它们中提取单个数字变得更加困难。

上面的代码运行后,该数组$rounds为:

[
  [[1,6],[2,5],[3,4]]
  [[1,2],[3,6],[4,5]]
  [[1,3],[4,2],[5,6]]
  [[1,4],[5,3],[6,2]]
  [[1,5],[6,4],[2,3]]
]
Run Code Online (Sandbox Code Playgroud)

循环中发生的循环移位可以这样可视化,其中数组被“折叠”到一半,还可以显示谁与谁配对(在列中):

在此处输入图片说明

玩家1永远不会移动,位于位置2的玩家将从数组中切出,并推入数组的末端,这意味着它将到达位置6。