VB.NET 中英超风格足球锦标赛的循环调度算法

问题描述 投票:0回答:1

我正在 VB.NET 中创建一个基本的、非常简单的足球经理游戏。游戏在控制台窗口上运行。我已经打好了所有的基础,现在我需要随机安排锦标赛中的 20 支俱乐部进行一场客场比赛,每个俱乐部总共 38 场比赛。然而,我一生都无法把它做好。我花了三天时间研究调度算法,想知道是否有人可以帮助我。

算法应该这样做:

  • 将进行38轮
  • 每轮将有10场比赛
  • 每个俱乐部每轮比赛一次,无论是主场还是客场。
  • 每家具乐部总共将进行 19 场主场比赛和 19 场客场比赛,总计 38 场比赛。俱乐部之间只能在主场和客场比赛各一场。

这是我迄今为止所做的,这是错误的并且未能实现我的目标:

  Sub CreateFixtures()
    Randomize()
    Dim totalRounds = (ClubList.Count - 1) 
    Dim matchID As Integer = 0
    Dim rnd As New Random()

    For round = 1 To 38
        Debug.WriteLine($"Round {round}")
        Dim availableTeams = New List(Of ClubClass)(ClubList)

        While availableTeams.Count > 1 ' Ensure there are at least 2 teams left
            Dim homeTeamIndex = rnd.Next(0, availableTeams.Count)
            Dim homeTeam = availableTeams(homeTeamIndex)

            ' Remove homeTeam from available teams to prevent it from playing against itself
            availableTeams.RemoveAt(homeTeamIndex)

            ' Select a random away team that hasn't already played against the home team
            Dim availableAwayTeams = availableTeams.Where(Function(team) Not homeTeam.HasPlayedAgainst(team)).ToList()

            If availableAwayTeams.Count > 0 Then
                Dim awayTeamIndex = rnd.Next(0, availableAwayTeams.Count)
                Dim awayTeam = availableAwayTeams(awayTeamIndex)

                CreateMatch(matchID, homeTeam, awayTeam, round)
                availableTeams.Remove(awayTeam)
                Debug.WriteLine($"{homeTeam.name} vs {awayTeam.name}")
                matchID += 1
            End If
        End While
    Next
End Sub
vb.net round-robin tournament sports-league-scheduling-problem
1个回答
0
投票

您的算法似乎无法系统地确保每支球队在整个赛季中在主场和客场只比赛一次。

从“循环赛”中,您可以尝试“循环法”进行循环赛安排:其想法是固定一个团队(通常是第一个团队)并围绕它轮换其他团队。

Round 1          Round 2          Round 3         ...
1 vs 20          1 vs 19          1 vs 18         ...
2 vs 19          20 vs 18         19 vs 17        ...
3 vs 18          2 vs 17          20 vs 16        ...
...                                               ...
19 vs 2          4 vs 20          3 vs 19         ...
20 vs 1          3 vs 2           2 vs 20         ...

这将是确保每支球队在赛季上半段与其他球队只交手一次的一种方法。然后,您将在赛季后半程重复此过程,切换主客场球队。

Sub CreateFixtures(clubs As List(Of String))
    Dim totalClubs As Integer = clubs.Count
    Dim totalRounds As Integer = (totalClubs - 1) * 2 ' Each team plays 38 rounds
    Dim matchesPerRound As Integer = totalClubs / 2

    ' Generate the first half of the season
    For round As Integer = 1 To totalClubs - 1
        Debug.WriteLine($"Round {round}")
        For match As Integer = 0 To matchesPerRound - 1
            Dim homeTeamIndex As Integer = (round + match) Mod (totalClubs - 1)
            Dim awayTeamIndex As Integer = (totalClubs - 1 - match + round) Mod (totalClubs - 1)

            ' Adjust indices to skip the fixed team
            If match = 0 Then
                awayTeamIndex = totalClubs - 1
            End If

            Dim homeTeam As String = clubs(homeTeamIndex)
            Dim awayTeam As String = clubs(awayTeamIndex)

            Debug.WriteLine($"{homeTeam} vs {awayTeam}")
        Next
    Next

    ' Repeat the process for the second half of the season, switching home and away
    For round As Integer = totalClubs To totalRounds - 1
        Debug.WriteLine($"Round {round}")
        For match As Integer = 0 To matchesPerRound - 1
            Dim homeTeamIndex As Integer = (round + match) Mod (totalClubs - 1)
            Dim awayTeamIndex As Integer = (totalClubs - 1 - match + round) Mod (totalClubs - 1)

            ' Adjust indices to skip the fixed team
            If match = 0 Then
                homeTeamIndex = totalClubs - 1
            End If

            Dim homeTeam As String = clubs(awayTeamIndex) ' Switch home and away
            Dim awayTeam As String = clubs(homeTeamIndex)

            Debug.WriteLine($"{homeTeam} vs {awayTeam}")
        Next
    Next
End Sub

您可以致电

CreateFixtures
并提供俱乐部名称列表。

© www.soinside.com 2019 - 2024. All rights reserved.