Page 2 of 3 FirstFirst 123 LastLast
Results 16 to 30 of 43
  1. #16
    ConneXionLost's Avatar
    ConneXionLost is offline Simulacrum
    Windows XP Access 2003
    Join Date
    Jan 2010
    Location
    Victoria, Canada
    Posts
    291
    Tried this just for fun.



    Cheers,

  2. #17
    bcmarshall is offline Advanced Beginner
    Windows XP Access 2003
    Join Date
    Jul 2010
    Posts
    95

    6 Deck Card Shuffling in Access

    Dammmm! That's fast! Thank you soooo much. Now I can turn my attention to important things!

  3. #18
    bcmarshall is offline Advanced Beginner
    Windows XP Access 2003
    Join Date
    Jul 2010
    Posts
    95
    Connexion, I have a quick question. Can you describe how the routine operates?

  4. #19
    Rawb is offline Expert
    Windows XP Access 2000
    Join Date
    Dec 2009
    Location
    Somewhere
    Posts
    875
    Awww, it looks like someone beat me too it!

    Oh well, I'll post my solution anyway. After all, I've already put all this work into it!

    I'll attach my DB (Access 2000), but the core of what I did is the following Function:

    Code:
    Function ShuffleTheDeck(strTableName, strSortIDField)
      On Error GoTo Error_ShuffleTheDeck
    
      Dim work As Workspace
      Dim rstDeck As DAO.Recordset
      Dim rstVerify As DAO.Recordset
      Dim fldDeck As DAO.Field
    
      Dim boolTransActive As Boolean
      Dim nbrCards, nbrRandom As Integer
      Dim strCriteria As String
    
      ' Initialize our Transaction tracking variable
      boolTransActive = False
    
      Set work = DBEngine(0)
      Set rstDeck = CurrentDb().OpenRecordset(strTableName, dbOpenDynaset)
      Set rstVerify = CurrentDb().OpenRecordset(strTableName, dbOpenDynaset, dbSeeChanges) ' Catch updates made from the rstDeck Recordset
    
      Set fldDeck = rstDeck.Fields(strSortIDField)
    
      ' Count the number of Records in the table and then jump back to the first
      ' one
      rstDeck.MoveLast
      nbrCards = rstDeck.RecordCount
      rstDeck.MoveFirst
    
      ' Start the Transaction and set our tracking variable
      work.BeginTrans
      boolTransActive = True
    
      ' Reset all the Field values so we don't run into an infinite loop!
      Do Until rstDeck.EOF
        With rstDeck
          .Edit
            fldDeck.Value = 0
          .Update
        End With
    
        ' Go to the next Record
        rstDeck.MoveNext
      Loop
    
      ' Jump back to the first Record for the next loop and update our other
      rstDeck.MoveFirst
    
      ' Loop through our table assigning a new random number to each Record
      Do Until rstDeck.EOF
        ' Generate a random number
        nbrRandom = Int((nbrCards - 1 + 1) * Rnd + 1)
    
        ' Try and find that number in the table
        strCriteria = "[" & strSortIDField & "]=" & nbrRandom
        rstVerify.FindFirst strCriteria
    
        ' If we find the number, keep generating random numbers until we find one
        ' not in use
        Do While Not rstVerify.NoMatch
          nbrRandom = Int((nbrCards - 1 + 1) * Rnd + 1)
    
          strCriteria = "[" & strSortIDField & "]=" & nbrRandom
          rstVerify.FindFirst strCriteria
        Loop
    
        ' Once we have a unique random number, assign it to the current Record
        With rstDeck
          .Edit
            fldDeck.Value = nbrRandom
          .Update
        End With
    
        ' Move to the next Record
        rstDeck.MoveNext
      Loop
    
      ' Save the database changes and unset the Transaction tracking variable
      work.CommitTrans
      boolTransActive = False
    
      ' Alert the user
      MsgBox "Done!"
    
    FunctionClosing:
      ' CLean up the variables and exit the function
      rstDeck.Close
    
      Set fldDeck = Nothing
      Set rstDeck = Nothing
    
      Exit Function
    
    Error_ShuffleTheDeck:
      ' If the transaction has been started, revert all the changes
      If boolTransActive = True Then
        work.Rollback
        boolTransActive = False
      End If
    
      ' Alert the user there was an error
      MsgBox "An error occurred while attempting to shuffle the deck of cards!" & vbCrLf & _
             vbCrLf & "Message: " & Err.Description
    
      ' Exit the function
      Resume FunctionClosing
    End Function
    All you do is pass the function the names of your Table and the Field (in that table) that holds the "Sort By" ID.

    P.S.
    Because ConneXion has a newer version of Access than I do, I probably can't look at his DB (but I'm gonna try anyway!), but I would assume we came up with similar solutions.
    Last edited by Rawb; 07-20-2010 at 09:06 AM. Reason: Attachments are so HARD!

  5. #20
    bcmarshall is offline Advanced Beginner
    Windows XP Access 2003
    Join Date
    Jul 2010
    Posts
    95

    6 Deck Card Shuffling in Access

    Thank you, Rawb, for the time and effort you put into your solution. I checked out the db you sent and it does indeed work much, much faster than what I had, but in all honesty the solution that Connexion offered is faster still. His takes no longer than half a second to do it all, and probably even less time than that.

    I don't know any way of "downconverting" to 2k from 2003, but I can at least describe what he did as best I can. You deserve it for the effort you put in!

    He has two tables, tblCard and tblShoe, each with 5 fields, Card ID, Suit, Kind, Deck, and Seed, with CardID as an AutoNumber field in the tblCard. The highest seed number is 96,621, and it appears that they are all random numbers between 1-100,000.

    There are two queries, qmakShoe, and qupdSaveSeed.

    Here is the SQL of the qupdSaveSeed.

    SELECT tblCard.CardID, tblCard.Suit, tblCard.Kind, tblCard.Deck, Int((97344-1+1)*Rnd([Seed])+1) AS ShuffleSeed INTO tblShoe
    FROM tblCard
    ORDER BY Int((97344-1+1)*Rnd([Seed])+1);


    And the SQL of qmakShoe.

    UPDATE tblCard INNER JOIN tblShoe ON tblCard.CardID = tblShoe.CardID SET tblCard.Seed = tblShoe!ShuffleSeed;

    Here is the event code attached to the shuffle button.

    Private Sub cmdShuffle_Click()
    On Error GoTo Err_cmdShuffle_Click

    Dim stDocName As String

    DoCmd.SetWarnings False

    stDocName = "qmakShoe"
    DoCmd.OpenQuery stDocName, acNormal, acEdit

    stDocName = "qupdSaveSeed"
    DoCmd.OpenQuery stDocName, acNormal, acEdit

    DoCmd.SetWarnings True

    Exit_cmdShuffle_Click:
    Exit Sub

    Err_cmdShuffle_Click:
    MsgBox Err.Description
    Resume Exit_cmdShuffle_Click

    End Sub
    Private Sub cmdShoe_Click()
    On Error GoTo Err_cmdShoe_Click

    Dim stDocName As String
    Dim stLinkCriteria As String

    Forms![fmnuMain].Visible = False

    stDocName = "frmShoe"
    DoCmd.OpenForm stDocName, , , stLinkCriteria

    Exit_cmdShoe_Click:
    Exit Sub

    Err_cmdShoe_Click:
    MsgBox Err.Description
    Resume Exit_cmdShoe_Click

    End Sub
    Private Sub cmdQuit_Click()
    On Error GoTo Err_cmdQuit_Click


    DoCmd.Quit

    Exit_cmdQuit_Click:
    Exit Sub

    Err_cmdQuit_Click:
    MsgBox Err.Description
    Resume Exit_cmdQuit_Click

    End Sub

    I hope that explains it well enough for you to reproduce it. I sincerely appreciate everyone's efforts on my behalf, and I finally have what I need and can move on to finishing writing the program and doing the evaluations that I've been longing to do for some time.

    Connexion, if you're looking in I'd like to ask something. Each card has a random seed number, the lowest being 244 and the highest mentioned at 96,621. Is there ever a possibility where the card with the lowest seed would ever be the first card in the deck, and conversely whether the one with the highest seed number could ever be the lowest card in the deck?

  6. #21
    ConneXionLost's Avatar
    ConneXionLost is offline Simulacrum
    Windows XP Access 2003
    Join Date
    Jan 2010
    Location
    Victoria, Canada
    Posts
    291
    Hi again,

    I'll attach a "2000" version for Rawb, et al.

    Thanks for posting the SQL and code.

    After a second look, I thought it would be better to modify the make table query slightly, here's the new SQL of the qupdSaveSeed:

    SELECT tblCard.CardID, tblCard.Suit, tblCard.Kind, tblCard.Deck, Int((97344-1+1)*Rnd([Seed]+[CardID])+1) AS ShuffleSeed INTO tblShoe
    FROM tblCard
    ORDER BY Int((97344-1+1)*Rnd([Seed]+[CardID])+1);

    The form code doesn't do much. The action is in the queries. Each Shuffle generates a new "seed" for each card, then just sorts on the seed. As Ted C explained, you don't need to use 1-312 for this. In fact I used 312x312=97344 as a lark. After that, each new seed is based on the previous one plus the ID just to ensure they'd be different each time. If you choose, you could number the records after the fact; it's up to you.

    "Is there ever a possibility where the card with the lowest seed would ever be the first card in the deck?" Yes, every time (because I sort the seed in the shuffle), but as I mentioned, each card gets a new random seed for each shuffle.

    Cheers,

  7. #22
    bcmarshall is offline Advanced Beginner
    Windows XP Access 2003
    Join Date
    Jul 2010
    Posts
    95
    Thanks again, Connexion. I updated the query with the new sql. It's really, really fast. It takes me more time to blink than it does to shuffle six decks.

    I've got another question. I never intended this to be anything more than an analytical program, so graphics were never a consideration. In fact, in my original shuffle routine I made no provision for suit, since for analytical purposes a six of clubs or diamonds is still a six, but your routine does include suits. I'm just wondering if you know how I can interface cards.dll with the routine. If I can utilize the graphics without too much effort it would be nice.

  8. #23
    BizIntelGuy is offline Novice
    Windows XP Access 2002
    Join Date
    Jul 2010
    Posts
    3
    Why not just use a legit programming language?

  9. #24
    bcmarshall is offline Advanced Beginner
    Windows XP Access 2003
    Join Date
    Jul 2010
    Posts
    95

    6 Deck Card Shuffling in Access

    Porque no los hablo.

    Parce-que je n'en parle pas.

    Ummm...because I don't speak them!

  10. #25
    bcmarshall is offline Advanced Beginner
    Windows XP Access 2003
    Join Date
    Jul 2010
    Posts
    95

    6 Deck Card Shuffling in Access

    I originally asked for, and received, a great routine that shuffles the cards very fast and stores the shuffle in a table. After posting it in this and other forums, the suggestion was made that a deck could be represented with a single number, something I had not considered before. Since one of my interests is to be able to store many given decks, I'm now realizing that it would be 312 times easier to store one number than a six-deck shuffle.

    Does anyone know of a way to convert that shuffle into a single number, and then convert the number back into the shuffle?

  11. #26
    bcmarshall is offline Advanced Beginner
    Windows XP Access 2003
    Join Date
    Jul 2010
    Posts
    95

    6 Deck Card Shuffling in Access

    Connexion, it's been several months since I started this thread and since you provided a really good solution for me. I've been sidetracked with a million different things and haven't really focused on using what you sent until now. I modified the routine slightly to provide an additional field which contains a numerical value for each card for the purpose of calculations, converting JQK to 10 and A to 11.

    The routine you sent works perfectly to shuffle the shoe. However, I'm still trying to sort out the best way to save the shoe so that it can be recalled and replayed as a constant. I want to evaluate the exact same card sequence played and/or betted differently to determine the best play. After playing through a shoe the number of wins and losses can be determined and a decision made as to whether that was a good or bad shoe.

    Ultimately I'd like to group a whole bunch of really bad, good, and average shoes for the player together, so that the most advantageous strategy can be developed for that scenario. I would run 20, 50, 100, or more known bad shoes one after the other, or a similar number of good shoes. That isn't meant to simulate casino play, but instead to develop the optimum way to play when the cards are going for me or against me.

    Either way it would require creating three new tables, calling them GoodShoe, AverageShoe, and BadShoe, as an example, and saving the shoe to the appropriate table after playing through the cards and deciding which category it falls into.

    I see two ways to accomplish saving the shoes. One is to save the entire shoe as a 624 character string in a Memo field in those tables. That obviously requires conversion of the shoe into a string, and then the reversal of that process to convert the string back into a shoe for play.

    The other way is to run an append query which would just add the current shoe to the records already stored in the appropriate table. Since each shoe is exactly 312 records long, a select query could later be run, selecting as an example records 313-624, which would isolate only the second shoe from the larger list.

    The second option seems cleaner, yet ultimately I would have many more records to sort through. 100 shoes would be over 31k records, which seems cumbersome even if it's not an unmanageable number. The first option would have only as many records in each table as there are shoes stored, so that seems to be an advantage. I'd like to ask your feedback as to which you think is more practical, and of course, whether you can think of another alternate method of accomplishing the same thing.

    I'd also like to ask for some assistance in the conversion to string and reconversion back to shoe should you believe the first option more practical. I'm not certain of how to proceed with this, and any ideas or solutions you can provide to accomplish it would be appreciated.

    There are always dozens of ways of accomplishing something. Since I'm in the very early stages I have the option to select the most logical before moving farther along, and I'd like to choose wisely.

  12. #27
    ConneXionLost's Avatar
    ConneXionLost is offline Simulacrum
    Windows XP Access 2003
    Join Date
    Jan 2010
    Location
    Victoria, Canada
    Posts
    291
    Hi,

    Access doesn't fret over the number of records, only the size of the database, and 31K records isn't much. Look up the word "specifications" in the Access Help and check the table size limit.

    I recommend the append method, but I only see you needing one other table [tblShoeBox] unless you want to get fancy with descriptors for each shoe (if so, then you'll want to use two more tables and probably rename some of my original tables). I also suggest you add a field [ShoeID] in [tblShoeBox] to identify the shoes for each 312 card shuffle (so if you call for [ShoeID]="GoodShoe88", you will get the 312 cards from that shoe.


    Cheers,

  13. #28
    bcmarshall is offline Advanced Beginner
    Windows XP Access 2003
    Join Date
    Jul 2010
    Posts
    95
    Thanks. The append query it is. There's surely no extra messing around with it!

    I've got another question. Of course a shuffle is a shuffle, but casinos always do two other steps. They cut the deck and burn the first card after the cut. I want to take my cards through the exact same steps. Of course I don't think it matters one way or the other as far as outcome is concerned, but I want to duplicate what is done in real life as closely as possible, and if they do it I should too.

    I already accomplished both tasks, but I'm sure there's a better way, and I'm just asking for advice. After the shuffle, I select a random number between 52 and 260 (you can't cut closer than one deck to either end), go to that number record, select the record, and then use SendKeys (yeah, I know the purists hate that) to select all the records from the cut record to the top. I then use a Cut command and move to a new record, select it and then paste. That's the cut.

    The process is virtually identical for the burn. I just select the first record, cut it, go to a new record and paste it. I still have all 312 records in the set and I'm ready to play.

    I don't particularly like using the SendKeys and cut and paste. Any easier ways you can think of? The sequence works very well, of course, and ultimately what matters is that the job is done consistently, but it does slow the process down a bit. It's not much, and the whole operation takes maybe a second or second and a half, but it's still slow compared with the extremely fast shuffle routine you provided.

    Again, any feedback would be appreciated.

  14. #29
    ConneXionLost's Avatar
    ConneXionLost is offline Simulacrum
    Windows XP Access 2003
    Join Date
    Jan 2010
    Location
    Victoria, Canada
    Posts
    291
    Shuffling cards

    For the cut; I guess I'm not clear on what you mean. Are you cutting the cards/deck or cutting the shoe?

    If you're cutting the deck, then I can't help but think you're wasting your efforts. Access isn't likely going to cheat, so there's nothing to gain from building a procedure to simulate a cut. But if you insist, and you already have a procedure to "cut", then the second you spend waiting for the "cut" sequence to run should satisfy your suspicions, or desire for "luck".

    "The practice of cutting is primarily a method of reducing the likelihood of someone cheating by manipulating the order of cards to gain advantage. Even if the dealer does not plan on cheating, cutting will prevent suspicions, thus many rules require it. Some players also consider the cut to be lucky."

    However, if you're cutting the shoe, then simply selecting a random card number to stop play would be sufficient; no need to "move" the cards around for that.

    The burn card seems to be a different matter. I'm suprised to learn you return the burn card to the end of the deck; unless you also "cut the shoe" so the burn card is never played.

  15. #30
    bcmarshall is offline Advanced Beginner
    Windows XP Access 2003
    Join Date
    Jul 2010
    Posts
    95
    Of course I know that Access isn't going to cheat, and a shuffle is a shuffle. I just want to simulate everything, and for the amount of effort involved (maybe a half hour) I know that when I'm actually playing the game, everything involved in the shuffle is as close to the real thing as possible. It's probably a really anal attitude, but as I said, it wasn't much effort and although there is a small efficiency sacrifice I like knowing that I've reproduced every step of the casino's efforts as closely as I possibly can.

    I'm cutting the entire shuffled shoe. In the casino after all six decks are shuffled together the last thing that's done is to randomly insert a cut card into the shuffled stack of cards, move all the cards from the front of the cut card around to the back of the shoe, insert the red card, place the stack into the shoe, and burn the top card. I'm reproducing all of that.

    I already have a red card instruction written in, the point beyond which no new hands are dealt and only the play already on the table is continued until completed. My local casino advised me that their red card point is about 2 1/2 decks from the end, so it was a simple matter to generate a random number in that range and set it as my red card point, which will be stored along with the rest of the shoe information. As cards are dealt from the shoe they are counted, and when the count exceeds the red card point a new shoe is called. If I didn't save the red card point, I would not be able to consistently and reliably reproduce the play even though I saved the shoe sequence, since I might deal less or more cards out of it one time through vs. another.

    I returned the burn card to the bottom of the shoe just to keep the 312 card shoe intact. It's really irrelevant, since the card is never played. I could just as easily delete it.

    Do you have any thoughts on a better way to cut the shoe? What I have works just fine, as I'm sure you can visualize from the description. I just thought there might be another way besides the SendKeys, and cut/paste operation I selected.

Page 2 of 3 FirstFirst 123 LastLast
Please reply to this thread with any new information or opinions.

Similar Threads

  1. Credit Card Info, Where?
    By mastromb in forum Access
    Replies: 3
    Last Post: 05-26-2010, 12:37 AM
  2. Import with a wild card
    By ukgooner in forum Import/Export Data
    Replies: 3
    Last Post: 09-09-2009, 08:08 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Other Forums: Microsoft Office Forums