Halloj! Du måste nog anropa Randomize före varje gång du anropar Rnd... Din slumpfunktion är fel, det ska vara "(rangeEnd - rangeStart + 1)" och inte "(rangeStart - rangeEnd + 1)". Hmm, din hitDice funktion är ändå lite fel... Randomize behöver bara startas en gång som han gjort i Form_Load Det där fungerade fint! Tack.. Jag ändrade bara hitDice, getResults och readData. >Hur ska jag förstå mer exakt när jag ska använda ByRef resp. ByVal? Svenpon, om du provar hans kod med ByVal så kommer du se att det inte fungerar. Vet dock inte varför. Jag förstår inte riktigt vad som är problemet - ni vet väl vad ByRef och ByVal betyder? >Men å andra sidan skickas de väl alltid som ByRef, om jag inte minns fel? Med ByVal så skapas en kopia av det värde du skickade som parameter (ByVal = By Value, alltså skickas endast variabelns värde) Just så, undvik ByRef om du vill ha kontroll över förloppen. Kör allt Lokalt så länge det går.Trubbel med tärningsfunktion
Håller i min VB-kurs på Malmöhögskola på att programmera en tärningsfunktion.
De hela bygger egentligen på två tärningar vars värden slumpas fram med hjälp av Rnd().
Användaren av programmet ska också kunna ange hur många gånger de två tärningarna ska kastas och därefter få ett svar på hur många gånger värdena på de två tärningarna blev likadana och hur många gånger de fått dubbel sexor.
Mitt program genererar dessvärre 0 i de båda resultat rutorna hela tiden :(
Så här ser min kod ut:
<code>
Option Explicit
' Read indata
Function readData(ByVal intAmount As Integer) As Boolean
Dim txtRawValue As String
Dim blnOkey As Boolean
txtRawValue = txtDiceAmount.Text
If IsNumeric(txtRawValue) Then
intAmount = Int(txtRawValue)
blnOkey = True
Else
MsgBox "Du måste ange ett tal i siffror!"
txtDiceAmount.SetFocus
txtDiceAmount.SelStart = 0
txtDiceAmount.SelLength = Len(txtDiceAmount.Text)
blnOkey = False
End If
readData = blnOkey
End Function
' Hit the dice!
Function hitDice(ByVal rangeStart As Integer, ByVal rangeEnd As Integer) As Integer
Dim rndAmount As Integer
rndAmount = Int(Rnd * (rangeStart - rangeEnd + 1) + rangeEnd)
hitDice = rndAmount
End Function
' Get dice results
Function getResults(ByVal int6 As Integer, ByVal intSame As Integer, ByRef intAmount As Integer) As Boolean
Dim rndNumber1 As Integer
Dim rndNumber2 As Integer
Dim i As Integer
Dim tmp6 As Integer
Dim tmpSame As Integer
i = 1
tmp6 = 0
tmpSame = 0
Do While i <= intAmount
rndNumber1 = hitDice(1, 6)
rndNumber2 = hitDice(1, 6)
' Check Amounts
If rndNumber1 = rndNumber2 Then
' Same amount
If tmpSame = 0 Then
tmpSame = 1
Else
tmpSame = tmpSame + 1
End If
' Both 6?
If rndNumber1 = 6 And rndNumber2 = 6 Then
' Both 6, count
If tmp6 = 0 Then
tmp6 = 1
Else
tmp6 = tmp6 + 1
End If
End If
End If
i = i + 1
Loop
int6 = tmp6
intSame = tmpSame
getResults = True
End Function
Sub displayResult(ByRef intB6 As Integer, ByRef intS As Integer)
lblResultSame.Caption = CStr(intS)
lblResult6.Caption = CStr(intB6)
' Reset amount field
txtDiceAmount.Text = ""
End Sub
Private Sub cmdDice_Click()
Dim intDiceAmount As Integer
Dim intBoth6 As Integer
Dim intBothSame As Integer
' Read indata
If readData(intDiceAmount) Then
' Get result data
If getResults(intBoth6, intBothSame, intDiceAmount) Then
' Display results
Call displayResult(intBoth6, intBothSame)
End If
End If
End Sub
Private Sub Form_Load()
Randomize
End Sub
</code>Sv: Trubbel med tärningsfunktion
Mvh,
ThomasSv: Trubbel med tärningsfunktion
Och sen har du glömt ByRef i två funktioner där du ändrar variablerna.
Har satt ihop hela koden:
<code>
Option Explicit
' Read indata
Function readData(ByRef intAmount As Integer) As Boolean
Dim txtRawValue As String
Dim blnOkey As Boolean
txtRawValue = txtDiceAmount.Text
If IsNumeric(txtRawValue) Then
intAmount = Int(txtRawValue)
blnOkey = True
Else
MsgBox "Du måste ange ett tal i siffror!"
txtDiceAmount.SetFocus
txtDiceAmount.SelStart = 0
txtDiceAmount.SelLength = Len(txtDiceAmount.Text)
blnOkey = False
End If
readData = blnOkey
End Function
' Hit the dice!
Function hitDice(ByVal rangeStart As Integer, ByVal rangeEnd As Integer) As Integer
Dim rndAmount As Integer
rndAmount = Int(Rnd * (rangeEnd - rangeStart + 1) + rangeEnd)
hitDice = rndAmount
End Function
' Get dice results
Function getResults(ByRef int6 As Integer, ByRef intSame As Integer, ByRef intAmount As Integer) As Boolean
Dim rndNumber1 As Integer
Dim rndNumber2 As Integer
Dim i As Integer
Dim tmp6 As Integer
Dim tmpSame As Integer
i = 1
tmp6 = 0
tmpSame = 0
Do While i <= intAmount
rndNumber1 = hitDice(1, 6)
rndNumber2 = hitDice(1, 6)
' Check Amounts
If rndNumber1 = rndNumber2 Then
' Same amount
If tmpSame = 0 Then
tmpSame = 1
Else
tmpSame = tmpSame + 1
End If
' Both 6?
If rndNumber1 = 6 And rndNumber2 = 6 Then
' Both 6, count
If tmp6 = 0 Then
tmp6 = 1
Else
tmp6 = tmp6 + 1
End If
End If
End If
i = i + 1
Loop
int6 = tmp6
intSame = tmpSame
getResults = True
End Function
Sub displayResult(ByRef intB6 As Integer, ByRef intS As Integer)
lblResultSame.Caption = CStr(intS)
lblResult6.Caption = CStr(intB6)
' Reset amount field
txtDiceAmount.Text = ""
End Sub
Private Sub cmdDice_Click()
Dim intDiceAmount As Integer
Dim intBoth6 As Integer
Dim intBothSame As Integer
' Read indata
If readData(intDiceAmount) Then
' Get result data
If getResults(intBoth6, intBothSame, intDiceAmount) Then
' Display results
Call displayResult(intBoth6, intBothSame)
End If
End If
End Sub
Private Sub Form_Load()
Randomize
End Sub
</code>
/MickeSv: Trubbel med tärningsfunktion
<code>
' Hit the dice!
Function hitDice(ByVal rangeStart As Integer, ByVal rangeEnd As Integer) As Integer
Dim rndAmount As Integer
Randomize()
rndAmount = Int(Rnd * (rangeEnd - rangeStart + 1) + rangeStart)
hitDice = rndAmount
End Function
</code>
Mvh,
ThomasSv: Trubbel med tärningsfunktion
Sen tycker jag att du skall ändra alla Integer till Long.
Gillar inte kommentaren om ByRef kan ställa till problem om du ändrar värdet i någon Funktion.
Skicka ByVal som du gjort det är säkrast för att ej komma i konflikt med Alias vi kompilering.Sv: Trubbel med tärningsfunktion
Vad exakt är det du har ändrat? Något mer än hitDice() funktionen och lite ByVal till ByRef?
Hur ska jag förstå mer exakt när jag ska använda ByRef resp. ByVal?Sv: Trubbel med tärningsfunktion
Här får du reda på vad ByRef och ByVal är: FAQ:ByVal och ByRef förklarat!
/MickeSv: Trubbel med tärningsfunktion
Enl min uppfattning kan du alltid köra med ByVal.Kan i skrivande stund inte
se nått fall där det skulle vara en fördel att kör ByRef.Vi har diskuterat detta förut
och kom då på att det finns något fall där ByRef skulle passa bättre.
Om du kollar API funktionerna som VB kan använda så måste du i 99 % av fallen skicka ByVal
ByRef är default i VB så det behöver du inte skriva ut.Sv: Trubbel med tärningsfunktion
/MickeSv: Trubbel med tärningsfunktion
Då är det ju bara att tänka vad som är lämpligt.
För små datatyper, integer, long, double, etc. så är det ingen prestandavinst med att använda ByRef, men det är det för "tyngre" datatyper, som användarskapade eller klasser. Men å andra sidan skickas de väl alltid som ByRef, om jag inte minns fel?
Skall värdet ändras använder man ByRef, annars ByVal, fast oftast är det bättre att försöka ha en funktion som returnerar värden istället.Sv: Trubbel med tärningsfunktion
Ja det är riktig , där satt den tex. måste du alltid skicka en Array ByRef.Sv: Trubbel med tärningsfunktion
Med ByRef så skickas en referens till din variabel och ev ändringar av värdet kommer att påverka originalvariabeln.
ex.
<code>
Sub exByVal(ByVal x as integer)
'Variabeln x har en egen minnesarea och innehåller samma
'värde som den variabel som användes i anropet
x = x + 10
End Sub
Sub exByRef(ByRef x as integer)
'Variabeln x använder samma minnesarea som den variabel som användes i anropet
'och en ändring av värdet på x ändrar därför värdet på den variabel som användes som parameter
'I VB kan exByRef(ByRef x as integer) även skrivas som exByRef( x as integer) då default är ByRef
x = x + 10
End Sub
Sub Main()
Dim y As Integer
y = 1
Call exByVal(y)
Debug.Print y 'y = 1,
Call exByRef(y)
Debug.Print y 'y = 11,
End Sub
</code>
Din function
Function getResults(ByVal int6 As Integer, ByVal intSame As Integer, ByRef intAmount As Integer) As Boolean
bör i ditt fall skrivas som
Function getResults(int6 As Integer, intSame As Integer, ByVal intAmount As Integer) As Boolean
Hoppas det klarnade lite
JanneSv: Trubbel med tärningsfunktion
Det blir nästan hopplöst att debugga om man inte har kontroll på vem som ändrar variabelns värde.