Nu har jag skrivit ett ljudträningsprogram (för musiker) men med randomfunc har jag stora problem då jag bara får den att slumpa om 12 ggr då den aldrig får samma värde 2 ggr? bifogar kod och hoppas på lite hjälp från er alla. Tjena... nej tvärtom =) lol...lägg bara delen där talen slumpas o stoppas i arrayen i en egen funtion och anropa den hur många gånger som behövs. Eftersom det gäller VB så blir det som sagts härovan. Lägg upp en Array(13) Eftersom det gäller VB så blir det som sagts härovan. Lägg upp en Array(13) Sven, hur förhindrar du med din funktion att inte samma nummer finns två gånger i din array? Som vanligt när man tro man kan skriva fritt ur minnet så här bör det vara Som jag har förstått det så vill du inte ha samma not 2 ggr i RAD. Snubben har inte varit här sen den 23:e, och det är fullståndigt omöjligt att förstå vad han menar. Om man läser själva frågan så verkar det som om han inte kan slumpa fler än två gånger. Exakt varför vet jag inte, men om ni läser frågan och det efterföljande svaret så ser ni vad jag menar. precis så är det jag menar Har du testat våra förslag ? funkar det ? Michael, Michael,Rnd
Public Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'rnd func
Randomize()
slumpen = Int((12 - 1 + 1) * Rnd() + 1)
' markerar A
rdA.Checked = True
'kollar vilket ljud som ska spelas
Select Case slumpen
Case "1"
tone = "E"
play.FileName = "Ess.wav"
play.Command = "open"
play.Command = "play"
Case "2"
'ladda ljudet
tone = "F"
play.FileName = "F.wav"
play.Command = "open"
play.Command = "play"
Case "3"
'ladda ljudet
tone = "F#"
play.FileName = "F2.wav"
play.Command = "open"
play.Command = "play"""
Case "4"
'ladda ljudet
tone = "G"
play.FileName = "G.wav"
play.Command = "open"
play.Command = "play"
Case "5"
'ladda ljudet
tone = "G#"
play.FileName = "G2.wav"
play.Command = "open"
play.Command = "play"
Case "6"
'ladda ljudet
tone = "A"
play.FileName = "A.wav"
play.Command = "open"
play.Command = "play"
Case "7"
'ladda ljudet
tone = "Bb"
play.FileName = "Bb.wav"
play.Command = "open"
play.Command = "play"
Case "8"
'ladda ljudet
tone = "B"
play.FileName = "B.wav"
play.Command = "open"
play.Command = "play"
Case "9"
'ladda ljudet
tone = "C"
play.FileName = "C.wav"
play.Command = "open"
play.Command = "play"
Case "10"
'ladda ljudet
tone = "C#"
play.FileName = "C2.wav"
play.Command = "open"
play.Command = "play"
Case "11"
'ladda ljudet
tone = "D"
play.FileName = "D.wav"
play.Command = "open"
play.Command = "play"
Case "12"
'ladda ljudet
tone = "Eb"
play.FileName = "Eb.wav"
play.Command = "open"
play.Command = "play"
Case ""
play.Command = "play"
End SelectSv: Rnd
Om jag förstått rätt vill du slumpa talen 1-12 tolv gånger utan att ett tal upprepar sig två gånger!
Jag tänkte ut en lösning i vb.net men principen och idén är väl samma i vilket annat språk.
Här har jag använt mig av en ArrayList alltså en flexiblare variant av en vanlig array.
Jag låter arrayen att fyllas på från 0 till 11 alltså tolv platser, men innan den fylls me ett värde görs ett kol ifall värdet redan existerar eller inte, finns värdet görs inget tillägg till arayen. En loop kollar tills arrayen får storleken 12 och då vet jag att alla värde mellan 1-12 finns med utan någon upprepning.
Sen hämtar jag bara värdena från min array från början till slut. /mvh babak
Dim number As New ArrayList
Dim slumpen As Integer
Dim i As Integer
Do Until number.Count = 12 'gör tills arraylisten har 12 värde i sig
slumpen = Int(12 * Rnd() + 1)
If number.Contains(slumpen) Then 'om värdet finns gör inget
Else
number.Add(slumpen) 'om ej finns, lägg till den i arraylistan
End If
Loop
nu kan värden hämtas frn arraylisten med en vanlig for next tex
for i=0 to 11
select case number(i)
case 1
....
case 2
...
....
....
next iSv: Rnd
Nu kan den bara slumpa talen 12 gånger
efter 12 slumpningar kan den inte slumpa nå mer
Det kan bara ett värde en gång nu...Sv: Rnd
Sv: Rnd
Kör I Form_Load skall det stå Randomize
<code>
Dim myRnd As Long,i As Long
Dim myArray(13) As Long
i = 1
Do Until i > 12
myRnd = Int(Rnd * 12) + 1
If myArray(myRnd) = 0 Then
MyArray(i) = myRnd
i = i +1
End If
Loop
'Om jag nu fritt ur minnet har rätt så har du dina slumptal 1-12 i MyArray(1)-MyArray(12)
</code>Sv: Rnd
Kör I Form_Load skall det stå Randomize
<code>
Dim myRnd As Long,i As Long
Dim myArray(13) As Long
i = 1
Do Until i > 12
myRnd = Int(Rnd * 12) + 1
If myArray(i) = 0 Then
MyArray(i) = myRnd
i = i + 1
End If
Loop
'Om jag nu fritt ur minnet har rätt så har du dina slumptal 1-12 i MyArray(1)-MyArray(12)
</code>Sv: Rnd
En lösning som jag ofta ser är att man slumpar sig igenom en array och för varje nummer som slumpas så kollar man igenom alla tidigare slumpade tal för att kolla att det inte redan använts. Detta är inge bra lösning då den kan ta lång tid på slutet av arrayen innan ett oanvänt numer hittats. Ett bättre sätt är att skapa en array och initiera den i nummerordning, t ex 1-100. Sedan loopar man igenom arrayen EN gång och för varje värde så slumpar man ett tal mellan lägsta och högsta möjliga index för arrayen och byter sedan plats med värdena array(LoopIndex) <-> array(SlumpIndex). På så sätt garanterar man att varje nummer endast förekommer en gång, man behöver bara köra igenom arrayen en gång (en del gör det i två steg, först initiera arrayen och sedan slumpa platsbyten men det går att lösa det i en genomkörning).
Jag har tidigare visat detta förfarande i tips & tricks [Slumpa och sortera (ett snabbare sätt)]
//
JanneSv: Rnd
<code>
Option Explicit
Dim myArray(13) As Long
Private Sub Form_Load()
Randomize
End Sub
Private Sub Command1_Click()
Dim myRnd As Long, i As Long
Dim tmpArray(13) As Long
List1.Clear
i = 1
Do Until i > 12
myRnd = Int(Rnd * 12) + 1
If tmpArray(myRnd) = 0 Then
tmpArray(myRnd) = 1
myArray(i) = myRnd
i = i + 1
'Om du vill kolla resultatet
List1.AddItem myRnd
End If
Loop
'MyArray(1) - MyArray(12) innehåller dina slumptal
End Sub
</code>Sv: Rnd
Det är väl bara att spara förra noten i en variabel.
<code>
Dim myRnd As Long,i As Long, lastRnd as long
Dim myArray(13) As Long
i = 1
Do Until i > 12
myRnd = Int(Rnd * 12) + 1
If myRnd <> lastRnd Then
MyArray(i) = myRnd
i = i + 1
End If
Loop
</code>Sv: Rnd
Sv: Rnd
jag KAN inte få samma tal 2 ggr, så den kan bara slumpa ett visst antal ggr, 12 i detta fallSv: Rnd
Mitt senaste bör lösa ditt problem om du efter inläsning till MyArray(13) plockar
i en For i = 1 To 12
'kollar vilket ljud som ska spelas
Select Case myArray(i)
Case Is = 1
tone = "E"
play.FileName = "Ess.wav"
play.Command = "open"
play.Command = "play"
Case Is = 2
'ladda ljudet
tone = "F"
play.FileName = "F.wav"
play.Command = "open"
play.Command = "play"
osv osv Obs inga "fnuttar" kring Case Is = 2Sv: Rnd
jag KAN inte... Betyder det att du vill ha samma tal två gånger men inte kan få det eller är det som jag tror att du inte FÅR ha samma nummer två gånger på dina 12 slumpningar.
Är det som jag tror att du menar så har du här ett förslag med en generell funktion för att skapa en array samt för att slumpa tal.
<code>
Option Explicit
Sub main()
Randomize
Dim myArray() As Integer
Dim i As Long
'Skapa en array (myArray(0) - myArray(11)) som innehåller tal från 1 till 12 i slumpad ordning
myArray = GetRandomArray(1, 12)
'Loopar igenom arrayen som exempel
For i = LBound(myArray) To UBound(myArray)
Debug.Print "myArray(" & i & ") = " & myArray(i)
'Här kan du t ex lägga in din Select Case sats
'Select Case myArray(i)
'Case 1
'...
'Case 2
'...
'osv
'End Select
Next
End Sub
'GetRandomArray funktionen löper igenom arrayen endast en gång för att generera en lista med tal från
'"StartValue" till "EndValue" i slumpad ordning.
Private Function GetRandomArray(Optional ByVal StartValue As Integer = 0, Optional ByVal EndValue As Integer = &H7FFF) As Integer()
Dim arrRet() As Integer
Dim arrSet() As Boolean
Dim RndNum As Integer, temp As Integer
Dim lngStart As Long, lngEnd As Long, i As Long
lngStart = StartValue: lngEnd = EndValue
If lngEnd - lngStart < 0 Then Exit Function
'Dimensionera arrayer
ReDim arrRet(lngEnd - lngStart) 'Array med slumpade tal
ReDim arrSet(lngEnd - lngStart) 'Hjälparray (krävs för att kunna lösa uppgiften med endast en loop)
For i = LBound(arrRet) To UBound(arrRet)
'Slumpa ett tal
RndNum = GetRandomNum(LBound(arrRet), UBound(arrRet))
If Not arrSet(i) Then
arrRet(i) = i + lngStart
arrSet(i) = True
End If
If Not arrSet(RndNum) Then
arrRet(RndNum) = RndNum + lngStart
arrSet(RndNum) = True
End If
'Byt plats arrRet(i) <-> arrRet(slump)
temp = arrRet(i)
arrRet(i) = arrRet(RndNum)
arrRet(RndNum) = temp
Next
GetRandomArray = arrRet
End Function
Private Function GetRandomNum(ByVal MinVal As Integer, ByVal MaxVal As Integer) As Integer
Dim temp As Currency
'Temp variablen används för att ta hand om när MaxVal har maxvärde
temp = CLng(MaxVal) - CLng(MinVal) + 1
GetRandomNum = Int((temp) * Rnd + MinVal)
End Function
</code>
//
JanneSv: Rnd
"jag KAN inte..." Betyder det att du vill ha samma tal två gånger men inte kan få det eller är det som jag tror att du inte FÅR ha samma nummer två gånger på dina 12 slumpningar.
Är det som jag tror att du menar så har du här ett förslag med en generell funktion för att skapa en array samt för att slumpa tal.
<code>
Option Explicit
Sub main()
Randomize
Dim myArray() As Integer
Dim i As Long
'Skapa en array (myArray(0) - myArray(11)) som innehåller tal från 1 till 12 i slumpad ordning
myArray = GetRandomArray(1, 12)
'Loopar igenom arrayen som exempel
For i = LBound(myArray) To UBound(myArray)
Debug.Print "myArray(" & i & ") = " & myArray(i)
'Här kan du t ex lägga in din Select Case sats
'Select Case myArray(i)
'Case 1
'...
'Case 2
'...
'osv
'End Select
Next
End Sub
'GetRandomArray funktionen löper igenom arrayen endast en gång för att generera en lista med tal från
'"StartValue" till "EndValue" i slumpad ordning.
Private Function GetRandomArray(Optional ByVal StartValue As Integer = 0, Optional ByVal EndValue As Integer = &H7FFF) As Integer()
Dim arrRet() As Integer
Dim arrSet() As Boolean
Dim RndNum As Integer, temp As Integer
Dim lngStart As Long, lngEnd As Long, i As Long
lngStart = StartValue: lngEnd = EndValue
If lngEnd - lngStart < 0 Then Exit Function
'Dimensionera arrayer
ReDim arrRet(lngEnd - lngStart) 'Array med slumpade tal
ReDim arrSet(lngEnd - lngStart) 'Hjälparray (krävs för att kunna lösa uppgiften med endast en loop)
For i = LBound(arrRet) To UBound(arrRet)
'Slumpa ett tal
RndNum = GetRandomNum(LBound(arrRet), UBound(arrRet))
If Not arrSet(i) Then
arrRet(i) = i + lngStart
arrSet(i) = True
End If
If Not arrSet(RndNum) Then
arrRet(RndNum) = RndNum + lngStart
arrSet(RndNum) = True
End If
'Byt plats arrRet(i) <-> arrRet(slump)
temp = arrRet(i)
arrRet(i) = arrRet(RndNum)
arrRet(RndNum) = temp
Next
GetRandomArray = arrRet
End Function
Private Function GetRandomNum(ByVal MinVal As Integer, ByVal MaxVal As Integer) As Integer
Dim temp As Currency
'Temp variablen används för att ta hand om när MaxVal har maxvärde
temp = CLng(MaxVal) - CLng(MinVal) + 1
GetRandomNum = Int((temp) * Rnd + MinVal)
End Function
</code>
//
Janne