Keeping a poker face
April 13, 1998
by Pat McClellan
Dear Multimedia Handyman,
I'm creating a Director poker game and I need to figure out how to deal the cards randomly. I know there's a random() function, but that only works for numbers. My cards are named as follows with the suit as a letter after a 1 character value: Hearts - AH, 2H, 3H, 4H, 5H, 6H, 7H, 8H, 9H, TH, JH, QH, KH.
Signed,
Joker's Wild
Dear Joker,
You're on the right track. What you need to make the link between the random() function and the names of your cards is a list. Lists are extremely powerful stuctures for holding and processing data. To design our lists, we need to consider the nature of your game. When you deal a well-shuffled deck of cards, the first card is a 1 in 52 selection. The next card is a 1 in 51 selection and CANNOT be the same card as the first card dealt (because the first card has been removed from the list of possible cards). Each subsequently dealt card is pulled from a smaller and smaller pool of possible cards.
Let's start by generating a list of the full deck of cards. This handler will only need to be executed once, because we are not going to alter the full deck list.
on makeFullDeck global gFullDeck -- initialize the list set gFullDeck = [] set valueList = ["a","2","3","4","5","6","7",¬ "8","9","t","j","q","k"] set suitList = ["H","D","C","S"] repeat with whichSuit = 1 to 4 set thisSuit = getAt(suitList, whichSuit) repeat with whichValue = 1 to 13 set thisValue = getAt(valueList, whichValue) set thisCard = thisValue & thisSuit append (gFullDeck, thisCard) end repeat end repeat endAfter running this handler, the global variable gFullDeck will contain a list (in order) of all the cards of the deck, designated by the naming convention you suggested in your question. Examples: Ace of Diamonds = "aD"; 3 of Hearts = "3D"; 10 of Spades = "tS"; King of Clubs = "kC". The important thing to realize is that this "full deck" is not shuffled.
Now, let's create a copy of that list that will serve as our game deck. This is the list that we'll deal from, so the values will be eliminated from the game deck as we go. Then, when we need to start a new game, simply reset the game deck = a copy of the full deck. NOTE: you can't simply set gGameDeck = gFullDeck.
on startNewGame global gFullDeck, gGameDeck set gGameDeck = duplicate(gFullDeck) end
This is where we need to figure out how to draw a random "card" from the gGameDeck, and then remove that value from the possible future choices. We'll use the random(), getAt(), deleteAt(), and count() functions. Count(gGameDeck) is a way to refer to the number of cards left in the game deck without actually keeping track of how many are left. We'll also need to make sure that all the cards have not already been dealt. After selecting the card, I'll put the cast member of the same name in sprite 5 (as an example).
on dealCard global gGameDeck set cardsLeft = count(gGameDeck) if cardsLeft = 0 then alert "No More Cards." end if set whichPick = random(cardsLeft) set selectedCard = getAt(gGameDeck, whichPick) deleteAt(gGameDeck, whichPick) set the member of sprite 5 = member selectedCard endNote that I only used the random() function once in the handler. An easy mistake is to do the following:
set selectedCard = getAt(gGameDeck, random(cardsLeft)) deleteAt(gGameDeck, random(cardsLeft))In this case, you are selecting one card, but deleting another. The term random(cardsLeft) will return a different value each time you use it. Therefore, it is necessary to set a variable to that random selection and then use the variable to select and delete the same card.
That's all there is to it. Good luck with your program... but then, I guess you don't need luck when you know how to control the cards!
Copyright 1997-2024, Director Online. Article content copyright by respective authors.