Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Crazy question: Can anyone help me create a routine to roll 2 dice 1000x and sum them? 4

TheresAlwaysAWay

Programmer
Mar 15, 2016
145
US
I'm fooling with a game program idea in Access that requires rolling of dice 1000x and summing the two of them, roughly equivalent to 1000 rolls on a craps table.

I used the Rnd function successfully, but it doesn't run hands sequentially to store them in a table for future reference.

I'm hoping one of the wizards out there can come up with something that will do the trick relatively quickly.

As always, thanks in advance to all of you.
 
In VBA code, I'd store them in a collection. Try this.
Code:
Public Function DiceRolls(Optional NumTimes As Integer = 1000) As Collection
    Dim aRoll As Byte
    Dim i As Integer

    Randomize Now()

    Set DiceRolls = New Collection
    For i = 1 To NumTimes
        aRoll = (5 * Rnd) + 1
        DiceRolls.Add aRoll
    Next
  
End Function

Public Sub HowToUse_DiceRolls()
    Dim rolls As Collection
    Dim roll As Variant
    Dim i As Integer
  
    Set rolls = DiceRolls(35)
  
    For Each roll In rolls
        i = i + 1
        Debug.Print roll & ", ";
    Next
    Debug.Print
  
    Set rolls = Nothing
End Sub

To have it run a thousand times, just remove the "35" in
Code:
Set rolls = DiceRolls()

I re-read the Topic and see that you wanted to roll TWO dice a thousand times.
And Sum them.

That makes it a bit more complicated because now we need to introduce a CLASS to hold the roll for each dice.

You need to Insert a class module, and put this code in the class module:
Code:
Public dice1 As Byte
Public dice1 As Byte
Public dice2 As Byte
Public diceSum As Integer
When you save it, give it the name "cmDice".

Now, our code changes to use the new cmDice class. It creates an instance of the cmDice class and stores the instance in the collection.
Code:
Public Function DiceRolls(Optional NumTimes As Integer = 1000) As Collection
    Dim aRoll As Byte
    Dim i As Integer
    Dim oDice As cmDice
   
    Randomize Now()
   
    Set DiceRolls = New Collection
    For i = 1 To NumTimes
        Set oDice = New cmDice
       
        aRoll = (5 * Rnd) + 1
        oDice.dice1 = aRoll
       
        aRoll = (5 * Rnd) + 1
        oDice.dice2 = aRoll
        
        oDice.diceSum = oDice.dice1 + oDice.dice2
       
        DiceRolls.Add oDice
    Next
   
    Set oDice = Nothing
End Function


Public Sub HowToUse_DiceRolls()
    Dim rolls As Collection
    Dim oDice As cmDice
   
    Set rolls = DiceRolls(35)
   
    For Each oDice In rolls
        Debug.Print oDice.dice1 & "+" & oDice.dice2 & "=" & oDice.diceSum & ", ";
    Next
    Debug.Print
   
    Set rolls = Nothing
    Set oDice = Nothing
End Sub
 
Last edited:
Thank you. I haven't had a chance to test this yet because I ran into an even more pressing problem.

I tried to log into Tek-Tips from my phone and I was prompted to change my password. There were several false starts, and suddenly I get a message that the account is locked and I can't find any information on how to unlock it.

My desktop remained logged in and so I'm able to respond here, but if I lose this login I won't be able to do anything at all.

I had another username but the same thing happened. I was never able to unlock and I had to create a new name with a different email address.

Can someone please help me figure out what to do? If my desktop automatically restarts for an update, or if there's a power failure I'm screwed. I won't be able to get back again to respond, and my earlier experience left me no way to get back. My earlier name that I had to abandon was macroscope. I want help on that one, too.

If any of you knows an administrator I really am concerned that I'll be shut out again. I hope someone can contact them on my behalf before I'm dead in the water again.
 
I can't help with the login problem. Sorry.

I'm still noodling on your post and realize that requirements can sometimes be tricky.

So, here's a solution if you need a sum of the number of rolls, not the sum of each roll.
Code:
Public Sub HowToUse_DiceRolls()
    Dim rolls As Collection
    Dim oDice As cmDice
    Dim allRollsSum As Integer
    
    Set rolls = DiceRolls(35)
    
    For Each oDice In rolls
        Debug.Print oDice.dice1 & "+" & oDice.dice2 & "=" & oDice.diceSum & ", ";
        allRollsSum = allRollsSum + oDice.diceSum
    Next
    Debug.Print
    Debug.Print "Sum of ALL rolls is " & allRollsSum
    
    Set rolls = Nothing
    Set oDice = Nothing
End Sub
 
No, I need the sum of each roll, just like craps. Two dice are thrown, and each has a 1 in six chance of any given face showing, and then the two dice are summed to provide the total for each roll.

The one requirement that I have is that I want to be able to save the results in a table so that I can re-run the exact same sequence many times. That way the dice rolls are no longer a variable but a constant, and whatever else I introduce is the variable that affects the results.

This definitely runs the dice, but it doesn't save the sequence for future reference.

I'm puzzling over your choice of (5 * Rnd) + 1 in the code. I believe it should be (6 * Rnd) + 1.
 
One other thing. I created a simple table with six fields.
ID, to keep Access PK happy;
Session, to identify which session each of the rolls belongs to;
Roll, which is a sequential number of 1-1000 to identify which roll each total represents;
D1 and D2, obviously the face of each die that is shown; and finally
Total, the sum of the two faces on that roll.

I hope that helps clarify my needs.
 
>My desktop remained logged in
In which case, just open your account details for the site (click your name in the top ribbon and select 'password and security' which should take you to a page where you can change your password.

Or try the 'Contact Us' option at the very bottom of pretty much every tek-tips page. They'll then use your email address to contact you.

> I want to be able to save the results in a table so that I can re-run the exact same sequence many times
The random number generator has the ability to regenerate the exact same sequence on demand. So you don't necessarily need a table.

Here's a simple example

Rich (BB code):
Option Explicit

Public Function dieroll(sides As Long) As Long
    dieroll = ((sides - 1) * Rnd()) + 1
End Function

Public Sub Example()
    Dim Sequence As Variant
    
    Sequence = 1234 ' Any numeric value
    ' Choose our sequence ...
    Rnd -1
    Randomize Sequence
    
    Dim die1 As Long
    Dim die2 As Long
    Dim lp As Long
    For lp = 1 To 1000
        die1 = dieroll(6)
        die2 = dieroll(6)
        Debug.Print Sequence, lp, die1, die2, die1 + die2
    Next
    Debug.Print
    
    'Choose 998th pair of rolls from a specific sequence, no table required
    Rnd -1
    Randomize Sequence

    For lp = 1 To 998
        die1 = dieroll(6)
        die2 = dieroll(6)
    Next
    Debug.Print Sequence, lp - 1, die1, die2, die1 + die2
End Sub
 
If you have a table (MyTable?) like this:
IDSessionRollD1D2Total
53151639
54152145
55153325
56154336
57155527
58156134
59157426

(Have a Total field as a calculated field)

So, you can have some simple code to generate your records:

Code:
Sub RollDice()
Dim i As Integer
Randomize
For i = 1 To 25
    Debug.Print "INSERT INTO MyTable (Session, Roll, D1, D2) VALUES (15, " & i & ", " & Int((6) * Rnd + 1) & ", " & Int((6) * Rnd + 1) & ")"
Next i
End Sub

Just change the Debug.Print to DB.Execute
 
Thanks for your help with login. So far I'm still logged in and able to answer. I've been locked out before and I don't want to test this until at least this thread is complete.

You have helped me in the past and I know your coding is impeccable but I really want to save the results to table. Is there a simple way to accomplish this?
 
My suggestion is as simple as it gets, and saves your data in the table.
Did you try it?
 
Andy, it works perfectly as a Debug.Print, but when I switch it to DB.Execute I get the following error.
Error 424. Object Required.
When I select Debug the whole Insert Into line is highlighted. Not sure what I'm doing wrong, but literally the only change I make is to change MyTable to Sessions2 (my name), and change Debug.Print to DB.Execute. Everything else remains exactly as you offered it.

One other question. You mention the total field as a calculated field. D1+D2 is obviously easy enough, but how do I add that into the code?
 
You may need a CurrentDb.Execute instead.
As far as Total column - I included a link to how to set up/use a calculated field. The beauty of it is - you don't need to do anything in code for the Total field, Access will calculate that for you (if you set up that field correctly). Plus, you will NOT get the situation where D1 = 2, D2 = 3, and Total will be something else than 5 (which could happen if you provide the value for that field yourself)

It is pretty much the same as your ID field (Primary Key field). If you set it up correctly, you do not need to mention this field in the INSERT statement, Access does all its magic 'auto-magically' for you :)
 
Last edited:
The CurrentDB.Execute was the ticket. Did everything I wanted it to do.

Thank you for all your help.

I'm gonna try strong's suggestion to reset the password. I've received email links in the past to reset and they fail every time, with a message that "Something's gone wrong" and I've sent several emails to the ContactUs link without a reply.

Just letting y'all know that if I disappear from the planet after this, this is the reason!
 
Thanks, strong. It worked. I still can't get my original account reactivated, but at least password has been reset and it seems I'm good to go.
 
Andy, one other question.

In your code you chose a fixed number, 15, to represent the Session ID. I was trying to replace that with a variable, "Nz(DMax('[Session]','[Sessions2]'),0)+1" and it fails. Can you spot why?

The complete line I replaced it with is:
CurrentDb.Execute "INSERT INTO Sessions2 (Session, Roll, D1, D2) VALUES ("Nz(DMax('[Session]','[Sessions2]'),0)+1", " & i & ", " & Int((6) * Rnd + 1) & ", " & Int((6) * Rnd + 1) & ")"

I tried both single ' and double " around the DMax expression
 
You cannot assign the Session number in your Insert statement because you will get incremental values for each Insert. You need to do it before all your Inserts. (Count your blessing that your approach did not work :) )

Try this approach (code not tested):

Rich (BB code):
Sub StartHere()
Dim intNextSession As Integer
intNextSession = Nz(DMax([Session],[Sessions2]),0)+1
Call RollDice(intNextSession, 1000)
End Sub

Sub RollDice(ByRef intS As Integer, ByRef intR As Integer)
Dim i As Integer
Randomize
For i = 1 To intR
    CurrentDb.Execute "INSERT INTO Sessions2 (Session, Roll, D1, D2) VALUES (intS  & ", " & i & ", " & Int((6) * Rnd + 1) & ", " & Int((6) * Rnd + 1) & ")"
Next i
End Sub
 
Last edited:
Thank you for all of your help and your input. It's simple to do when you know how!

You've given me exactly what I was looking for.
 
[thumbsup2]
Have you tried the computed / calculated field? Once you use it, you will find a whole bunch of ways to use it:
FullName: FirstName + ' ' + LastName
FullNameRev: LastName + ', ' + FirstName

Etc.
 
Purists would argue that a calculated field in a table that is derived from data in that same table is bad practice

And I'd be interested to know why this has to be a table at all
 
I would like to hear that argument. (Always willing to learn)
IMO, it is a lot better than having a Total field where you can write your own value (which could be wrong).
There is also a query/view option to have the data with the calculated field(s)...
 

Part and Inventory Search

Sponsor

Back
Top