You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel生成赛季赛程:如何避免球队赛事时间冲突?

修复赛事生成中球队单日多场比赛的问题

原代码的问题在于,每个球队单独遍历其他球队并递增matchDay,完全没有全局统筹赛程——这就导致同一球队会在同一个matchDay被安排多场对决,比如球队1在matchDay1既对阵球队2又对阵球队3。

要解决这个问题,我们需要按照循环赛制的标准编排逻辑来生成赛程,确保每个比赛日(matchDay)里,每支球队最多只会有一场比赛。以下是修改后的实现:

class GenerateSeasonCommand extends Command
{
    protected $signature = 'generate:season';
    protected $description = 'Generate a season with properly scheduled matches (no overlapping games per team per match day)';

    public function handle(): void
    {
        $season = Season::query()->create([
            'name' => $this->ask('What is the name of the season?'),
        ]);

        $seasonGameData = [];
        $teams = Team::all()->toArray();
        $teamCount = count($teams);

        // 处理奇数球队的情况:添加一个虚拟轮空球队(避免某轮有球队无比赛)
        if ($teamCount % 2 !== 0) {
            $teams[] = ['id' => null]; // 虚拟轮空标识
            $teamCount++;
        }

        $totalMatchDays = $teamCount - 1;
        $halfTeamCount = $teamCount / 2;

        for ($matchDay = 1; $matchDay <= $totalMatchDays; $matchDay++) {
            // 每轮生成对阵
            for ($i = 0; $i < $halfTeamCount; $i++) {
                $homeTeam = $teams[$i];
                $awayTeam = $teams[$teamCount - 1 - $i];

                // 跳过轮空的比赛
                if ($homeTeam['id'] === null || $awayTeam['id'] === null) {
                    continue;
                }

                $seasonGameData[] = [
                    'season_id' => $season->id,
                    'home_team_id' => $homeTeam['id'],
                    'away_team_id' => $awayTeam['id'],
                    'game_mode_id' => $this->getRandomGameModeId(),
                    'map_id' => Map::query()->inRandomOrder()->first()->id,
                    'match_day' => $matchDay,
                    'created_at' => now()
                ];
            }

            // 轮转球队列表(除第一个球队外,其他球队循环右移一位)
            $lastTeam = array_pop($teams);
            array_splice($teams, 1, 0, [$lastTeam]);
        }

        SeasonGame::query()->insert($seasonGameData);

        $this->info('Season and matches generated successfully! No overlapping games per team per match day.');
    }

    private function getRandomGameModeId(): int
    {
        // 简化原逻辑,原逻辑等价于:75%概率1-3,25%概率1-4
        return mt_rand(1, 4) === 4 ? mt_rand(1, 4) : mt_rand(1, 3);
    }
}

关键改动说明

  • 全局赛程编排:不再让每个球队单独计算比赛日,而是以轮次为单位,每轮确保所有球队(除轮空队)只打一场
  • 奇数球队处理:添加虚拟轮空球队,避免某轮出现球队无比赛的情况,生成时自动跳过轮空对阵
  • 球队轮转逻辑:每轮结束后,通过轮转球队列表来生成新的对阵组合,确保所有球队两两对决且无重复、无重叠
  • 优化随机查询:将orderByRaw('RAND()')替换为Laravel原生的inRandomOrder(),更符合框架规范

这样生成的赛程中,每支球队在每个matchDay只会有一场比赛,完全避免了赛事重叠的问题。

内容的提问来源于stack exchange,提问作者ash

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 21:13:30