How to Make a Memory Game - Page 3

Step 2: Let's think with code

OK, now how can we do all this in the computer?

Well, lets use an array to represent the deck. We'll have N number of pictures, and we want to take X of them out and use them as cards. Essentially each value in the array will be it's own number plus 1. So array index 0 will be picture 1, and so on.

Don't forget when reading code, that "//" and "/* stuff here */" are comments for viewers, not the computer. We can create a deck of cards with a createDeck() function. The function would be pretty simple:

The above function creates the aforementioned deck model. It simply requires a global variable called picCount which would hold the number of pictures we're going to have total. Whenever you add a picture, be sure to adjust picCount accordingly. Now that we have a deck we need a means of shuffling it.

How in the world can we do this? We have a deck set as an array. One option could be to randomly pick 2 elements from an array and switch them. But then how many times do we have to do this operation before we can be sure the deck is properly shuffled? At least twice the deck size right? I've got an idea.

We take out a card randomly and set it in a new pile. We keep randomly grabbing one card until the new pile is full and the old pile is gone. Our new pile will be a random set of our original set of cards.

LOGIC MONSTER! Logic monster sez that pulling a card out of a deck is easy, the stack falls down instantly and the missing slot is erased, but if you have a deck on a computer, of 5 billion cards and you remove the middle, then 2.5 billion cards have to be moved down by one spot. Each one taking a lot of computer time.

The logic monster is right. Lists are more difficult for a computer to manage than in real life. When a card is moved out of a deck, the whole stays there, and each other card has to be TOLD to move down. This is compounded by the difficulty that we've chosen to use an array, and that we have allready allocated the computer space 2 full decks. It would suck to move to 3, 4, 5 or even X decks of space just to sort 1 deck.

The way I'd like to handle it, isn't really the best way in the world, but it works and it's fast. Basically, it works like this:
We choose a card from the deck, we copy it to our new spot. If it's already in the new deck, we throw it away, if it's new we leave it. Eventually, we'll have randomly selected every card and copied them into our new deck. When this is done, we throw the old deck away and we have shuffled.

We don't need to shuffle often, otherwise a more advanced algorithm would be needed.

Here's what the code for the shuffling looks like:

/*
* Function shuffle - when given a deck of N cards (array) the
* shuffle will return a deck of N cards with the same elements
* of the given deck in random order
*/
function shuffle(deckOld) {
// creating the deck we will return
deck = new Array();
// fill array of cards with unique pics
do {
//*** NOT INDENTED FOR WEB PAGE PURPOSES ***
newRandom = Math.floor(deckOld.length*Math.random());
deck.push(deckOld[newRandom]);
// copy array
scanData = new Array();
scanData = scanData.concat(deck);
// if last added was duplicate, than remove.
if (scanData.sort(Array.UNIQUESORT) == 0) {
deck.pop();
}
} while (deck.length

We use the datastructure of a stack which is very common in computer science. Flash has built in functions for the stack, which makes the entire process more quick. Infact, whenever you use a Flash MX function instead of a custom written one, the program execution is usually much faster. This has to do with the level at which the code is run. Actionscript is run as a script, whereas the inate functions of Flash reside in executables and DLLs.

So now we can create a deck and shuffle it. How are we going to go about dealing the cards now?

WELL, lets just make a deal function. We tell it how many cards to deal, and we'll give it the empty deck. The deal function will shuffle the deck, take P cards from the top, copy them and shuffle those. Then deal them out. Dealing the cards will just be making a copy of a card, place it's X and Y positions and since all these cards aren't real, we'll have to tell that card which picture to show. Here's our finished deal function.

rowBreak is a variable that tells us how many cards per row. We can set this to dynamically break the card deals into rows at any rate. The variable deck1 is filled with the shuffled version of the deck passed down. We then take off only a portion of the cards and toss the rest. This is done with the slice function. We basically slice off the top and put that back into the deck, the others fall to the ground:deck1 = deck1.slice(0,uPic);

deck2 is then comprised of a shuffled version of deck1 and we've got our cards ready to go.

We create the card, then we set 3 things. We tell it what x position, y position and which picture to display.
-xpos is mostly controlled by the wrapping number moveX, as the cards grow to rowBreak.
-ypos is controlled by moveY, which is just going to keep going at every rowBreak it gets larger.
-curPicNum is the variable that controls what picture each card should show. As you can see, we've made a card movieclip that will want to know which of it's picCount pics to show. Without setting the card movieclip to stop on a particular picture, it would simply cycle through the pictures continuously.

» Description:
I created this font for free use. Everyone can apply it in personal or business texts. Its free, but I want to be communicated in case of business use. Donations are accepted to keep the project of free fonts alive! Thank you all