| Register
Saturday, May 17, 2008   

Playing and Planning with OOP

Created By  Satori Canton, at  3/4/2006 - 11 comments.

Click to view this author's website.

When Flash MX first came out, one of the first pseudo-OOP classes that I ever made was a deck of cards. The deck was just a data object (kind of a high level array) that stored objects representing playing cards. It could be shuffled, cards dealt, etc. It was intended to be the utility class underneath any card game that I may want to create.

The exercise was useful, because it's relatively simple, but illustrates how to plan an OOP application (or at least one aspect of an application). Recently, I've revisited my old class and updated it for ActionScript 2.0. I thought some people may like to see the process of planning a deck of cards in Flash.

If you actually get a physical deck of cards and look at it, you'll see that it's basically an array (queue) of cards (data objects). The smallest and simplest part of the deck is the individual card. So, let's start our design by defining the Card class.

A basic playing card has a suit and a value. Cards also normally have a fancy single-color design on the back of them. In some games or card tricks, the back-color of the card is important, so we may want to store that data as well. The Card class really just represents data, so it doesn't need to have any methods or events. We may want to define a toString() method just to make it easy to trace out the value of a single card in Flash. That pretty much defines the public aspects of our Card class.

Now, to the actual CardDeck. Like I was saying above, a deck of cards is very much like a high-level array. So, we'll probably have a property of the class that represents this deckArray. We'll also want to be able to check the length of the deck array, so we should give the CardDeck a length property.

For the methods of the card deck, we'll have to consider all of the things that you may want to do with a deck of cards. Also, some games (like 21) may use multiple decks. Other games (like poker) may or may not use Jokers, depending on the type of game. So, when we first create our deck of cards, we should be able to declare just how many decks should be included and whether or not Jokers should be included. We'll call that method "createDecks". We may want an "addCard" method to allow us to insert custom cards (maybe we just want one Joker, or maybe a player returned a card to the deck). Obviously we'll need "deal" and "shuffle". When the deck runs low, or the game starts over, we will want to be able to start with a full deck. So we should add a "refreshDeck" method to support this.

We may want to loop through the deck and look at the value of the cards or remove a specific card, so we should have "getItemAt" and "removeItemAt" methods.

Supposing that the back-color of the card is important, we should have a way to set the back-color for all cards in a deck, so we'll want a "setBackColor" method. If color is important, we may want to create a red and a blue deck separately, then merge them into one deck, so we'll need a "merge" method.

That pretty much covers the basic things you would want to do with a deck of cards. But what if you want to cheat or do a magic trick with a deck of cards? If you can do it with a real deck, you should be able to do it with a virtual deck, so we should support those methods as well. A few simple "magic" methods may be "getHighestCard", "getMatchingSuit" and "getMatchingValue". Want to get a flush every hand, just deal the first card and reference that card with getMatchingSuit() for the next four cards and you'll be unstoppable.

The CardDeck class could represent the deck of cards in the game, but it could also represent the individual hands that a player is holding. After all, a player's hand is just an array of Card objects (just like our CardDeck). So, we should have a few events that would either notify a controller that we're at the end of the deck, or can notify a view that a card has been added or removed. Our events will be "cardAdded", "cardRemoved" and "endDeck".

Finally, since the CardDeck is going to have to handle events, we can use Flash's EventDispatcher to mix in the basic event handling methods. This will add the following methods to our CardDeck: "addEventListner", "dispatchEvent", "dispatchQueue" and "removeEventListner".

I normally implement an interface called IEventDispatcher when I plan on having a class use the EventDispatcher mix in. So, our final diagram of the CardDeck application will look something like this:

Now, we haven't written a line of code. In fact, you wouldn't even have to know how to write ActionScript to create this class diagram. Or for that matter, you could take this exact class diagram and implement it in VisualBasic, C++, Ruby, JavaScript or whatever. The point is, we don't start a project by firing up Flash and wildly hacking out code. Instead, we took a few minutes to consider what we're actually making, how such a thing works in the real world, and plan the functionality we want our classes to have. It wasn't hard and didn't take long at all. But now we have a perfect blueprint to work off of.

Although this is extremely simple, you could take this diagram and have one developer create the Card class and have another developer create the CardDeck class. In a complex application, this kind of planning is essential. But even in this simple example, it's very useful. At this point if we think of anything else that we want to be able to do to the CardDeck, we only have to update our diagram. We won't have to change any code.

When it comes time to code, it will be simple to break this down into specific methods and properties. There will of course be a few private properties and methods not illustrated in our diagram. But that's fine. That's why encapsulation is advantageous in OOP. We can do whatever we want on the inside, as long as the public side of our classes stays the same.

If you want to see how to actually code these classes, check out the source files. If you have any questions, please post them in the comments.

Need Professional Help For Your ActionScript Project?
ActionScript.com Consulting Services provide top quality professional ActionScript consulting to businesses around the globe. If you have a professional project in need to world-class talent, tell us about your project by requesting a quote today.

Reader Comments

  1. Satori Canton  Replied:
    ( 3/5/2006 At 11:31 PM)

    I made a quick and dirty demo of how you would use this CardDeck class both as a deck of cards (called mainDeck in the demo) and also as the player's hands and the community cards in a game of Texas Hold'em. The individual hands (models) notify the views that the models have changed through simple event listeners. Then the text fields can update the state of the game. A simple controller controls the logic of the game.


    I changed the source for the CardDeck slightly to include a "refreshDeck" event that was needed for the views, and I also created a toHTMLString() method to support color coded output displayed in the text boxes. You can get the demo and the updated class source here.

  2. Ali Bayat  Replied:
    ( 3/6/2006 At 11:43 AM)

    Hi,my name is Ali. And I am a student at the moment, I am studying for web site design and I need learn about flash to design web sites so how can I learn this cours on the internet.

  3. Zach DeBord  Replied:
    ( 3/20/2006 At 6:58 PM)

    Could you tell me what program was used to create the class diagram?

  4. Satori Canton  Replied:
    ( 3/20/2006 At 7:44 PM)

    The class diagram was made with gModeler.
    http://www.gskinner.com/gmodeler/

  5. Arpit Jain  Replied:
    ( 4/18/2006 At 12:19 AM)

    Does gModeler has options for creating an interface linkage? I could able to create an interface link like the one shown in the diagram on top, where CardDeck implements IEventDispatcher.

  6. Satori Canton  Replied:
    ( 4/18/2006 At 1:55 AM)

    I don't think gModeler supports interface linkage. If it does, I don't know how to do it. I edited the graphic to illustrate the structure of my design. I used gModeler to make the basic structure, but edited the graphical connection to more clearly show an interface.

  7. Vicki Pearson  Replied:
    ( 5/18/2006 At 11:15 PM)

    Hi.
    Would love to see the source files but when I download I get an unexpected file error in Flash (MX 2004) Is there anyway you could email them to me?
    Thank YOu very much
    Vicki

  8. Satori Canton  Replied:
    ( 5/18/2006 At 11:16 PM)

    These files are Flash 8 format.

  9. Jeff Chadwell  Replied:
    ( 6/30/2006 At 4:52 PM)

    Hi,

    I was looking at the com.actionscript.games.CardDeck class and I think the deckArray method is incorrect. Shouldn't you be using the Array "slice" method instead of the "splice" method?

    Jeff Chadwell

  10. Satori Canton  Replied:
    ( 7/1/2006 At 1:10 AM)

    Jeff, you're right. That was a typo. It's easy to get "slice" and "splice" confused. But in the case of deckArray, it's intended to return an array by value and not by reference. "slice" is the correct method.

  11. Scott Mayhew  Replied:
    ( 3/24/2007 At 3:31 PM)

    I like the way that works, Can you tell me how to add a movieclip to each player instead of text

Login to post your comments. If you do not have an account with us please Register.
Copyright 2005 by ActionScript, Inc.   |  Privacy Statement  |  Terms Of Use  |  ActionScript Client Extranet