Chapter 15. Casino and Card Games

Casino and Card Games

Gambling games have always been a popular genre of computer games. The Web is full of casino and card games in Flash, Shockwave, and Java. Most are just for fun, but some allow you to bet real money.

In this chapter, you’ll look at four just-for-fun casino games. The first is a pure game of chance: a slot machine. Next, you’ll see how to make a video poker game. Then, you’ll look at a game that requires a little more skill for the player: blackjack. The final game is one of my favorites: pyramid solitaire, the most fun of all the solitaire games.

Tip

Tip

I’d like to warn developers about the difference between a just-for-fun casino game and a real one. Real casino games that involve real money or prizes require complex security programming to make sure the player can’t cheat by hacking at the data on his computer or the data sent over the network. A developer who accepts a project to build a real casino game should be an expert in computer and network security, not just a Flash expert. Even if you are an expert at both, proceed with great caution in accepting such a project: It will be difficult and probably cause you many headaches.

Slot Machine

Slot MachineExample file: Slotmachine.fla

A slot machine is a simple type of game, but with a somewhat complex interface. The player simply clicks the slot machine’s lever to pull it, and then waits for the result. The slot machine does the rest of the work.

Figure 15.1 shows the example movie slot machine. The lever to the right is the only part with which the player interacts. The three windows each present a different item when the slot machine is done.

A simple slot machine with a lever and three windows.

Figure 15.1. A simple slot machine with a lever and three windows.

Project Goal

Although some slot machines have many strange and interesting ways to bet and win, this one is simple. The player clicks to pull the lever. Then the wheels in the three windows appear to spin. One by one, they stop on a random item.

When all three wheels stop, the three items showing determine the outcome of the turn. The amount won is equivalent to the amounts shown at the bottom of the machine in Figure 15.1.

Approach

The only difficult part in this game is the spinning. One way to do it would be to have different items move from bottom to top through the window. The problem with this approach is that they would have to move very fast to appear to be spinning as fast as real slot machine wheels spin. Flash just can’t animate things at that speed on most computers.

Instead, you can use a blurry spin animation. This animation is a few frames of blurred color in a movie clip. Figure 15.2 shows a few of these frames.

These frames of animation create the effect of a spinning wheel when played rapidly.

Figure 15.2. These frames of animation create the effect of a spinning wheel when played rapidly.

Each of the three windows has a copy of the “spin” movie clip. When it’s time for the wheels to spin, all three of these movie clips are told to play, and told precisely how many times to loop. They are given different numbers so that the wheels stop spinning at different times.

Check out the example movie Slotmachine.fla to see how the wheels spin and stop at different times.

Preparing the Movie

There are three key library elements in this movie. All the rest are just background elements. The first element is the lever. The first frame has a button on it that the player can click. The rest of this movie clip is an animation of the lever being pulled.

The “spin” movie clip starts with a blank frame where the “spin” movie clip waits until the player pulls the lever. The frame is transparent so that the “symbols” movie clip can show through.

The rest of the frames in the “spin” movie clip contain the blur animation shown earlier in Figure 15.2. Behind these images is an opaque white field that covers the “symbols” clip while the wheels are spinning.

The “symbols” movie clip contains seven frames, each with a different symbol on it. In the example movie, the symbols include an acorn, apple, leaf, log, moon, sun, and fox.

Writing the Code

Most of the code for this game creates functions in the main timeline. However, let’s start by looking at all the pieces of code found in the movie clips.

In the example movie, if you move the lever from its current spot, you will see a button under it. Attached to this button is a simple script that calls the “pull” function in the main timeline:

<LINELENGTH>90</LINELENGTH>
on (release) {
    pull();
}

The “spin” movie clip has two short scripts in it. A plain stop() command appears on the first frame. A script that reduces a counter called “numTimes” by one appears on the last frame. If this counter is 0, it returns the movie clip to the first frame and notifies a function in the main timeline. Otherwise, it causes the movie clip to loop back to frame 2.

<LINELENGTH>90</LINELENGTH>
numTimes--;
if (numTimes <= 0) {
    gotoAndStop(1);
    _root.spinDone(_name);
} else {
    gotoAndPlay(2);
}

Much of the code in the main timeline deals with determining how much money, if any, the player won on the spin.

The code starts, however, by setting each of the three symbols to a random frame, and giving the player $100 in “cash”:

<LINELENGTH>90</LINELENGTH>
initGame();
stop();

function initGame() {
    // start three symbols out randomly
    for(i=1;i<4;i++) {
        _root["symbol"+i].gotoAndStop(randomSymbol());
    }
    // start cash at $100
    cash = 100;
    showCash();
}

Rather than display the player’s cash as a plain number, the next function places a dollar sign, followed by the “cash” variable into “displayCash.” This variable is linked to a text area on the Stage.

<LINELENGTH>90</LINELENGTH>
// display cash with $
function showCash() {
    cashDisplay = "$"+cash;
}

When the user clicks on the lever button, several things happen. First, $1 is subtracted from the player’s cash. Next, the “arm” movie clip is sent to frame 2 so it can animate the lever going down. Then, all three “spin” movie clips begin animating. Each clip starts with a different “numTimes” setting—8, 6, and 4—to make the first animation loop 8 times, the second 6, and the third 4.

The result of each spin is also determined at this time. The “symbol” movie clips are set, although they are hidden behind the opaque “spin” animations until they are done.

<LINELENGTH>90</LINELENGTH>
// pull the handle
function pull() {

    // deduct $1 per pull
    cash--;
    showCash();

    // play arm animation
    _root["arm"].gotoAndPlay(2);

    // tell spin animations to go
    for(i=1;i<4;i++) {
        // tell spin animations how many times
        _root["spin"+i].numTimes = 8-i*2;
        _root["spin"+i].gotoAndPlay(2);
    }

    // pick a random result for each symbol
    for(i=1;i<4;i++) {
        _root["symbol"+i].gotoAndStop(randomSymbol());
    }
}

The way a random symbol is picked is not simple. If each of the seven symbols had an even chance of appearing, then each matching outcome would have the same chance of happening. In other words, three acorns would appear as often as three foxes. This would mean that having different payouts for different matching sets wouldn’t make sense.

Tip

Tip

Actual slot machines have a surprisingly complex method for picking the symbols that end up in the windows. These methods involve complex mathematical formulas so that the casino can control exactly how much of a chance the player has of winning.

Instead, each symbol needs to have a different chance of appearing. A log symbol, for instance, appears 29% of the time. A fox symbol, on the other hand, appears only 6% of the time.

The way this is done is by placing the relative chance of a symbol appearing into a list. Then, a random number is picked. If this random number falls within the percentage chance of the first symbol, then the first symbol is picked. If not, then the code proceeds to the next number in the list. This is done until a symbol is picked. Walk yourself through the following code to see how it works:

<LINELENGTH>90</LINELENGTH>
// choose a random symbol based on probability calculations
function randomSymbol() {
    // get chances of each symbol appearing
    chances = [29,21,16,12,9,7,6];

    // determine total count of chances
    totalChances = 0;
    for(j=0;j<chances.length;j++) {
        totalChances += chances[j];
    }

    // pick a random number
    r = int(Math.random()*totalChances);

    // determine which symbol the number represents
    for(j=0;j<chances.length;j++) {
        if (r < chances[j]) {
            return(j+1);
        } else {
            r -= chances[j];
        }
    }
}

When a “spin” movie clip is done animating, it calls the “spinDone” function with the name of the movie clip instance. Movie clip “spin1” is singled out as the last animation in the sequence. When this one is done, the “calcWin” function is called to determine the winnings.

<LINELENGTH>90</LINELENGTH>
// called by each spin animation
function spinDone(name) {

    // see whether this is the last symbol to stop spinning
    if (name == "spin1") {

        // calculate winnings
        win = calcWin();
        cash += win;
        showCash();
    }
}

The “calcWin” function determines whether all three symbols match. It also counts the number of acorns in the sequence. If all three match, then the amount won is determined by which symbol it is. If there is no match, the player can still win a little with one or two acorns present.

<LINELENGTH>90</LINELENGTH>
// determine how much the player won
function calcWin() {

    // how many acorns
    numAcorns = 0;
    for(i=1;i<4;i++) {
        if (_root["symbol"+i]._currentFrame == 2) numAcorns++;
    }

    // is it three matching symbols?
    firstSymbol = _root["symbol1"]._currentFrame;
    threeOfAKind = true;
    for(i=2;i<4;i++) {
       if (_root["symbol"+i]._currentFrame != firstSymbol) threeOfAKind=false;
    }

    // determine payout of three matches
    if (threeOfAKind) {
        if (firstSymbol == 1) {
            win = 20;
        } else if (firstSymbol == 2) {
            win = 10;
        } else if (firstSymbol == 3) {
            win = 30;
        } else if (firstSymbol == 4) {
            win = 50;
        } else if (firstSymbol == 5) {
            win = 80;
        } else if (firstSymbol == 6) {
            win = 100;
        } else if (firstSymbol == 7) {
            win = 1000;
        }

    // two acorns
    } else if (numAcorns == 2) {
        win = 2;

    // one acorn
    } else if (numAcorns == 1) {
        win = 1;

    // nothing
    } else {
        win = 0;
    }

    return(win);
}

Loose Ends

If you look at the example movie, you will see that the slot machine background is actually in the foreground. The three windows are holes in this image where the symbols and spin animations show through.

You might also want to decide what to do when a player reaches $0. You can check for this condition and then branch to another frame when it happens. You can tell players that the game is over, or that they have been given another $100 to play with.

Other Possibilities

More complex slot machines could include multiple symbols in a window. Some machines show three symbols, stacked vertically, and the player can win by matching symbols across three horizontal lines and two diagonal lines between the windows. Sometimes the player can choose to insert from one to five coins to enable potential wins along different lines.

Because this Flash movie is not for gambling, but just for fun, it is more important to see the potential for changing the graphics to match different Web site themes. For instance, you could have candy symbols for a kid’s site. The appearance of the machine and the type of symbols chosen can make a slot machine movie a good addition to many Web sites.

Video Poker

Video PokerExample file: Videopoker.fla

In casinos, the video poker machines are right next to the slot machines. They are essentially the same thing: You insert a coin and take a chance that you might win. The only difference is that you get to interact with the machine in the middle of the game to affect the outcome.

Make no mistake: The house always wins in the end. However, because the player gets to replace some cards in the middle of the game, video poker makes the player feel like he has a better chance. This will also make it more difficult for us to build.

Project Goal

Video poker is played in three steps. The first step is the game waiting for the player to ask that cards be dealt. Then, the player looks at the five cards and assesses them. The second step is when the player decides which cards to keep and which to discard. The last step is when new cards have been dealt and the final value of the hand is decided. This immediately leads back to the first step.

The game needs to present the player with a set of five cards randomly chosen from a shuffled deck. Figure 15.3 shows the screen with five cards.

The video poker game shows the player five cards.

Figure 15.3. The video poker game shows the player five cards.

The player can choose to replace any or all the cards. After that is done, the program must examine the final five cards and determine what they are worth.

Approach

The first thing the program needs is a shuffled deck of cards. This is an array of strings such as “h7,” which represents the seven of hearts. The four suits are represented by “c,” “d,” “h,” and “s.” An ace is a 1, as in “c1” for the ace of clubs, and the jack, queen, and king are “11,” “12,” and “13.”

Creating an ordered deck of cards is easy; however, a random deck is another matter. To create a shuffled deck, you start with an ordered array and then pick random items from it, one by one, and place them in a new array.

The first five cards from the array are then displayed on the screen. A button is placed under each card. One click changes the card to the image of the back of a card. A second click returns the card in case the player changes her mind.

After the player is satisfied with her choices, she hits the “Draw” button. Then any cards tagged for replacement are replaced by the next cards in the shuffled deck.

The trickiest bit of programming comes at the end of the game. An array of the five final cards must be evaluated for its poker value. Here is a list of possible values:

  • Low pair—A pair of cards, 10 or lower.

  • High pair—A pair of jacks, queens, kings, or aces.

  • Three-of-a-kind—Any three cards of the same value.

  • Straight—Five cards with consecutive values such as 8, 9, 10, jack, and queen. An ace can be either before a 2 or after a king.

  • Flush—Five cards of the same suit.

  • Full house—A pair and three-of-a-kind.

  • Four-of-a-kind—Four cards of the same value.

  • Straight flush—Five cards with consecutive values, all the same suit.

  • Royal flush—A straight flush with a 10, jack, queen, king, and ace.

To determine whether the final hand meets any of the previously listed criteria, you have to analyze the array of cards in several ways.

After the hand’s value has been determined, the final step is to match that value to a win amount and give the player the cash.

Preparing the Movie

The main library element in this game is the deck of cards, which is a 54-frame movie clip. The first frame shows the blank outline of a card. The second frame shows the back of any card. Frames 3 to 54 each show a different card in the deck. Each frame is named with the same name the code uses to identify cards. For instance, “c1” is the ace of clubs and “h11” is the jack of hearts.

If you look at the example movie, Videopoker.fla, you will see that the “deck” movie clip is complemented by a whole library folder filled with graphics. This makes it easier to reuse elements from card to card.

The movie is set up with five instances of the “deck” movie clip. They are named “card0” to “card4.” The first frame needs only a “deal” button, as does the third frame. The middle frame should have a “draw” button instead, as well as a “hold/replace” button under each card.

Writing the Code

The first frame of the main timeline contains most of the code. It starts by setting the player’s “cash” to 100.

<LINELENGTH>90</LINELENGTH>
startGame();
stop();

// init cash
function startGame() {
    cash = 100;
}

As in the slot machine, use a function to display the player’s cash with a “$” before it:

<LINELENGTH>90</LINELENGTH>
// display cash with $
function showCash() {
    cashDisplay = "$"+cash;
}

A hand starts with the player paying $1. Each hand is dealt from a fresh new deck of 52 cards. The “firstDraw” function picks the first five cards and the “showCards” function sets the movie clips on the Stage to those cards.

<LINELENGTH>90</LINELENGTH>
// start a hand
function startDeal() {
    // deduct from cash
    cash--;
    showCash();

    // shuffle and deal
    createDeck();
    firstDraw();
    showCards();
}

Creating a completely random deck involves two steps. The first is to create an ordered deck. This is done by looping through all the suits and values and adding a card to an array for each combination.

Next, the program takes random cards from this ordered deck and places them in another array. When that array is full and the previous array is empty, you have a shuffled deck.

<LINELENGTH>90</LINELENGTH>
// create a shuffled deck
function createDeck() {
    // creat an ordered deck
    suits = ["c","d","s","h"];
    temp = new Array();
    for(suit=0;suit<4;suit++) {
        for(num=1;num<14;num++) {
            temp.push(suits[suit]+num);
        }
    }

    // pick random cards until deck has been shuffled
    deck = new Array();
    while (temp.length > 0) {
        r = int(Math.random()*temp.length);
        deck.push(temp[r]);
        temp.splice(r,1);
    }
}

The “firstDraw” function takes five cards from the deck and pushes them into the “cards” array. It also initializes a small array called “hold,” which remembers which cards the player wants to keep.

<LINELENGTH>90</LINELENGTH>
// deal first five cards
function firstDraw() {
    cards = new Array();
    for(i=0;i<5;i++) {
        cards.push(deck.pop());
    }

    // set hold array to all held
    hold = [true,true,true,true,true];

    showCards();
}

To translate the array of cards in the player’s hand to something that the player can see, the “showCards” handler sets the frame for each of the five movie clip instances on the Stage to match the strings in the “hand” array:

<LINELENGTH>90</LINELENGTH>
// set card movie clips to the player's hand
function showCards() {
    for(i=0;i<5;i++) {
        _root["card"+i].gotoAndStop(cards[i]);
    }
}

After all the cards have been shown to the player, he must decide what to do next. The “Hold/Draw” button under each card calls the “holdDraw” function with a number from 0 to 4. The first time a button is clicked, the code changes the movie clip instance to show the back of a card. If the player clicks the button again, the code replaces the card. The player can toggle back and forth as many times as he wants before clicking the “Draw” button.

The “hold” array will have a true in any position to represent that the player wants to keep the card, and a false if the player wants to replace it:

<LINELENGTH>90</LINELENGTH>
// toggle a card between hold and draw
function holdDraw(cardNum) {

    // card being held, turn it over
    if (hold[cardNum]) {
        _root["card"+cardNum].gotoAndStop("back");
        hold[cardNum] = false;

    // card turned over, hold it instead
    } else {
        _root["card"+cardNum].gotoAndStop(cards[cardNum]);
        hold[cardNum] = true;
    }
}

When the player clicks the “Draw” button, the “secondDraw” function replaces any cards that are marked by a false in the “hold” array. The function calls “showCards” to display the changes.

The code then immediately uses the function “handValue” to determine what the player has. This value is passed into “winnings” to determine how much cash, if any, should be added to the player’s cash. Also, the variable “resultsDisplay” is used to display both of these values on the screen.

<LINELENGTH>90</LINELENGTH>
// replace cards not held and decide on winnings
function secondDraw() {

    // replace cards not held
    for(i=0;i<5;i++) {
        if (!hold[i]) {
            cards[i] = deck.pop();
        }
    }
    showCards();
    // figure out what player has
    handVal = handValue(cards);

    // determine the amount won
    winAmt = winnings(handVal);
    resultsDisplay = handVal + ": " + winAmt;

    // add winnings
    cash += winAmt;
    showCash();

    gotoAndPlay("done");
}

Before you get into the critical “handValue” function, you need to create a utility function called “compareHands.” The function “handValue” needs to sort the cards in the player’s hand so that the lowest values are first. Flash doesn’t know anything in particular about a deck of playing cards, so you have to teach it.

The “compareHands” function takes two cards and compares them. It isolates characters 1 and 2 from each card, which means that it ignores character 0. This means that “c7” becomes 7 and “c13” becomes 13.

It then returns one of three responses: -1 means card a is numerically before card b, 0 means card a is the same value as card b, and 1 means card a comes numerically after card b.

This function is required by the sort command that will be used in the “handValue” function. If sort didn’t have this specialized function, it would attempt to sort the “hand” array in alphabetical order, which would place all clubs in front of all diamonds because one starts with a “c” and the other a “d.” Instead, you want the cards to be sorted in numerical order.

<LINELENGTH>90</LINELENGTH>
// this function is used by the sort command to
// decide which cards come first
function compareHands(a,b) {

    // get number value of cards
    numa = Number(a.substr(1,2));
    numb = Number(b.substr(1,2));

    // return -1, 0, or 1 depending on comparison
    if (numa < numb) return(-1);
    if (numa == numb) return(0);
    if (numa > numb) return(1);
}

The “handValue” function, which is coming up next, starts by making a copy of the “cards” array and storing it in the “hand” array. It then sorts this array using the “compareHands” function Writing the Code.

For instance, if the player’s hand is [“h4,” “d5,” “c2,” “s3,” “h6”], then the array after the sort will be [“c2,” “s3,” “h4,” “d5,” “h6”]. This makes it easier for the code to determine whether the array has a set of cards that are in consecutive order, called a “straight.”

A “straight” is determined by looking at each card and seeing whether it is one value higher than the card before it Writing the Code. If this condition holds throughout the array, then it is a straight.

This technique won’t find one type of straight: when a straight starts with a 10, goes up to a king and then wraps back around to an ace. This is a special type of straight recognized in poker and you can perform a simple test to determine whether it has occurred Writing the Code.

Tip

Tip

Some people think that straights can wrap around the end of a deck, with the ace acting as the first and last card. For instance: a queen, king, ace, two, and three. This is not a valid poker straight, but merely an odd variation used in some friendly amateur games. An ace can be used as the first card of the straight (ace, two, three, four, five), or the last card of a straight (ten, jack, queen, king, ace), but not both for wrap-around sequences. The rules of poker are detailed in many sources, such as the popular Hoyle series of books.

Next, you check to see whether all the cards have the same suit Tip. This is done by comparing all cards, except the first one, with the first card. If all cards match the suit of the first card, then they must all match.

The next step is to make an array called “counts” and store the number of cards of each value in it Tip. This array has 14 values, each representing the number of cards in the hand of that value. The first item in the array is not used because there is no card of “0” value.

For example, if a hand has an ace, two threes, a four, and a jack, the array would be [0,1,0,2,1,0,0,0,0,0,0,1,0,0].

Finally, the code can start the task of determining what type of hand the player has. The “counts” array is looped through and any 2, 3, or 4 is noted Tip. A single appearance of a 2 means that the player has a pair. A single appearance of a 3 means the player has three-of-a-kind. A single appearance of a 4 means the player has four-of-a-kind. It is also possible to find a second appearance of a 2, or both a 2 and a 3 in the hand. The first is two-pair, and the second is a full house.

Next, a test is made to determine whether there are any pairs that are jacks or higher Tip. Video poker typically rewards only pairs that are jacks or higher and gives nothing for pairs that are 10 or lower.

Another test checks to see whether the player has an ace in the hand Tip. This is used in case the player has a straight flush. If the player has a straight flush and one card is an ace, then it means the player has the highest sort of straight flush: a royal flush.

Now the function has a whole series of true or false values: “straight,” “flush,” “hasKingAndAce,” “fourOfAKind,” “threeOfAKind,” “twoPair,” “pair,” “fullHouse,” and “jackOrHigher.” With these true or false values, the actual value of the hand can be determined and returned as a string Tip.

<LINELENGTH>90</LINELENGTH>
    // determine what the player has
    function handValue() {

        // make a copy of the player's cards and sort them
        hand = cards.slice();
Tip    hand.sort(compareHands);

        // make arrays with suits and numbers for easy access
        suits = new Array();
        nums = new Array();
        for(i=0;i<5;i++) {
            suits.push(hand[i].substr(0,1));
            nums.push(Number(hand[i].substr(1,2)));
        }

Tip    // see whether they are in perfect order
        straight = true;
        for(i=0;i<4;i++) {
            if (nums[i] + 1 != nums[i+1]) straight = false;
        }

Tip    // look for 10, J, Q, K and Ace
        if ((nums[0] == 1) and (nums[1] == 10) and (nums[2] == 11)
           and (nums[3] == 12) and (nums[4] == 13))  straight = true;

Tip    // see whether they are all the same suit
        flush = true;
        for(i=1;i<5;i++) {
            if (suits[i] != suits[0]) flush = false;
        }

Tip    // make array of how much of each number is in hand
        counts = new Array();
        for(i=0;i<14;i++) {
            counts.push(0);
        }
        for(i=0;i<5;i++) {
            counts[nums[i]]++;
        }

Tip    // use counts array to find matches
        pair = false;
        twoPair = false;
        threeOfAKind = false;
        fourOfAKind = false;
        for(i=1;i<14;i++) {
            // pair found
            if (counts[i] == 2) {
                // second pair found
                if (pair) {
                    twoPair = true;
                // first pair found
                } else {
                    pair = true;
                }
            // three-of-a-kind
            } else if (counts[i] == 3) {
                threeOfAKind = true;
            // four-of-a-kind
            } else if (counts[i] == 4) {
                fourOfAKind = true;
            }
        }

Tip    // see whether any matches are jacks or higher
        jackOrHigher = false;
        for(i=1;i<14;i++) {
            if (((i == 1) or (i > 10)) and (counts[i] >= 2)) {
                jackOrHigher = true;
            }
        }

Tip    // see whether hand has both king and ace
            hasKingAndAce = false;
            if ((counts[1]==1) and (counts[13]==1)) hasKingAndAce = true;

Tip        // return the type of hand the player has
            if (straight and flush and hasKingAndAce) {
                return("Royal Flush");
            } else if (straight and flush) {
                return("Straight Flush");
            } else if (fourOfAKind) {
                return("Four-Of-A-Kind");
            } else if (pair and threeOfAKind) {
                return("Full House");
            } else if (flush) {
                return("Flush");
            } else if (straight) {
                return("Straight");
            } else if (threeOfAKind) {
                return("Three-Of-A-Kind");
            } else if (twoPair) {
                return("Two Pair");
            } else if (pair and jackOrHigher) {
                return("High Pair");
            } else if (pair) {
                return("Low Pair");
            } else {
                return("Nothing");
            }
        }

The only function left is the “winnings” function, which takes a string generated by “handValue” and finds the appropriate amount won:

<LINELENGTH>90</LINELENGTH>
// take the type of hand and return the amount won
function winnings(handVal) {
    if (handVal == "Royal Flush") return(800);
    if (handVal == "Straight Flush") return(50);
    if (handVal == "Four-Of-A-Kind") return(25);
    if (handVal == "Full House") return(8);
    if (handVal == "Flush") return(5);
    if (handVal == "Straight") return(4);
    if (handVal == "Three-Of-A-Kind") return(3);
    if (handVal == "Two Pair") return(2);
    if (handVal == "High Pair") return(1);
    if (handVal == "Low Pair") return(0);
    if (handVal == "Nothing") return(0);
}

Loose Ends

Each “hold/draw” button contains a slightly different piece of code. The first one looks like this:

<LINELENGTH>90</LINELENGTH>
on (press) {
    holdDraw(0);
}

The “0” tells the “holdDraw” function that the request is about card 0. The other four buttons have the number 1 to 4 there instead.

Although the first frame of the movie immediately calls “startGame,” as you can see from the code in the “Writing the Code” section, the second frame must call “startDeal.” Check out the example movie to see it yourself.

Other Possibilities

I picked the amounts specified in “winnings” using common sense. However, you might want to pick different numbers depending on how much you want the game to favor the house or the player.

You will also want to handle the case where the player runs out of money. Send her to a “game over” frame, for instance.

Another variation on this game would be to allow players to bet from $1 to $5 per turn. This allows players to bet less when they feel unlucky and more at other times.

Simple Blackjack

Simple BlackjackExample file: Blackjack.fla

Blackjack is another popular casino card game that translates well to the computer screen. After all, the dealer in blackjack follows a precise set of rules. Therefore, you can write a program to imitate the dealer’s behavior.

Project Goal

The goal here is not to create a full-featured blackjack game, but rather a basic one. There are several rules in blackjack that are rarely used, such as doubling down, insurance, and splitting. These are seldom used by the player, and they complicate the code to the point of making it super-advanced. So instead of dealing with those rules and making this section of the book useful to only a few, those rules have been omitted so this section is easier to understand.

Figure 15.4 shows the example movie in action. You can see that the player has drawn five cards for a total of 18. The dealer drew three cards to get 21.

The Flash Blackjack game shows a hand just completed where the dealer beat the player 21 to 18.

Figure 15.4. The Flash Blackjack game shows a hand just completed where the dealer beat the player 21 to 18.

This simple blackjack game deals two cards to the player and dealer. The dealer’s first card is facedown until the player has finished drawing. The player can draw until he gets 21 or more. Then, the computer draws for the dealer until the dealer has at least 17.

If the player gets 21 in his first two cards, he immediately wins the bet, plus 50%. If the dealer gets 21, the hand ends immediately. After that, whoever gets the higher amount without passing 21, wins.

The player also can control how much he bets, from $5 to $25, in increments of $5.

Approach

As in the video poker game, there is a “deck” array that stores a shuffled deck of cards. The difference here is that there are actually six decks of cards shuffled into the same “deck” array. In blackjack, this is called a “shoe.”

Both the player and the dealer have an array representing the cards in their hands. You have to make a special consideration for the dealer’s first card, because it shouldn’t be shown until the player is finished drawing.

Unlike video poker, determining the value of a hand is simple in blackjack. The only twist is that an ace can be worth 1 or 11. However, because two aces worth 11 would total 22, there is no point in ever making a second ace worth 11. So, all you need to do is to recognize that if a hand has an ace in it, count it as 1, and then add 10 to the hand if that 10 won’t put the hand over 21. So a hand with a 3, 9, and an ace equals 13, because making the ace worth 11 makes the hand worth 23.

Preparing the Movie

Unlike video poker, there can be anywhere from 2 to 11 cards in a hand. So for each hand, 11 movie clip instances are placed named “player0” to “player10” and “dealer0” to “dealer10.” Instead of having a blank card outline for the first frame of the “deck” movie clip, nothing is placed in that frame. Therefore, when you place them on the Stage, all you see is Flash’s default movie clip marker. You can see all 22 of them in Figure 15.5.

All the cards appear as little circles—Flash’s movie clip marker for when there is nothing else visible for that movie clip.

Figure 15.5. All the cards appear as little circles—Flash’s movie clip marker for when there is nothing else visible for that movie clip.

This movie has a complex timeline. Each labeled marker in the timeline represents a different point in the game. Figure 15.6 shows this complex timeline and you can see most of the labels.

The complex timeline of the blackjack game has a labeled frame for each step. Frame 4’s label is the only one obscured. It reads “shuffle.”

Figure 15.6. The complex timeline of the blackjack game has a labeled frame for each step. Frame 4’s label is the only one obscured. It reads “shuffle.”

As the game progresses, so does the playback head along the timeline. Each keyframe calls a different function in the code. The code itself appears in the first keyframe.

Because of the nature of Flash timelines, it is important to take a look at the example movie, Blackjack.fla, on the CD-ROM to see for yourself where all the keyframes are and what code they call.

Writing the Code

The first frame calls “initGame,” but there is no stop() command right after it. The timeline should continue and move directly to the “shuffle” frame.

<LINELENGTH>90</LINELENGTH>
initGame();

The “initGame” function sets up the player’s “cash”:

<LINELENGTH>90</LINELENGTH>
function initGame() {
    cash = 100;
    showCash();
}

The “createDeck” function is similar to the one used in video poker, but it actually adds each card six times to create a show of six decks.

One of the drawbacks of the six decks is that it can take some time to shuffle in Flash. Therefore, the “shuffle” frame appears just one frame before the keyframe where the “createDeck” function is called. This ensures that the word “shuffle” appears in the screen before the code starts working on the assignment. Therefore, the player doesn’t have to wonder if her computer froze.

<LINELENGTH>90</LINELENGTH>
// create a shuffled deck
function createDeck() {
    // create an ordered deck
    suits = ["c","d","s","h"];
    temp = new Array();
    for(i=0;i<6;i++) {
        for(suit=0;suit<4;suit++) {
            for(num=1;num<14;num++) {
                temp.push(suits[suit]+num);
            }
        }
    }

    // pick random cards until deck has been shuffled
    deck = new Array();
    while (temp.length > 0) {
        r = int(Math.random()*temp.length);
        deck.push(temp[r]);
        temp.splice(r,1);
    }
}

The “initHand” function sets up the “playerHand” and “dealerHand” arrays. It also sets the flag “showDealerFirstCard” to false and sets the bet to the default $5.

<LINELENGTH>90</LINELENGTH>
// init hand arrays and bet
function initHand() {
    playerHand = new Array();
    dealerHand = new Array();
    showDealerFirstCard = false;

    bet = 5;
    showBet();
}

The “addToBet” function responds to the player clicking the “Add to bet” button. It adds $5 to the bet, but doesn’t allow the player to go above $25.

<LINELENGTH>90</LINELENGTH>
// allow the player to increase her bet up to $25
function addToBet() {
    bet += 5;
    if (bet > 25) bet = 25;
    showBet();
}

When the player hits the “Deal” button, “makeBet” is called to transfer the bet amount out of the player’s cash pool. The movie then flows forward through the four frames: “Deal1” to “Deal4.”

<LINELENGTH>90</LINELENGTH>
// take the money away from the player
function makeBet() {
    cash -= bet;
    showCash();
}

Each of the four “Deal” frames calls “dealCard.” Twice this function is called with “playerHand” and twice with “DealerHand.” The function deals two cards to the player and two to the dealer. The function “showCards” is also called in each of these frames.

<LINELENGTH>90</LINELENGTH>
// take one card from the deck and give it to the player
function dealCard(hand) {
    hand.push(deck.pop());
}

The “showBet” and “showCash” functions display the current bet and the player’s cash with a “$” in front of them. Remember to create the appropriate text areas for each of these.

<LINELENGTH>90</LINELENGTH>
// display cash with $
function showCash() {
    cashDisplay = "$"+cash;
}

// display bet with $
function showBet() {
    betDisplay = "$"+bet;
}

The “showCards” function loops through each of the cards in both the player’s and dealer’s hands and sets the movie clips on the Stage to represent them. It uses the flag “showDealerFirstCard” to determine whether the first card in the dealer’s hand is shown or the back of a card is shown instead.

<LINELENGTH>90</LINELENGTH>
// show all cards in both hands
function showCards() {
    // only show the dealer's first card when player is finished
    if (showDealerFirstCard) {
        _root["dealer0"].gotoAndStop(dealerHand[0]);
    } else {
        _root["dealer0"].gotoAndStop(2);
    }

    // show the rest of the dealer's cards
    for(i=1;i<dealerHand.length;i++) {
        _root["dealer"+i].gotoAndStop(dealerHand[i]);
    }

    // show all of the player's cards
    for(i=0;i<playerHand.length;i++) {
        _root["player"+i].gotoAndStop(playerHand[i]);
    }

    // show the numerical value of both hands
    playerValue = handValue(playerHand);
    dealerValue = handValue(dealerHand);
}

After the initial deal of two cards each, there is the chance that either player has blackjack. If the player does, then she immediately wins her bet, plus 50% more. If the dealer does, then the player loses right away.

<LINELENGTH>90</LINELENGTH>
// check to see whether either has blackjack
function checkForBlackjack() {

    // if player has blackjack
    if ((playerHand.length == 2) and (playerValue == 21)) {
        // award 150% winnings
        cash += bet*2.5;
        showCash();
        result = "Blackjack!";
        gotoAndPlay("Done");

    // if dealer has blackjack, instant loss
    } else if ((dealerHand.length == 2) and (dealerHand == 21)) {
        result = "Dealer has blackjack!";
        gotoAndPlay("Done");
    }
}

After the initial four cards are dealt, the movie comes to a rest on the “Player” frame. This frame has a “Hit” and a “Stay” button. The player can use the “Hit” button to request another card. The “hit” function is called. If the new card puts the player at 21 or more, then the game automatically moves forward.

<LINELENGTH>90</LINELENGTH>
// player draws another card
function hit() {
    dealCard(playerHand);
    showCards();
    playerValue = handValue(playerHand);

    // if player gets 21 or busts, go to dealer
    if (playerValue >= 21) startDealer();
}

When the player is finished drawing, the dealer gets to go. The “startDealer” function kicks off this stage of the game by setting the “showDealerFirstCard” to true and displaying it through an extra call to “showCards.” Then the game advances to the “Dealer” frame.

<LINELENGTH>90</LINELENGTH>
// show dealer's first card and let dealer draw
function startDealer() {
    showDealerFirstCard = true;
    showCards();
    gotoAndPlay("Dealer");
}

The “Dealer” frame loops over and over, calling “dealerMove” each time. In each case, the dealer’s hand is examined to see whether it’s worth 17 or more. The house rules for this game are that the dealer must hit on 16 or lower and stand on everything else. When the dealer stands, the “decideWinner” function is called.

<LINELENGTH>90</LINELENGTH>
// dealer draws if < 17
function dealerMove() {
    if (handValue(dealerHand) < 17) {
        dealCard(dealerHand);
        showCards();
        gotoAndPlay("Dealer");

    // dealer is done
    } else {
        decideWinner();
    }
}

The “handValue” function is used in many of the functions shown in the previous code to calculate the numerical value of a hand. The value of each card is added to the total, with aces representing 1. If an ace is found and the addition of 10 will not bust the hand, then 10 is added to the total.

<LINELENGTH>90</LINELENGTH>
// calculate hand value
function handValue(hand) {
    total = 0;
    ace = false;

    for(i=0;i<hand.length;i++) {
        // add value of card
        val = Number(hand[i].substr(1,2));

        // jack, queen, and king = 10
        if (val > 10) val = 10;
        total += val;

        // remember whether an ace is found
        if (val == 1) ace = true;
    }

    // ace can = 11 if it doesn't bust player
    if ((ace) and (total <= 11)) total += 10;

    return(total);
}

The following function uses a series of conditions to determine who won. Not only is the “cash” adjusted if the player wins, but each case also sets the “result” variable, which is then displayed on the Stage in the “Done” frame.

<LINELENGTH>90</LINELENGTH>
// see who won, or whether there is a tie
function decideWinner() {
    showCash();
    if (playerValue > 21) {
        result = "You Busted!";
    } else if (dealerValue > 21) {
        cash += bet*2;
        result = "Dealer Busts. You Win!";
    } else if (dealerValue > playerValue) {
        result = "You Lose!";
    } else if (dealerValue == playerValue) {
        cash += bet;
        result = "Tie!";
    } else if (dealerValue < playerValue) {
        cash += bet*2;
        result = "You Win!";
    }
    showCash();
    gotoAndPlay("Done");
}

The “Done” frame contains a “Next Hand” button that calls the following function. This function checks to make sure that there are more than 26 cards left in the deck. If not, another shuffle is performed. If there are enough cards left, then “initHand” is called and the game returns to the “Bet” frame.

Either way, the “resetCards” function is used to set all the “deck” movie clips on the Stage back to the first frame so that the cards don’t persist on the screen.

<LINELENGTH>90</LINELENGTH>
// start next hand
function newDeal() {
    resetCards();

    // if deck has less than 26 cards, reshuffle
    if (deck.length < 26) {
        gotoAndPlay("shuffle");
    } else {
        initHand();
        gotoAndPlay("Bet");
    }
}

// remove cards from table
function resetCards() {
    for(i=0;i<dealerHand.length;i++) {
        _root["dealer"+i].gotoAndStop(1);
    }
    for(i=0;i<playerHand.length;i++) {
        _root["player"+i].gotoAndStop(1);
    }
}

Loose Ends

The main timeline for this movie is the most complex of any game in this book. Therefore, it is important to check out the example movie on the CD-ROM to get a good sense of where everything goes.

You’ll also need to create various text areas to display the value of each hand, the bet amount, the cash amount, and the result.

Other Possibilities

Although this game is a good one from which to learn a little ActionScripting, it will disappoint avid blackjack players. Therefore, for the benefit of advanced ActionScript programmers, here’s a bit about how to add some of the missing features to the game.

Doubling down is the easiest feature to add. All you need to do is create another button on the “Player” frame called “Double.” When the player clicks it, he is dealt one new card, his bet is subtracted once again from his cash, and the play passes to the dealer. However, you have to make sure that the player has not already drawn any cards because doubling can happen only when the player has just his initial two cards.

Insurance is a little harder to do because it creates another branch in the flow of the game. Insurance happens when the dealer is showing an ace. In that case, the player can choose to take out insurance, which is basically a bet against the dealer having 21. If insurance is accepted, and the dealer has 21, then the hand immediately ends. Although the player loses his original bet, he wins the insurance bet.

Splitting is a difficult addition to this game. If the player has two cards of equal value, such as two 9s, then she should be allowed to split the hand into two hands, each starting with a single 9. This means that you cannot store the player’s hand in a single array, “playerHand,” but you must make it an array of arrays. In most cases, this “playerHands” array contains a single array representing the only hand. If the player splits, then it will contain two arrays. The player might be able to split more than once, giving you three, four, or more arrays inside the “playerHands” array. Then each hand must be played out. You can see how this complicates every part of the game. Even at the end of the game, the player could potentially win, lose, and tie some or all hands.

Pyramid Solitaire

Pyramid SolitaireExample movie: Pyramid.fla

Pyramid solitaire is not as popular as standard solitaire nor as complex; however, it is easier to learn and very addictive. Figure 15.7 shows the basic game setup.

Pyramid solitaire is played with a pyramid of 28 cards and the remaining deck.

Figure 15.7. Pyramid solitaire is played with a pyramid of 28 cards and the remaining deck.

Any card that is completely uncovered is playable. If another card in the pyramid covers part of a card, it cannot be played until the covering cards are removed. To remove a card, the player must match it up with another card so that the total value of both cards equals 13. For instance, a 10 and a 3, or a 6 and a 7, can be paired up. An ace has a value of 1, a jack a value of 11, a queen is a 12 and a king is a 13. This means that the king is the only card that can be selected by itself, without a second card.

The object, of course, is to remove all the cards in the pyramid. To help with this, the remaining 24 cards in the deck are placed under the pyramid and cards can be turned over one at a time. Whichever card is face-up can be combined with a card in the pyramid to total 13.

Take a moment to play the example movie. You may want to put the book down because you might end up playing for a while.

Project Goal

The goal of this project is to make a complete pyramid solitaire game. It will even recognize the rare case when a player “wins” by removing all the cards in the pyramid. When players feel that they are at an impasse, or that the hand dealt is not likely to be fruitful, they can hit a button to re-deal at any time.

Approach

We use the same deck of cards from the blackjack game. The game starts by shuffling the deck and dealing out the pyramid. The rest of the cards are placed in a face-down pile at the bottom of the screen. The player can click on this stack and the card is shown in a face-up stack next to it, which starts out empty. Every click on the face-down stack deals a new card to the face-up pile.

The player can select any uncovered card in the pyramid or the card in the face-up pile. A border in the form of a movie clip highlights the card selected.

When the player clicks another card, it is compared to the first card to see whether it totals 13. If so, then both cards are removed. If one of these cards is in the face-up stack, then the card under it is revealed.

The way to determine whether a card in the pyramid is uncovered is to loop through all the cards in the pyramid to see whether either of the two cards that are supposed to cover it are still there. For instance, the second card in the third row should be covered by the second and third cards in the fourth row and the third card in the fourth row. If either is still there, then the card cannot be selected.

When a card is removed from the face-up stack, the previously visible card must be revealed. This means that you need to keep track of the cards in the face-up stack by placing them into an array as they are turned over.

Kings are a special case. If a king is selected, then it is immediately removed from either the face-up stack or the pyramid, providing it is not covered.

Preparing the Movie

The movie uses the same “deck” movie clip in the Library as the blackjack game. It needs to have its Linkage property set to export with the movie. There is also an “outline” movie clip that is also set to export.

The only frames needed are the “Play” frame and a “Game Over” frame. The latter would be used only in the rare case of a win. Both frames should have a “New” button placed on them that re-deal the game whenever the user wants.

Writing the Code

Almost all the code appears in the main timeline. It starts with the function “startGame.” After a new, shuffled deck of cards is created, seven rows of cards are also created Writing the Code. The first row has one card in it, the second row has two cards, and so on.

Each card is placed according to its row and position in the row Writing the Code. In addition, the scale of each card is reduced to 50% because the deck used in the blackjack game is about twice the size of what you want for this game Writing the Code.

The value of the card is taken from the “deck” array Writing the Code. This corresponds to the frame label inside the “deck” movie clip. This value is stored in the “value” property of the movie clip and goes to the correct frame. The movie clip properties “row” and “col” store the movie clip’s position in the pyramid Writing the Code.

You then create the face-down and face-up stacks by making a movie clip for each Writing the Code. The face-down stack is sent to the frame “back” to show the image of the back of a card. The other stack remains on frame one, which is blank.

The variable “firstcard” is set to undefined Writing the Code. This variable holds the value of the first card in a pair to be selected by the user. The “stack” array is used to keep track of the cards in the face-up stack. This way when a card in that stack is used, the value of the previous card can be dug out.

Finally, the outline movie clip is created from the Library symbol Writing the Code. It is moved offscreen for now.

<LINELENGTH>90</LINELENGTH>
    startGame();
    stop();

    function startGame() {

        // shuffle deck
        createDeck();

Writing the Code    // place pyramid cards
        level = 0;
        for(row=0;row<7;row++) {
            for(i=0;i<=row;i++) {
                // make new movie clip
                mc = _root.attachMovie("Deck","card"+level,level);

Writing the Code            // position clip
                mc._x = i*60-row*30 + 275;
                mc._y = row*30 + 50;

Writing the Code            // reduce size from standard deck
                mc._xscale = 50;
                mc._yscale = 50;

Writing the Code            // set value of card
                mc.value = deck.pop();
                mc.gotoAndStop(mc.value);

Writing the Code            // remember its position
                mc.row = row;
                mc.col = i;
                level++;
            }
        }

Writing the Code    // place face-down and face-up stacks
        for(i=0;i<2;i++) {
            mc = _root.attachMovie("Deck","stack"+i,level);
            mc._x = i*60 + 100;
            mc._y = 340;
            mc._xscale = 50;
            mc._yscale = 50;
            level++;
        }

        // show back of card for face-down stack
        _root["stack0"].gotoAndStop("back");

Writing the Code    // set up selection and face-up stack
        firstCard = undefined;
        stack = new Array();

Writing the Code    // set up outline for use
        outline = _root.attachMovie("outline","outline",1000);
        outline._xscale = 50;
        outline._yscale = 50;
        outline._x = -1000;
    }

The “createDeck” function is similar to the one in the blackjack game. However, this time you’re sorting only one deck of cards. The result ends up in the global variable “deck.”

<LINELENGTH>90</LINELENGTH>
// create a shuffled deck
function createDeck() {
    // create an ordered deck
    suits = ["c","d","s","h"];
    temp = new Array();
    for(suit=0;suit<4;suit++) {
        for(num=1;num<14;num++) {
            temp.push(suits[suit]+num);
        }
    }

    // pick random cards until deck has been shuffled
    deck = new Array();
    while (temp.length > 0) {
        r = int(Math.random()*temp.length);
        deck.push(temp[r]);
        temp.splice(r,1);
    }
}

Instead of using a movie clip script or button to detect mouse clicks, I’ll register this function to handle them.

First, it loops through all the cards in the pyramid and determines whether any are the victim of the click Writing the Code. The loop starts at 28 and counts down. This way cards on top are considered before the cards under them.

If a pyramid card has been clicked, then the code tries to determine whether a card is on top of it Writing the Code. It does this by calling “cardPresent” with the row and column of the two cards that could possibly be covering the one clicked.

If the local variable “card” is still undefined, then no card has been chosen. One last check is made to see whether the player has clicked the face-up card stack, which is the movie clip “stack1” Writing the Code.

If a card has been selected, and the global variable “firstcard” is still undefined, then no other card is currently selected. A reference to this card is placed in “firstcard” Writing the Code.

If another card is already selected, then the value of the new card and the old card are totaled. The utility function “cardValue” is used to get the numerical value of the cards Writing the Code. If the total is 13, then both cards are removed with another utility function, “removeCard.”

If, on the other hand, the “firstcard” has a value of 13 by itself, then it must be a king and is removed by itself Writing the Code.

If the “stack0” movie clip has been clicked, then it means that the user has decided to take a card from the face-down deck and flip it over to the face-up deck. The last value in the “deck” array is taken and used to change the frame of the movie clip “stack1” Writing the Code. The “stack” array is used to keep track of cards that are flipped between these stacks.

To highlight the card selected, the “outline” movie clip is moved to the same position as the selected card Writing the Code.

Finally, the first card in the pyramid is tested Writing the Code. If it is missing, then the user must have removed the top card of the pyramid and won the game.

<LINELENGTH>90</LINELENGTH>
    _root.onMouseDown = function() {
        var card = undefined;

        // see whether one of the pyramid cards was clicked
Writing the Code    for(var i=27;i>=0;i--) {
            if (_root["card"+i].hitTest(_xmouse,_ymouse)) {
                var card = _root["card"+i];
                break;
            }
        }

        // if a pyramid card, is it uncovered?
Writing the Code    if (card != undefined) {
            if (cardPresent(card.row+1,card.col) or cardPresent(card.row+1,card.col+1)) {
                card = undefined;
            }
        }

        // perhaps it was the face-up stack?
Writing the Code    if (card == undefined) {
            if (stack1.hitTest(_xmouse,_ymouse)) {
                card = stack1;
            }
        }

        // got a card, so check it
        if (card != undefined) {

Writing the Code        // first card clicked
            if (firstCard == undefined) {
                firstCard = card;

            // ignore second click on same card
            } else if (firstCard == card) {

Writing the Code        // if second card clicked and both total 13
            } else if (cardValue(firstCard) + cardValue(card) == 13) {

                // remove both cards
                removeCard(card);
                removeCard(firstCard);
                firstCard = undefined;

            // otherwise, make this the first card
            } else {
                firstCard = card;
            }
        }

Writing the Code    // if only one card selected, but it is a king
        if (cardValue(firstCard) == 13) {
            removeCard(firstcard);
            firstCard = undefined;
        }

Writing the Code    // if face-down stack clicked, deal card
        if (stack0.hitTest(_xmouse,_ymouse)) {
            stack1.value = deck.pop();
            stack1.gotoAndStop(stack1.value);
            stack.push(stack1.value);

            // if no more cards in stack, remove face-down stack
            if (deck.length == 0) {
                stack0.removeMovieClip();
            }
        }

Writing the Code    // place outline over selected card
        if (firstCard != undefined) {
            outline._x = firstCard._x;
            outline._y = firstCard._y;
        } else {
            outline._x = -1000;
        }

Writing the Code    // if top card of pyramid is gone, player won
        if (_root["card0"] == undefined) {
            gotoAndStop("game over");
        }
    }

All that’s left is a bunch of utility functions. The first one, “removeCard,” takes away a card from either the face-up stack or the pyramid. To remove a card from the face-up stack, it must simply reset the “stack1” movie clip to the frame that represents the previously-shown card. This is where the array “stack” comes in handy. Each card placed on the face-up stack is added to “stack.” To get a card back, you just need to pop the last one off the “stack” and then examine the last item of “stack.”

If the card is from the pyramid, then the reaction is much simpler. The movie clip is removed.

<LINELENGTH>90</LINELENGTH>
function removeCard(thisCard) {
    if (thisCard == stack1) {
        // remove card from stack
        stack1.gotoAndStop(1);
        stack.pop();
        stack1.value = stack[stack.length-1];
        stack1.gotoAndStop(stack1.value);
    } else {
        // remove card from pyramid
        thisCard.removeMovieClip();
    }
}

The next utility routine, “cardPresent,” loops through the cards to determine whether any card that still exists has a matching “row” and “col” property.

<LINELENGTH>90</LINELENGTH>
function cardPresent(row, col) {
    // loop through pyramid to see whether this card is there
    for(var i=0;i<28;i++) {
        thisCard = _root["card"+i];
        if ((thisCard.row == row) and(thisCard.col == col)) {
            return (true);
        }
    }
    return(false);
}

The “cardValue” function takes the “value” property of a card movie clip, strips the first character, and returns the numerical value. For instance, if the “value” of the card is “c9,” then a 9 is returned.

<LINELENGTH>90</LINELENGTH>
function cardValue(card) {
    // strip first letter from name of card to get its value
    n = card.value;
    n = parseInt(n.substr(1,2));
    return(n);
}

The last utility function loops through all the pyramid cards and removes any that are left. It also removes “stack0” and “stack1.” This clears the Stage in preparation for another round.

<LINELENGTH>90</LINELENGTH>
function clearGame() {
    // remove pyramid cards
    for(var i=0;i<28;i++) {
        _root["card"+i].removeMovieClip();
    }

    // remove stack
    stack0.removeMovieClip();
    stack1.removeMovieClip();
}

Loose Ends

The New button on the screen has a simple script that first calls “clearGame” and then “startGame.” This resets the game any time the player wishes.

<LINELENGTH>90</LINELENGTH>
on (press) {
    clearGame();
    startGame();
}

Other Possibilities

The game can be made considerably easier if you allow players to turn over the face-up deck and go through the cards as many times as they like. You can do this by recognizing when the “deck” is empty and putting each card from “stack” back on to “deck.”

There are many other solitaire games you can build. My collection of game research includes more than 200 variations. Most require that cards be dragged around and moved from stack to stack. This makes the ActionScript far more complex, but not impossible for a skilled programmer.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.188.10.246