[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

VB.NET : Creating a Match / Tournament Draw (Soccer)

Posted on 2005-05-02
13
Medium Priority
?
1,747 Views
Last Modified: 2014-07-06
Hi All,

Anyone got any tips or tricks on how I would go about creating a match draw through VB.NET

Ideally what i'd like is for the user to select a grade and division, then select the teams, in which their home grounds will be linked to them (and the number of fields available on the ground via the db) and then the program creates the draw.

For example, let's say: Grade 12 Division 2, has 10 teams. 18 rounds is the season. Each team will verse each other twice (as a team cant verse itself so that equates to 18 matches/rounds). How would the program create this. Also one thing to take note is that if there's 9 teams in the 10 team competition, the program will automatically throw in a BYE round, so like the number of teams in the division needs to be even to eliminate the BYE round.

It sounds pretty complex i know and the way i'm explaining it aint top notch (the idea's still scratchy in my head) but if anyone can give us a hand it'll be greatly appreciated.

Code samples will be a dream come true.

Thanks heaps

Ray.
0
Comment
Question by:RayFrangie
  • 4
  • 3
  • 2
  • +2
12 Comments
 
LVL 2

Expert Comment

by:curlypinhead
ID: 13911550
It would take me a long time to write out complete code so to begin with...
you would have 2 dropdownlists (gradDDL and divisionDDL).  When someone selects both of these, then clicks a button, you would:
1.  lookup the number of teams in the database based on the gradeDDL and divisionDDL.


  dim numTeams as Integer = sqlQuery("numTeams")
  dim numWeeks as Integer = (numTeams - 1)
  dim thisWeek as Integer
  dim i as Integer
  dim j as Integer
  dim found as Integer
  dim teamAssigned[numWeeks][numTeams] as Integer


initialize array to ""
for thisWeek = 1 to numWeeks
  for i = 1 to numTeams
        teamAssigned[numWeeks][numTeams] = ""
  next
next

for thisWeek = 1 to numWeeks
  for i = 1 to numTeams
    'check to see if this team was already assigned for this week
    if teamAssigned[thisWeek][i] = "" then
      for j = 1 to numTeams
        if i <> j then
          'check to see if these teams have been matched in this or previous weeks
          found = 0
            for(weekFind = 1; weekFind <= thisWeek; weekFind++)
              if teamAssigned[weekFind][i] = j
                found = 1
              end if
            next
                          
            'if they haven't been matched, match these teams.
            if found = 0 then
              teamAssigned[thisWeek][i] = j
              teamAssigned[thisWeek][j] = i
              exit for
            end if
         end if
       next
     end if
   next
next

'set up byes
for thisWeek = 1 to numWeeks
  for i = 1 to numTeams
    if teamAssigned[numWeeks][numTeams] = "" then
      '0 will imply that the team has a bye
      teamAssigned[numWeeks][numTeams] = 0
    end if
  next
next


At this point the teamAssigned array will have the assignments for the first half of the season.  Duplicate this for the second half and you should be ok.  This may not be the optimal solution (not random and maybe slow) but I think it will work.  Try it out.

curlypinhead
0
 
LVL 10

Expert Comment

by:heintalus
ID: 13911756
How good is your C#, I've created an example project to create round robin draws which I'm eventually going to use for our Hockey club, which I could send you.
0
 
LVL 4

Expert Comment

by:mortar
ID: 13913589
hi heintalus, i'm trying to make a similiar program for volleyball.. Any chance you could send that to me?
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 10

Expert Comment

by:heintalus
ID: 13913729
Hi mortar

Flick me an email to andybonner@lycos.com as I have no idea of how to find your email address & i'll send it onto you.  It's just a very simple app showing how to generate round robin draws.  I couldn't find any examples on the web so I had to come up with something myself which I think works quite well.

regards
Andy
0
 
LVL 1

Author Comment

by:RayFrangie
ID: 13914641
heintalus,

Please send it to me at techsupport@rcsystems.com.au

I've got a converter that converts from C# to VB.NET

I'll give that a shot and see how it goes...



curlypinhead:

Thanks for the code, but i'd like something that will randomise the team.
0
 
LVL 4

Expert Comment

by:mortar
ID: 13914658
Hi Ray.. if you successfully convert that code can you please e-mail it to me, swapping _-_AT_-_ for the @ symbol.  Just trying to avoid spam!!

mortar_-_AT_-_ash-tech.net

Thanks!!
0
 
LVL 1

Author Comment

by:RayFrangie
ID: 13914675
Will Do Mortar,

Just waiting for the code to arrive in my inbox at the moment :)

Thanks and Regards,

Ray.
0
 
LVL 10

Expert Comment

by:heintalus
ID: 13914803
OK guys, you should all have received the C# example, I'll try to put together a vb.net example tonight, time permitting, just in case the converters don't work.  I used them myself in the past before I jumped in & learnt C# so I know how quirky they are 8)

Andy
0
 
LVL 2

Expert Comment

by:curlypinhead
ID: 13920486
Hey all,

I looked at heintalus' program.  It is really good!  I tried to randomize the outcomes and this is what I got...

private void GenerateCombinations()
{
      Draws.Clear();
      rtbCombinations.Clear();
      rtbDraws.Clear();

      string[] s = new string[] {"A","B","C","D","E","F","G","Bye"};
      ArrayList Teams = new ArrayList(s);
      ArrayList Teams2 = new ArrayList(Teams.ToArray());

      for (int i = 0; i < Teams.Count-1; i++)
      {
            Teams2.RemoveAt(0);

            for (int j = 0; j < Teams2.Count; j++)
            {
                  rtbCombinations.AppendText(Teams[i]+" vs "+Teams2[j]+"\r\n");
                  Draws.Add(new Draw(Teams[i].ToString(),Teams2[j].ToString()));
            }
      }
}

private void GenerateDraws()
{
      int matches = 7; //should be (Teams.Count - 1)
      DrawCollection dc;

      for (int i = 0; i < matches; i++)
      {
            int round = i+1;
            rtbDraws.AppendText("Round "+round.ToString()+"\r\n");
            dc = new DrawCollection(Draws);
            
            Random rndNum = new Random( );
            do
            {
                  //Wait to allow the timer to advance.
                  Thread.Sleep(20);
                  int randomMatch = (int)(Math.Floor(rndNum.NextDouble()*(dc.Count - 1)));
                  rtbDraws.AppendText(dc[randomMatch].Match+",");
                  Draws.Remove(dc[randomMatch]);
                  dc.RemoveDraws(dc[randomMatch]);

                  Application.DoEvents();
            }
            while (dc.Count > 0);

            rtbDraws.AppendText("\r\n");
      }
}

I changed the GenerateCombinations function so it resets the Draw collection and the RichTextBoxs.  In the GenerateDraws funciton I used a random number to select the next draw.

This code is a bit quirky.  Sometimes it doesn't select four matches for a week (it might select 2 or 3 instead).  This is because a match can get selected that will make it impossible to select another distinct match.

To get around this, just try again.  Every four or five times a set will come up with four matches every week.

Hope it helps.

curlypinhead
0
 
LVL 10

Accepted Solution

by:
heintalus earned 2000 total points
ID: 13921786
OK Guys, I've emailed off a VB.Net example but I've since modified it to the following which will randomize the teams

Code for Draw

Imports System.Reflection

'/ <summary>
'/ Holds details of a draw instance.
'/ </summary>
<DefaultMember("Match")> _
Public Class Draw

    Private m_strMatch As String
    Private m_strTeam2 As String
    Private m_strTeam1 As String

    '/ <summary>
    '/     Create new instance of a draw
    '/ </summary>
    '/ <param name="T1" type="string">
    '/     <para>
    '/         First teams name
    '/     </para>
    '/ </param>
    '/ <param name="T2" type="string">
    '/     <para>
    '/         Second teams name
    '/     </para>
    '/ </param>
    '/ <returns>
    '/     A void Draw value...
    '/ </returns>
    Public Sub New(ByVal T1 As String, ByVal T2 As String)
        m_strTeam1 = T1
        m_strTeam2 = T2
        m_strMatch = T1 + " VS " + T2
    End Sub

    Public ReadOnly Property Team1() As String
        Get
            Return m_strTeam1
        End Get
    End Property

    Public ReadOnly Property Team2() As String
        Get
            Return m_strTeam2
        End Get
    End Property

    Public ReadOnly Property Match() As String
        Get
            Return m_strMatch
        End Get
    End Property

End Class

Code for DrawCollection

''' <summary>
'''     A collection that stores 'Draw' objects.
''' </summary>
Public Class DrawCollection
    Inherits System.Collections.CollectionBase

    ''' <summary>
    '''     Initializes a new instance of 'DrawCollection'.
    ''' </summary>
    Public Sub New()
        MyBase.New()
    End Sub

    ''' <summary>
    '''     Initializes a new instance of 'DrawCollection' based on an already existing instance.
    ''' </summary>
    Public Sub New(ByVal draValue As DrawCollection)
        MyBase.New()
        Me.AddRange(draValue)
    End Sub

    ''' <summary>
    '''     Adds the contents of another 'DrawCollection' at the end of this instance.
    ''' </summary>
    Public Overloads Sub AddRange(ByVal draValue As DrawCollection)
        Dim intCounter As Integer = 0
        Do While (intCounter < draValue.Count)
            Me.Add(draValue(intCounter))
            intCounter = intCounter + 1
        Loop
    End Sub

    ''' <summary>
    '''     Initializes a new instance of 'DrawCollection' with an array of 'Draw' objects.
    ''' </summary>
    Public Sub New(ByVal draValue() As Draw)
        MyBase.New()
        Me.AddRange(draValue)
    End Sub

    ''' <summary>
    '''     Copies the elements of an array at the end of this instance of 'DrawCollection'.
    ''' </summary>
    Public Overloads Sub AddRange(ByVal draValue() As Draw)
        Dim intCounter As Integer = 0
        Do While (intCounter < draValue.Length)
            Me.Add(draValue(intCounter))
            intCounter = intCounter + 1
        Loop
    End Sub

    ''' <summary>
    '''     Represents the 'Draw' item at the specified index position.
    ''' </summary>
    Default Public Property Item(ByVal intIndex As Integer) As Draw
        Get
            Return CType(List(intIndex), Draw)
        End Get
        Set(ByVal draValue As Draw)
            List(intIndex) = draValue
        End Set
    End Property

    ''' <summary>
    '''     Adds a 'Draw' item with the specified value to the 'DrawCollection' collection.
    ''' </summary>
    Public Function Add(ByVal draValue As Draw) As Integer
        Return List.Add(draValue)
    End Function

    ''' <summary>
    '''     Gets a value indicating whether the 'DrawCollection' contains the specified value.
    ''' </summary>
    Public Function Contains(ByVal draValue As Draw) As Boolean
        Return List.Contains(draValue)
    End Function

    ''' <summary>
    '''     Copies the 'DrawCollection' values to a one-dimensional System.Array
    '''     instance starting at the specified array index.
    ''' </summary>
    Public Sub CopyTo(ByVal draArray() As Draw, ByVal intIndex As Integer)
        List.CopyTo(draArray, intIndex)
    End Sub

    ''' <summary>
    '''     Returns the index of a 'Draw' object in the collection.
    ''' </summary>
    Public Function IndexOf(ByVal draValue As Draw) As Integer
        Return List.IndexOf(draValue)
    End Function

    ''' <summary>
    '''     Inserts an existing 'Draw' into the collection at the specified index.
    ''' </summary>
    Public Sub Insert(ByVal intIndex As Integer, ByVal draValue As Draw)
        List.Insert(intIndex, draValue)
    End Sub

    ''' <summary>
    '''     Removes a specific item from the 'DrawCollection'.
    ''' </summary>
    Public Sub Remove(ByVal draValue As Draw)
        List.Remove(draValue)
    End Sub

    ''' <summary>
    '''     Removes team draws from the 'DrawCollection'.
    ''' </summary>
    Public Sub RemoveDraws(ByVal draValue As Draw)
        Dim Draws As ArrayList = New ArrayList
        Dim d As Draw
        For Each d In List
            If d.Team1 = draValue.Team1 OrElse d.Team1 = draValue.Team2 OrElse d.Team2 = draValue.Team1 OrElse d.Team2 = draValue.Team2 Then
                Draws.Add(d)
            End If
        Next

        For Each d In Draws
            List.Remove(d)
        Next
    End Sub

    ''' <summary>
    '''     Returns an enumerator that can be used to iterate through
    '''     the 'DrawCollection' collection.
    ''' </summary>
    Public Shadows Function GetEnumerator() As DrawEnumerator
        Return New DrawEnumerator(Me)
    End Function

    ''' <summary>
    '''     A strongly typed enumerator for 'DrawCollection'.
    ''' </summary>
    Public Class DrawEnumerator
        Implements System.Collections.IEnumerator

        Private iEnBaseEnumerator As System.Collections.IEnumerator

        ''' <summary>
        '''     The enumerator constructor.
        ''' </summary>
        Public Sub New(ByVal draMappings As DrawCollection)
            MyBase.New()
            Me.iEnBaseEnumerator = CType(draMappings, System.Collections.IEnumerable).GetEnumerator
        End Sub

        ''' <summary>
        '''     Gets the current element from the collection.
        ''' </summary>
        ReadOnly Property Current() As Object Implements System.Collections.IEnumerator.Current
            Get
                Return iEnBaseEnumerator.Current
            End Get
        End Property

        ''' <summary>
        '''     Advances the enumerator to the next element of the collection
        ''' </summary>
        Function MoveNext() As Boolean Implements System.Collections.IEnumerator.MoveNext
            Return iEnBaseEnumerator.MoveNext
        End Function

        ''' <summary>
        '''     Sets the enumerator to the first element in the collection
        ''' </summary>
        Sub Reset() Implements System.Collections.IEnumerator.Reset
            iEnBaseEnumerator.Reset()
        End Sub

    End Class

End Class


Code for Form1

Public Class Form1
    Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "

    Public Sub New()
        MyBase.New()

        'This call is required by the Windows Form Designer.
        InitializeComponent()

        'Add any initialization after the InitializeComponent() call

    End Sub

    'Form overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    Friend WithEvents rtbDraws As System.Windows.Forms.RichTextBox
    Friend WithEvents rtbCombinations As System.Windows.Forms.RichTextBox
    Friend WithEvents btnFill As System.Windows.Forms.Button
    Friend WithEvents TextBox1 As System.Windows.Forms.TextBox
    Friend WithEvents Label1 As System.Windows.Forms.Label
    Friend WithEvents Label2 As System.Windows.Forms.Label
    Friend WithEvents Label3 As System.Windows.Forms.Label
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.rtbDraws = New System.Windows.Forms.RichTextBox
        Me.rtbCombinations = New System.Windows.Forms.RichTextBox
        Me.btnFill = New System.Windows.Forms.Button
        Me.TextBox1 = New System.Windows.Forms.TextBox
        Me.Label1 = New System.Windows.Forms.Label
        Me.Label2 = New System.Windows.Forms.Label
        Me.Label3 = New System.Windows.Forms.Label
        Me.SuspendLayout()
        '
        'rtbDraws
        '
        Me.rtbDraws.Location = New System.Drawing.Point(328, 32)
        Me.rtbDraws.Name = "rtbDraws"
        Me.rtbDraws.ReadOnly = True
        Me.rtbDraws.Size = New System.Drawing.Size(224, 192)
        Me.rtbDraws.TabIndex = 7
        Me.rtbDraws.Text = ""
        '
        'rtbCombinations
        '
        Me.rtbCombinations.Location = New System.Drawing.Point(208, 32)
        Me.rtbCombinations.Name = "rtbCombinations"
        Me.rtbCombinations.ReadOnly = True
        Me.rtbCombinations.Size = New System.Drawing.Size(100, 192)
        Me.rtbCombinations.TabIndex = 6
        Me.rtbCombinations.Text = ""
        '
        'btnFill
        '
        Me.btnFill.Location = New System.Drawing.Point(336, 248)
        Me.btnFill.Name = "btnFill"
        Me.btnFill.TabIndex = 5
        Me.btnFill.Text = "Fill"
        '
        'TextBox1
        '
        Me.TextBox1.Location = New System.Drawing.Point(16, 32)
        Me.TextBox1.Multiline = True
        Me.TextBox1.Name = "TextBox1"
        Me.TextBox1.Size = New System.Drawing.Size(168, 192)
        Me.TextBox1.TabIndex = 8
        Me.TextBox1.Text = ""
        '
        'Label1
        '
        Me.Label1.Font = New System.Drawing.Font("Tahoma", 8.25!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
        Me.Label1.Location = New System.Drawing.Point(16, 8)
        Me.Label1.Name = "Label1"
        Me.Label1.Size = New System.Drawing.Size(168, 23)
        Me.Label1.TabIndex = 9
        Me.Label1.Text = "Enter Team Names 1 per line"
        Me.Label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft
        '
        'Label2
        '
        Me.Label2.Font = New System.Drawing.Font("Tahoma", 8.25!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
        Me.Label2.Location = New System.Drawing.Point(208, 8)
        Me.Label2.Name = "Label2"
        Me.Label2.Size = New System.Drawing.Size(120, 23)
        Me.Label2.TabIndex = 10
        Me.Label2.Text = "Combinations"
        Me.Label2.TextAlign = System.Drawing.ContentAlignment.MiddleLeft
        '
        'Label3
        '
        Me.Label3.Font = New System.Drawing.Font("Tahoma", 8.25!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
        Me.Label3.Location = New System.Drawing.Point(328, 8)
        Me.Label3.Name = "Label3"
        Me.Label3.Size = New System.Drawing.Size(120, 23)
        Me.Label3.TabIndex = 11
        Me.Label3.Text = "Draw"
        Me.Label3.TextAlign = System.Drawing.ContentAlignment.MiddleLeft
        '
        'Form1
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.ClientSize = New System.Drawing.Size(576, 278)
        Me.Controls.Add(Me.Label3)
        Me.Controls.Add(Me.Label2)
        Me.Controls.Add(Me.Label1)
        Me.Controls.Add(Me.TextBox1)
        Me.Controls.Add(Me.rtbDraws)
        Me.Controls.Add(Me.rtbCombinations)
        Me.Controls.Add(Me.btnFill)
        Me.Name = "Form1"
        Me.Text = "Form1"
        Me.ResumeLayout(False)

    End Sub

#End Region

    Private Draws As DrawCollection = New DrawCollection
    Private Teams As ArrayList = New ArrayList
    Private Teams2 As ArrayList = New ArrayList

    Public Class Team
        Implements IComparable

        Private m_strName As String
        Private m_strGUID As String

        Public Sub New(ByVal TeamName As String)
            m_strName = TeamName
            m_strGUID = Guid.NewGuid.ToString()
        End Sub

        Public ReadOnly Property TeamName() As String
            Get
                Return m_strName
            End Get
        End Property

        Public ReadOnly Property TeamGuid() As String
            Get
                Return m_strGUID
            End Get
        End Property

        Public Function CompareTo(ByVal obj As Object) As Integer Implements System.IComparable.CompareTo
            Dim team2 As Team = CType(obj, Team)
            Return String.Compare(m_strGUID, team2.TeamGuid)
        End Function

        Public Overrides Function ToString() As System.String
            Dim strValue As System.String

            strValue = m_strName

            Return strValue
        End Function

    End Class

    Private Sub btnFill_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnFill.Click

        rtbCombinations.Clear()
        rtbDraws.Clear()
        Teams.Clear()
        Teams2.Clear()

        Dim delimStr As String = vbCrLf
        Dim delimiter As Char() = delimStr.ToCharArray()

        Dim s As String
        For Each s In Me.TextBox1.Text.Split(delimiter)
            If s <> "" Then
                Teams.Add(New Team(s))
            End If
        Next

        If Teams.Count Mod 2 <> 0 Then
            Teams.Add(New Team("Bye"))
        End If

        Teams.Sort()
        Teams2 = New ArrayList(Teams.ToArray())

        GenerateCombinations()
        GenerateDraws()
    End Sub

    Private Sub GenerateCombinations()

        Dim i As Integer
        For i = 0 To Teams.Count - 1

            Teams2.RemoveAt(0)

            Dim j As Integer
            For j = 0 To Teams2.Count - 1
                rtbCombinations.AppendText(Teams(i).ToString + " vs " + Teams2(j).ToString + vbCrLf)
                Draws.Add(New Draw(Teams(i).ToString(), Teams2(j).ToString()))
            Next

        Next
    End Sub

    Private Sub GenerateDraws()
        Dim matches As Integer = CInt(Draws.Count / 2)
        Dim dc As DrawCollection

        Dim i As Integer
        For i = 0 To 6
            Dim round As Integer = i + 1
            rtbDraws.AppendText("Round " + round.ToString() + vbCrLf)
            dc = New DrawCollection(Draws)

            Do While dc.Count > 0
                rtbDraws.AppendText(dc(0).Match + ",")
                Draws.Remove(dc(0))
                dc.RemoveDraws(dc(0))

                Application.DoEvents()
            Loop

            rtbDraws.AppendText(vbCrLf)
        Next
    End Sub

End Class


If you want me to email you the latest project let me know

HTH
Andy
0
 
LVL 1

Author Comment

by:RayFrangie
ID: 14104060
Hi All,

Apologies for the delay in replying to this post

Me and Andy (heintalus) have been working on the solution offline and have created the application that will do what i need

The points will be awarded to Andy

Many thanks to all for their input. Hopefully the answer will help many people in the future

Cheers,
Ray.
0
 

Expert Comment

by:Steven Figueroa
ID: 40179288
Hey! can you email me the project? Thx
(stevenneo23  @  gmail.com)
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Article by: Kraeven
Introduction Remote Share is a simple remote sharing tool, enabling you to see, add and remove remote or local shares. The application is written in VB.NET targeting the .NET framework 2.0. The source code and the compiled programs have been in…
Introduction When many people think of the WebBrowser (http://msdn.microsoft.com/en-us/library/2te2y1x6%28v=VS.85%29.aspx) control, they immediately think of a control which allows the viewing and navigation of web pages. While this is true, it's a…
Loops Section Overview
Screencast - Getting to Know the Pipeline
Suggested Courses
Course of the Month20 days, 2 hours left to enroll

873 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question