Php 将循环赛1v1扩展为1v1

Php 将循环赛1v1扩展为1v1,php,round-robin,Php,Round Robin,我试图将循环算法从1v1组扩展到1v1组(类似于免费)。我自己做了这个函数来完成日程安排,但是当我试图扩展它时,一些团队重复了。例如,我有16支球队,我希望有5轮,第1队在5轮中出现7次,第2队在5轮中出现3次。我需要他们最多出现5次。我真的不明白我怎么能做到。欢迎任何建议和链接 function make_schedule(array $teams, int $rounds = null, bool $shuffle = true, int $seed = null): array {

我试图将循环算法从1v1组扩展到1v1组(类似于免费)。我自己做了这个函数来完成日程安排,但是当我试图扩展它时,一些团队重复了。例如,我有16支球队,我希望有5轮,第1队在5轮中出现7次,第2队在5轮中出现3次。我需要他们最多出现5次。我真的不明白我怎么能做到。欢迎任何建议和链接

function make_schedule(array $teams, int $rounds = null, bool $shuffle = true, int $seed = null): array
{


    $teamCount = count($teams);


   if($teamCount < 4) {
        return [];
    }
    //Account for odd number of teams by adding a bye
    if($teamCount % 2 === 1) {
        array_push($teams, null);
        $teamCount += 1;
    }
    if($shuffle) {
        //Seed shuffle with random_int for better randomness if seed is null
        srand($seed ?? random_int(PHP_INT_MIN, PHP_INT_MAX));
        shuffle($teams);
    } elseif(!is_null($seed)) {
        //Generate friendly notice that seed is set but shuffle is set to false
        trigger_error('Seed parameter has no effect when shuffle parameter is set to false');
    }
    $quadTeamCount = $teamCount / 4;
    if($rounds === null) {
        $rounds = $teamCount - 1;
    }

    $schedule = [];

    for($round = 1; $round <= $rounds; $round += 1) {
        $matchupPrev = null;

        foreach($teams as $key => $team) {
            if($key >= $quadTeamCount ) {
                break;
            }

            $keyCount = $key + $quadTeamCount;
            $keyCount2 = $key + $quadTeamCount + 1;
            $keyCount3 = $key + $quadTeamCount + 2;


            $team1 = $team;
            $team2 = $teams[$keyCount];
            $team3 = $teams[$keyCount2];
            $team4 = $teams[$keyCount3];


            //echo "<pre>Round #{$round}: {$team1} - {$team2} - {$team3} - {$team4} == KeyCount: {$keyCount} == KeyCount2: {$keyCount2} == KeyCount3: {$keyCount3}</pre>";

            //Home-away swapping
            $matchup = $round % 2 === 0 ? [$team1, $team2, $team3, $team4 ] : [$team2, $team1, $team4, $team3];

            $schedule[$round][] = $matchup ;
        }
        rotate($teams);
    }

    return $schedule;
}
function make_schedule(数组$teams,int$rounds=null,bool$shuffle=true,int$seed=null):数组
{
$teamCount=计数($teams);
如果($teamCount<4){
返回[];
}
//通过添加“再见”来说明奇数个团队
如果($teamCount%2==1){
数组_push($teams,null);
$teamCount+=1;
}
如果($shuffle){
//如果种子为空,则使用random_int进行种子洗牌以获得更好的随机性
srand($seed??random_int(PHP_int_MIN,PHP_int_MAX));
洗牌($团队);
}elseif(!is_null($seed)){
//生成友好通知,种子已设置,但洗牌设置为false
触发器_错误('Seed参数在shuffle参数设置为false时无效”);
}
$quadTeamCount=$teamCount/4;
如果($rounds==null){
$rounds=$teamCount-1;
}
$schedule=[];
对于($round=1;$round$team){
如果($key>=$quadTeamCount){
打破
}
$keyCount=$key+$quadTeamCount;
$keyCount2=$key+quadTeamCount+1;
$keyCount3=$key+quadTeamCount+2;
$team1=$team;
$team2=$teams[$keyCount];
$team3=$teams[$keyCount2];
$team4=$teams[$keyCount3];
//echo“Round{$Round}:{$team1}-{$team2}-{$team3}-{$team4}==KeyCount:{$KeyCount}==KeyCount2:{$KeyCount2}==KeyCount3:{$KeyCount3}”;
   function rotate(array &$items)
{
    $itemCount = count($items);
    if($itemCount < 3) {
        return;
    }
    $lastIndex = $itemCount - 1;
    /**
     * Though not technically part of the round-robin algorithm, odd-even 
     * factor differentiation included to have intuitive behavior for arrays 
     * with an odd number of elements
     */
    $factor = (int) ($itemCount % 2 === 0 ? $itemCount / 2 : ($itemCount / 2) + 1);
    $topRightIndex = $factor - 1;
    $topRightItem = $items[$topRightIndex];
    $bottomLeftIndex = $factor;
    $bottomLeftItem = $items[$bottomLeftIndex];
    for($i = $topRightIndex; $i > 0; $i -= 1) {
        $items[$i] = $items[$i - 1];
    }
    for($i = $bottomLeftIndex; $i < $lastIndex; $i += 1) {
        $items[$i] = $items[$i + 1];
    }
    $items[1] = $bottomLeftItem;
    $items[$lastIndex] = $topRightItem;
}
//客场交换 $matchup=$round%2===0?[$team1,$team2,$team3,$team4]:[$team2,$team1,$team4,$team3]; $schedule[$round][]=$matchup; } 轮换(小组); } 返回$schedule; }
旋转功能:

abcd
bcde
cdef
defg
函数旋转(数组和$items)
{
$itemCount=计数($items);
如果($itemCount<3){
返回;
}
$lastIndex=$itemCount-1;
/**
*虽然技术上不是循环算法的一部分,但奇偶
*包括因子微分,使阵列具有直观的行为
*具有奇数个元素
*/
$factor=(int)($itemCount%2===0?$itemCount/2:($itemCount/2)+1);
$topRightIndex=$factor-1;
$topRightItem=$items[$topRightIndex];
$bottomLeftIndex=$factor;
$bottomLeftItem=$items[$bottomLeftIndex];
对于($i=$topRightIndex;$i>0;$i-=1){
$items[$i]=$items[$i-1];
}
对于($i=$bottomLeftIndex;$i<$lastIndex;$i+=1){
$items[$i]=$items[$i+1];
}
$items[1]=$bottomLeftItem;
$items[$lastIndex]=$topRightItem;
}
例如:

如果我把回合数设为5,每个队打5场比赛。

处理第五轮:

好吧,在我想了一会儿之后,也许没有一种方法可以让他们不重复打球,但是如果打法降低到最小,就像每支球队应该只打5次一样——这意味着每轮一次。这就是我的意思。我在“他们重复”一词中的意思是,有16支球队,5轮,有些球队在所有这些轮中都会重复7次,而其他球队在这5轮中会重复3次。我想避免这种情况,让每支球队最多打5轮。

你的
foreach()
与其他3支球队的选择是错误的。其中一个步骤必须是
4的倍数
。如果不选择,则将在开始时选择多个团队,并且根本不选择阵列末尾的团队。这将导致像这样的错误团队匹配(团队在这里是字母):

然后你的<代码>中断点击

相反,它应该是这样的:

abcd
efgh
ijkl
mnop
此算法将团队列表分为四组:

adei|klnf|gjmc|pobh
请记住,根据下一轮
$团队
阵型的洗牌情况,您可能会遇到两次相同的对手


在这里,
ad
kl
op
团队将再次面对。

我不清楚。循环赛意味着每个队至少与其他队比赛一次。16支队伍最多只能出现5次?请用您的预期输出更新您的问题。@fubar用屏幕截图更新。请编辑您的问题,以包括关于团队应如何相互匹配的说明。
5
总匹配有什么特别之处?当你有超过
5场比赛时,你想如何处理重复对手?@Progman补充了一些解释,如果需要更多,我将以评论的形式写下。我以这5轮为例。就像,每个队都必须打n个回合。如果我设置了7轮,每个队必须打7次。请编辑您的问题以包含
rotate()
函数的源代码。此外,看起来这段代码是针对1v1匹配的,但是您应该添加您的代码(或尝试)以用于1v1匹配,它生成的示例输出以及您在生成的输出中遇到的问题。再次面对这些问题是可以的。这个解决方案真的很可靠,谢谢你的耐心,不过,我想我想到了一个改进这个的方法。如果我成功了,我将在稍后分享一个答案。再次感谢你。祝您有个美好的一天!
abcd|efgh|ijkl|mnop
adei|klnf|gjmc|pobh