1

I just finished creating a programming (Be advised I am a beginner at this programming stuff) I was going for an idea of making a program that asks a user how many times they want to throw a set of three 6 sided dies, once the program has that input number of throws from the user, it will find out the out come of each throw and place it into a total integer so that it can be moved to a textbox to show how many times that number came up during the number of rolls almost like a tally system. Now I might be doing this the total wrong way or my logic might not be the greatest at programming but any help would be amazing I will post my code so far below

Public Class Form1
    Dim Numthrow As Integer
    Dim threetotal, fourtotal, fivetotal, sixtotal, sevtotal, eighttotal, ninetotal, tentotal, eeltotal As Integer
    Dim twtotal As Integer
    Dim threeteentotal As Integer
    Dim fourteentotal As Integer
    Dim fiveteentotal As Integer
    Dim sixteentotal As Integer
    Dim eightteentotal As Integer
    Dim nineteentotal As Integer

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Numthrow = TextBox1.Text

        For index = 0 To Numthrow
            Dim oDice As New Random
            Dim iDiceResult As Integer = oDice.Next(2, 19)

            If iDiceResult = 3 Then
                threetotal = threetotal + 1
            End If

            If iDiceResult = 4 Then
                fourtotal = fourtotal + 1
            End If

            If iDiceResult = 5 Then
                fivetotal = fivetotal + 1
            End If

            If iDiceResult = 6 Then
                sixtotal = sixtotal + 1
            End If

            If iDiceResult = 7 Then
                sevtotal = sevtotal + 1
            End If

            If iDiceResult = 8 Then
                eighttotal = eighttotal + 1
            End If

            If iDiceResult = 9 Then
                ninetotal = ninetotal + 1
            End If

            If iDiceResult = 10 Then
                tentotal = tentotal + 1
            End If

            If iDiceResult = 11 Then
                eeltotal = eeltotal + 1
            End If

            If iDiceResult = 12 Then
                twtotal = twtotal + 1
            End If

            If iDiceResult = 13 Then
                threeteentotal = threeteentotal + 1
            End If

            If iDiceResult = 14 Then
                fourteentotal = fourteentotal + 1
            End If

            If iDiceResult = 15 Then
                fiveteentotal = fiveteentotal + 1
            End If

            If iDiceResult = 16 Then
                sixteentotal = sixteentotal + 1
            End If

            If iDiceResult = 17 Then
                sevtotal = sevtotal + 1
            End If
            If iDiceResult = 18 Then
                eightteentotal = eightteentotal + 1
            End If
        Next
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        threetotal = 0
        fourtotal = 0
        fivetotal = 0
        sixtotal = 0
        sevtotal = 0
        eighttotal = 0
        ninetotal = 0
        tentotal = 0
        eeltotal = 0
        twtotal = 0
        threeteentotal = 0
        fourteentotal = 0
        fiveteentotal = 0
        sixteentotal = 0
        sevtotal = 0
        eightteentotal = 0
    End Sub
End Class
Tomas Pastircak
  • 2,867
  • 16
  • 28

3 Answers3

1

First you need to look at a couple of errors.

Creating a random variable inside a loop is guarateed to fail in the generation of your random numbers.
See this question for details

Next, in the Random.Next(minValue, maxValue) call, the minValue parameter is Inclusive while the maxValue is Exclusive. So you get random numbers starting from 2 not from 3

Finally, to simplify your problem you could use an array

' Defined at the global form level
Dim diceValue(18) As Integer
Dim randomGen As Random = new Random()

Private Sub Button1_Click(......)
    Numthrow = TextBox1.Text
    For index = 0 To Numthrow
       dim diceResult = randomGen.Next(3,19)
       diceValue(diceResult) += 1
    Next
End Sub

Notice that for the sake of readability I have dimensioned the array to 19 elements, also if you really use only 16 elements. The first three elements at index 0,1,2 should be discarded

Community
  • 1
  • 1
Steve
  • 213,761
  • 22
  • 232
  • 286
  • So I have used the code you provided I just need to kind of understand the randomGen part will get a number from 3 to 18? which would make up the set of D6 dies right? – user3576108 Apr 26 '14 at 14:05
  • Also when storing the total and displaying in a text box I just use textbox2.text = diceValue(10) correct? – user3576108 Apr 26 '14 at 14:06
  • The [Random.Next](http://msdn.microsoft.com/en-us/library/2dx6wyd4(v=vs.110).aspx) call use the first parameter as the lowest number that could be returned while the second parameter is the upper limit not included in the possible results. So `Next(3,19)` returns number from 3 to 18. The array has 19 elements starting from index 0 to 18 so the random numbers counter are stored and incremented at the corresponding index obtained by the random call – Steve Apr 26 '14 at 14:11
  • To display the single results you need of course 18 textboxes and do not use implicit conversion also if it is handy. `textBox.Text = diceValue(3).ToString()` – Steve Apr 26 '14 at 14:12
0

Instead of having all those variables, you could use an array or a list, and the indices of the array would correspond to your totals:

Put this in your class/module:

Private myTotals = New List(Of Integer)
Private oDice As New Random

And here is your event handler:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Numthrow = TextBox1.Text

    For index = 0 To Numthrow
        Dim iDiceResult As Integer = oDice.Next(2, 19)
        myTotals(iDiceResult) += 1
    Next
End Sub

Note that you want to instantiate Random only once because if you don't, then it will result in the same numbers being generated every time. Computers cannot truly generate random numbers; they take them from a table of random numbers instead.

rory.ap
  • 34,009
  • 10
  • 83
  • 174
0

Using classes

Public Class Form1
    Dim agame As New Dice(3, 6)
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        agame.RollAll(100000)
        Dim temp As Dictionary(Of Integer, Integer)
        temp = agame.GetStats
        For Each diect As KeyValuePair(Of Integer, Integer) In temp
            Debug.WriteLine("{0}  {1}", diect.Key, diect.Value)
        Next
        agame.ClearStats()
    End Sub
End Class

Public Class CommonRandom
    Public Shared prng As New Random
End Class

Public Class Die
    Inherits CommonRandom
    Property Faces As Integer 'number of faces on die
    Property CurrentFace As Integer 'the current face
    Private _rollfaces As Integer 'for call to Random
    Private _stats As New Dictionary(Of Integer, Integer)

    Public Sub New(numberOfFaces As Integer)
        If numberOfFaces > 0 Then
            Me.Faces = numberOfFaces
            Me._rollfaces = numberOfFaces + 1
            Me.CurrentFace = 1
            'set up stat buckets
            For x As Integer = 1 To numberOfFaces
                Me._stats.Add(x, 0)
            Next
        Else
            Throw New ArgumentException("faces > 0")
        End If
    End Sub

    Public Function Roll() As Integer 'roll this die
        Me.CurrentFace = prng.Next(1, Me._rollfaces)
        Me._stats(Me.CurrentFace) += 1 'accum stats
        Return Me.CurrentFace
    End Function

    Public Function GetStats() As Dictionary(Of Integer, Integer)
        Return Me._stats
    End Function

    Public Sub ClearStats()
        For x As Integer = 1 To Me.Faces
            Me._stats(x) = 0
        Next
    End Sub
End Class

Public Class Dice
    Inherits CommonRandom
    Private Property Dice As New List(Of Die) 'holds die
    Private _stats As New Dictionary(Of Integer, Integer) 'stats

    Public Sub New(numberOfDie As Integer, numberOfFaces As Integer)
        If numberOfDie > 0 Then 'add die to collection
            For x As Integer = 1 To numberOfDie
                Me.Dice.Add(New Die(numberOfFaces))
            Next
        Else
            Throw New ArgumentException("number of die > 0")
        End If
    End Sub

    ''' <summary>
    ''' number of die
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function NumberOfDie() As Integer
        Return Me.Dice.Count
    End Function

    ''' <summary>
    ''' roll all die
    ''' </summary>
    ''' <param name="NumberOfTimesToRoll"></param>
    ''' <remarks></remarks>
    Public Sub RollAll(Optional NumberOfTimesToRoll As Integer = 1)
        For x As Integer = 1 To NumberOfTimesToRoll
            For Each d As Die In Me.Dice
                d.Roll()
            Next
        Next
    End Sub

    ''' <summary>
    ''' roll a random die
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function RollOneDie() As Integer
        Dim whDie As Integer = prng.Next(Me.Dice.Count)
        Return Me.Dice(whDie).Roll()
    End Function

    ''' <summary>
    ''' get the stats of all die
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetStats() As Dictionary(Of Integer, Integer)
        Dim temp As Dictionary(Of Integer, Integer)
        For Each d As Die In Me.Dice
            temp = d.GetStats
            For Each diect As KeyValuePair(Of Integer, Integer) In temp
                If Me._stats.ContainsKey(diect.Key) Then
                    Me._stats(diect.Key) += diect.Value
                Else
                    Me._stats.Add(diect.Key, diect.Value)
                End If
            Next
        Next
        Return Me._stats
    End Function

    ''' <summary>
    ''' clear the stats
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub ClearStats()
        Me._stats.Clear()
        For Each d As Die In Me.Dice
            d.ClearStats()
        Next
    End Sub
End Class
dbasnett
  • 11,334
  • 2
  • 25
  • 33