Shuffling data isn’t just something that a card game might need — in my game Match Game Magic I needed to shuffle picture objects between each level. In this article I’ll introduce you to some code that might help in your game.
Even though it’s not just card games that can make use of shuffling, for this example I’m going to use a set of playing cards. Let’s create a complete deck using a table:
1 2 3 4 |
completeDeck = {"CA", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "C10", "CJ", "CQ ", "CK", "HA", "H2", "H3", "H4", "H5", "H6", "H7", "H8", "H9", "H10", "HJ", "HQ", "HK", "SA", "S2", "S3", "S4", "S5", "S6", "S7", "S8", "S9", "S10", "SJ", "SQ", "SK", "DA", "D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9", "D10", "DJ", "DQ", "DK"} |
That gives us a deck of cards, Ace through King of Clubs, Hearts, Spades, and Diamonds. We could grab all four Aces like this:
1 2 3 4 |
print( completeDeck[1] ) -- CA print( completeDeck[14] ) -- HA print( completeDeck[27] ) -- SA print( completeDeck[40] ) -- DA |
Before The Shuffle
Let’s skip ahead (or sideways) and look at ways to turn that table of strings into actual card graphics. I grabbed a set of cards from wikimedia.org and named them the same as the strings in the completeDeck table, so the files showing the aces are CA.png, HA.png, SA.png and DA.png, which means you can use the value returned from the table to display any card.
For example, this would show the Six of Spades:
1 |
local card = display.newImage( completeDeck[32] .. ".png" ) |
This technique makes it easy to work with 52 different graphic files without shuffling around the actual names of the files.
The Shuffle Function
When I realized I needed to shuffle some data I buckled down and started coding. Um, not really, I Googled for something that was already done. I’ve been programming since 1984 and could write a shuffle routine in my sleep, but I’d rather spend time doing stuff that’s more fun. 🙂
You can find a shuffle routine in the Ansca Mobile’s Code Exchange — or this is the one I ended up with (which is very similar):
1 2 3 4 5 6 7 8 9 |
local function shuffle(t) local n = #t while n > 2 do local k = math.random(n) t[n], t[k] = t[k], t[n] n = n - 1 end return t end |
You can work through it if you want; for me all I care is that I can pass in a table and get back the table after it’s been shuffled. (You get like that after you’ve been around the block a time or two.) It a nutshell, it runs through the table, grabs two values and swaps them.
Okay, we’re done, eh?
Not quite, because there’s a hidden pothole you’ll run into if you’re not careful.
Avoiding The Pothole
Take a look at this chunk of code:
1 2 3 |
local deck = completeDeck deck = shuffle(deck) displayDeck(deck) |
First we make a copy of the complete deck of cards, then shuffle it, and then display it. No problem.
Except that when you do this:
1 |
local deck = completeDeck |
…you’re not actually making a copy of the table, you’re making a new “pointer” to the existing table. So when you pass deck into the shuffle() routine, you’re actually shuffling the completeDeck original.
That may not be a problem if you never need the original ordered deck, but I kind of like to keep my original data “original” so I can start from scratch again during the game if I need to, so let’s look at the way to solve the problem.
Here’s a routine that takes a table you pass in and passes back an exact duplicate — not just a pointer to the original.
1 2 3 4 5 6 7 |
function table.copy(t) local t2 = {} for k,v in pairs(t) do t2[k] = v end return t2 end |
Now you can shuffle, fold, spindle, or mutilate the duplicate table and your original data is still safe and sound.
If you’d like to download the entire sample project, including the 52 card graphics, join Game Dev Nation (It’s free!) and the download link will appear in this spot after you confirm your registration via email and log back in.
Please click the Like button below if you appreciate this tutorial. 🙂
Exactly what I was looking for. Thanks Jay!
[…] In the app you would be able to choose your favorite horse, use brushes and such to groom… Shuffling Your Data | Game Dev Nationhttp://gamedevnation.com/lua/shuffling-your-data/Shuffling data isn’t just something that a card […]
Hi.. nice post.. very useful