我在Visual Basic中制作了一个玩家匹配程序。该程序应该选择随机注册的玩家并配对。我目前正在研究奇数玩家的一部分。
我所拥有的解决方案正在发挥作用,但可能并不那么有效。我有更好的方法来编写这段代码吗?
代码应该选择随机玩家,并确保不再选择它们。如你所见,为了使代码工作,我必须让它循环数千次。如果我没有一些玩家不会出现在列表框中。有更好的解决方案???
如果它令人困惑" spiller"是"播放器"
的挪威语For i As Integer = 0 To 100000
Dim spiller1 As Integer
Dim spiller2 As Integer
Do
spiller1 = CInt(Math.Floor(Rnd() * spillerListe.Count))
spiller2 = CInt(Math.Floor(Rnd() * spillerListe.Count))
Loop Until CBool(spiller1 <> spiller2)
If brukteSpillere(spiller1) = False And brukteSpillere(spiller2) = False Then
brukteSpillere(spiller1) = True
brukteSpillere(spiller2) = True
lstSpillere.Items.Add(spillerListe(spiller1).ToString + " VS. " + spillerListe(spiller2).ToString())
End If
Next i
答案 0 :(得分:4)
这是一团糟......拥有一个包含所有可用索引的List(Of Integer)。
Loop while availableIndex.Count > 1
Pick a random index from availableIndex and remove it from that list
Pick a random index from availableIndex and remove it from that list
Add these two index to the list of pairs
End Loop
这样您就不需要检查随机值是否相同或者是否已经选择它们。
现在,如果您不想创建列表。然后威胁随机数不作为索引,而是作为要检查的项目数。
Delta = RandomNumber
x = 0
For i As Integer = 0 To itemList.Count-1
If Not itemList(i).IsChoosen Then
x += 1
If x = Delta Then
' i is now your item to pick
itemList(i).IsChoosen = True
Exit For
End If
End If
Next
答案 1 :(得分:2)
解决此问题有两种有效方法:
按随机数对播放器列表进行排序,然后将1与2,3匹配为4,依此类推。
Dim r As New Random
Dim randomListe = spillerListe.OrderBy(Function() r.Next).ToList
从您的范围生成两个随机数,将这些玩家匹配到一个单独的列表中,从原始列表中删除玩家。一般来自较小范围的两个随机数(原始减去2),匹配等等。
编辑:看了MSDN后,List的RemoveAt性能为O(n),所以效率不高,最好使用字典which is O(1) at removing items,所以而不是spillerListe
有一些spillerDicte
,您可以在表格中添加条目(key = index,value = item)。
答案 2 :(得分:0)
如果您将玩家的名字保留在列表中,并且在挑选玩家后将其从列表中删除,该怎么办?可能这不是最好的高性能解决方案,但很明显你想做什么
Dim lstSpillere = new List(Of String)() ' Just for the example below
Dim spillerListe = new List(Of String)() from {"Marc", "John", "Steve", "George", "David", "Jeremy", "Andrew" }
Dim rnd = new Random()
While spillerListe.Count > 1
Dim firstPlayer = spillerListe(rnd.Next(0, spillerListe.Count))
spillerListe.Remove(firstPlayer)
Dim secondPlayer = spillerListe(rnd.Next(0, spillerListe.Count))
spillerListe.Remove(secondPlayer)
lstSpillere.Add(firstPlayer + " VS. " + secondPlayer)
' for debug purpose....
Console.WriteLine(firstPlayer & " VS. " & secondPlayer)
End While
if spillerListe.Count > 0 Then
Console.WriteLine("Excluded from play list is:" & spillerListe(0))
End if
这里的重要关键是生成应该在循环外部的Random实例,以避免在循环执行所需的短时间内生成相同的数字。
答案 3 :(得分:0)
试试这个:
Module Module1
Dim rnd As New Random
Sub Main()
Dim RegisteredPlayers As New List(Of Player)
' Fill List (example 100 players)
For index As Integer = 1 To 100
RegisteredPlayers.Add(New Player(String.Format("Player{0}", index)))
Next
'Sort Players using a random number
Dim SortedPlayersArray = RandomSortItems(RegisteredPlayers.ToArray())
'Pair players by selecting 2 consequative ones from randomly sorted array
Dim Matches As New List(Of Match)
For index As Integer = 1 To SortedPlayersArray.Length Step 2
Dim m As Match = New Match(SortedPlayersArray(index - 1), SortedPlayersArray(index))
Matches.Add(m)
Debug.WriteLine(m.ToString())
Next
' Match Player48 vs. Player79
' Match Player3 vs. Player53
' Match Player18 vs. Player43
' Match Player85 vs. Player1
' Match Player47 vs. Player56
' Match Player23 vs. Player66
' etc..
End Sub
Public Function RandomSortItems(Of T)(ByVal items As T()) As T()
Dim sorted As T() = New T(items.Length-1) {}
Array.Copy(items, sorted, sorted.Length)
Dim keys As Double() = New Double(items.Length-1) {}
For i As Integer = 1 To items.Length
keys(i - 1) = rnd.NextDouble()
Next
Array.Sort(keys, sorted)
Return sorted
End Function
End Module1
Public Class Player
Dim m_name As String
Public Sub New(ByVal player_name As String)
m_name = player_name
End Sub
Public ReadOnly Property Name() As String
Get
Return m_name
End Get
End Property
Public Overrides Function ToString() As String
Return m_name
End Function
End Class
Public Class Match
Dim m_player_1 As Player, m_player_2 As Player
Public Sub New(ByVal player_1 As Player, ByVal player_2 As Player)
m_player_1 = player_1
m_player_2 = player_2
End Sub
Public ReadOnly Property Player1() As Player
Get
Return m_player_1
End Get
End Property
Public ReadOnly Property Player2() As Player
Get
Return m_player_2
End Get
End Property
Public Overrides Function ToString() As String
Return String.Format("Match {0} vs. {1}", Player1, Player2)
End Function
End Class
备用随机分拣机(应该更快)
Public Function RandomSortItems(Of T)(ByVal items As T()) As T()
Dim slist As New SortedList(Of Double, T)
For i As Integer = 1 to items.Length
slist.Add(rnd.NextDouble(), items(i-1) )
Next i
return slist.Values.ToArray()
End Function