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
相关产品推荐
相关产品推荐

