Card Shuffling Function

So I’m trying to build a Blackjack engine inside my game. I have most of it working, when you click the Deal button it deals two cards, when you click the Hit button it deals another card, etc. The way I have it set up, there is a “NewCard” object that has 53 animations (1 card back, and 52 separate animations for the individual cards). When a “NewCard” is created, it’s automatically set on the card back (animation 0), then it shuffles the card through the animations. When it meets certain criteria, picks an animation, deletes the “NewCard” object, and creates a “DealtCard” object in its place that has the animation the “NewCard” settled on.

My trouble is with the criteria for the “NewCard” object settling on an animation. The goal is to have it keep rolling until it lands on an animation that is not animation 0 or the same animation as a “DealtCard” object on the screen. However, it’s only working for the first “DealtObject” instance created. When a “NewCard” is created, it scrolls past animation 0 and whatever animation the first “DealtCard” is set to, but it ignores the second instance of “DealtCard” and is totally okay with landing on its same animation. Is there any way to tell it not to land on the current animation of any instance of object “DealtCard”?

Can I see some events?

To generate a random non repeated number, you can use:

  • A structure with (initially) 52 childrens, that let you know wich values you have already used. For example, the first dealt card is a random number between 1 and 52, let’s say it was 10 (10 of Diamonds): Create the dealt object with the animation 10 (the value of the children), “move” the last children (52 = K of Hearts) to the position of 10 (set structure[“10”] = 52), and finally delete the children 52. Now you have a structure with 51 childrens, without the 10 of Diamonds, because the children 10 has the value of 52. The next card to deal has to be a random number between 1 and 51, without the risk to generate a repeated number:

Deck: Deck: Deck: 1 1 1 1 1 1 2 2 2 2 2 2 ... ... ... ... ... ... 10 10 <-- you take this 10 52 <-- move last child here 10 52 ... ... ... ... ... ... 52 52 52 52 51 51 <-- delete last child
You’ll need an extra variable “size” so keep track the structure length, if the new expressions to get the structure size don’t exist in your GD version :wink:

  • A while loop (brute-force-like), you generate a random number, if the generated number is already a dealt card, generate a new one, check, and so on:

Conditions: Conditions to deal a card Actions: Do = 1 to variable already_dealt // just to start the while loop //Sub-event While: Variable already_dealt is = 1 Conditions: No conditions Actions: Do = Random(52) to variable random_card // generate a new random number Do = 0 to variable already_dealt // non repeated by default //Sub-event For each DealtObject, repeat: // now let's check if really is not repeated, against every dealt object Conditions: Animation of DealtObject is = Variable(random_card) //oops, it is repeated Actions: Do = 1 to variable already_dealt // set as repeated, so the while loop generates a new number
Note that the While loop will need more loops if there are a lot of dealt cards, for example if you have only one card in the deck (51 cards dealt), in average the while loop will need 52 loops to get that last card number.

I can help more if you show me some events, so I can tell you where to place the events, and use some already created variables :slight_smile:

Just would like to add, you can also use the new inventory extension.

At the beginning just add 52 items to an inventory with the name 1,2,3,4…52. Each item would represent a card in the deck and you can even call the inventory as"deck"

After, when you are about to take a card from the deck, just create a random number and check if the item with tha number as name is available in the “deck” or not.
If it available, create a card with tha animation displayed and remove item from the “deck”.
In case it is not available then generate a new random number until find one that is available using the while loop.

Each player could have it own inventory and just move the items/cards between the inventories by simply remove/add items and check which item/card is present in which inventory.
Also, from experience, instead of creating and deleting card objects, it easier to make a card game if objects are permanently present in the scene to display cards but displaying an empty animation or hidden when don’t needed and it become visible and display an animation only when needed. Basically think of it as empty slots waiting for information to display a card.

2 Likes

What I have currently is basically what you’re describing as a While Loop; every time you generate a card, it randomizes, it’s supposed to check to see if the card exists, and if it has it creates a new one. The trouble is stemming from the fact that the cards it’s checking are multiple instances of the same object, each displaying different animations between 1 and 52. Here’s what the code looks like:

1. The number of NewCard is =1	|	Do =”Yes” to the text of global variable Gambling.Shuffling

2. The text of global variable Gambling.Shuffling is =”Yes”	|	Do =Random(4) to the number of current animation of NewCard

3. If the number of the current animation of NewCard is !=0	|	Do =”No” to the text of global variable Gambling.Shuffling

4. The text of the global variable Gambling.Shuffling is =”No”	|	Create object DealtCard at position Newcard.X(); NewCard.Y(), Do =NewCard.Animation() to the number of current animation of DealtCard; Delete object NewCard; Do =”Standby” to the text of global variable Gambling.Shuffling

I’m currently using 4 card to test out if this is working, so the NewCard and the DealtCard objects have 5 animations, 0 being a card back and 1-4 being actual cards. When the NewCard is created, it’s on animation 0; the game checks the NewCard object to see if it’s at animation 0, and if it is it shuffles a random animation.

The shuffling state is currently set to be based on a variable with three states; Standby (initial variable), Yes, and No. When the NewCard object is found to be at animation 0, the Gambling.Shuffling variable changes from Standby to Yes; the game randomly changes NewCard’s animation; the game checks to see if the animation is either 0 (a card back) or the same animation as the DealtCard object already in play, if it isn’t it sets the variable Gambling.Shuffling to “No”; when the variable Gambling.Shuffling is on “No”, it creates a DealtCard object in place of the NewCard object, changes the DealtCard object’s animation to the same animation as NewCard, and deletes the NewCard.

All of this is working fine except for when it checks current animation of the object DealtCard; the way this is set up, there are multiple DealtCard objects on the screen, each displaying a different animation. It’s only checking the first one, but it’s ignoring any of the additional DealtCard objects.

All that said, I think I have an idea, based on ddabrahim’s suggestion of hidden cards used to display the dealt cards. If I keep a number of cards for each player hidden, then set them to copy the NewCard object’s chosen animation and become visible when the NewCard object randomized its animation, then set the NewCard to not copy the animation of any visible DealtCard objects (which would each be separate objects in this case), I think it will work.

EDIT: Yep, that’s the solution. I put in a variable that counts how many cards are on the table (the variable goes up by 1 every time the Deal/Hit button is pressed), and at each stage the game will check existing DealtCards’ animations and rule them out, randomly pick a new number for NewCard, then assign the animation of NewCard to a hidden DealtCard object and make it visible. Because there’s only four animations currently available, once all four are used up, the NewCard object just shuffled infinitely, but never lands on an existing one. Once I have all 52 cards in there, it will be all set up.