0

I am new to actionscript 3.0 and I am trying to make a deck of cards shuffle, I have succeeded with this but my problem is that my cards are being repeated, so I have duplicates of the same card in a 52 card deck after shuffling. I am trying to create a texas holdem game.

I found this discussion Randomize or shuffle an array but it does not tell me how to incorporate the Fisher–Yates algorithm into my code. I have tried several different methods suggested here and else where over the web and nothing is working (Think the problem is defiantly my lack of experience).

Can someone please give me an example of how to incorporate this into my code or a link to somewhere that will explain how to do this correctly.

Thanks in advance.

Paul

package src.CardDeck
{
    public class CardDeck
    {
        public var allCards:Array = [];
        public var cardNames:Array;
        public var cardValues:Array;
        public var gameType:String;
        public var drawnCards:uint = 0;

        public function CardDeck(game:String)
        {
            gameType = game;
            cardNames = ["Ace","Two","Three",
                         "Four","Five","Six",
                         "Seven","Eight","Nine",
                         "Ten","Jack","Queen","King"];
            if(gameType == "texasholdem")
            {
                cardValues = [1,2,3,4,5,6,7,8,9,10,10,10,10];
            }
            makeSuit("Spade");
            makeSuit("Heart");
            makeSuit("Diamond");
            makeSuit("Club");
        }

        private function makeSuit(suitString:String):void
        {
            var card:Object;

            for(var i:uint = 0; i < cardNames.length; i++)
            {
                card = {};
                card.cardType = suitString;
                card.cardName = cardNames[i];
                card.cardValue = cardValues[i];
                card.isDrawn = false;
                allCards.push(card);
            }
        }

        public function shuffle():Array
        {
            var shuffledArray:Array = [allCards.length];
            var randomCard:Object;
            do
            {
                randomCard = getRandomCard();
                if(shuffledArray.indexOf(randomCard) == -1)
                {
                    shuffledArray.push(randomCard);
                }
            }
            while(shuffledArray.length < allCards.length)
                return shuffledArray;
        }

        private function getRandomCard():Object
        {
            var randomIndex:int = Math.floor(Math.random()* allCards.length);
            return allCards[randomIndex];
        }
    }
}
Community
  • 1
  • 1

2 Answers2

5

Bug Note:

var shuffledArray:Array = [allCards.length];

Makes an array with a single element which shuffledArray[0] = allCards.length. In fact you do not need to pre allocate it just say:

var shuffledArray: Array = []; 

Here is the classical Fisher–Yates version:

public function shuffleFisherYates():Array {
var shuffledArray:Array = [];
var randomCardIndex: int;
    do {
        randomCardIndex = Math.floor(Math.random()* allCards.length);
        shuffledArray.push(allCards[randomCardIndex]); // add to mix
        allCards.splice(randomCardIndex,1); // remove from deck
    }while(allCards.length); // Meaning while allCards.length != 0
    return shuffledArray;
}

Here is Durstenfeld's (in place) version:

public function shuffleDurstenfeld():Array {
var swap:Object;
var countdown:int = allCards.length-1;
var randomCardIndex: int;
    for(i = countdown; i > 0; i--){
        randomCardIndex = Math.floor(Math.random()* countdown);
        swap = allCards[countdown];
        allCards[countdown] = allCards[randomCardIndex];
        allCards[randomCardIndex]= swap;
    }
    return allCards; // shuffled in place
}
Volkan
  • 2,212
  • 1
  • 14
  • 14
0

Assuming your shuffling code is okay, I think a reason why you are seeing repeated cards is that within your getRandomCard() method, you are not accounting for cards that have been drawn. You randomly generate an index and return the card there in the array....but that card is still in the array and it's possible that same index can be randomly generated again, resulting in the same card being returned.

mitim
  • 3,169
  • 5
  • 21
  • 25
  • I have a long way to go to learn OOP. Thank you very much lhsan Compiles now with no errors but can you have a quick look http://stackoverflow.com/questions/15593171/1120-access-of-undefined-property-shuffledarray . Thanks mitim shuffling fine with no errors but I am still learning so can you break it down for me thanks. – user2203250 Mar 23 '13 at 23:14
  • are you able to draw cards without repeats or does your original problem still exist? – mitim Mar 23 '13 at 23:34
  • looking at your code in your other question linked above, it looks like you've got shuffling working (I gave it a quick look myself). What I meant in my original answer is that say you have a deck of cards and you want to draw one by choosing a random number from 1 to 52. You do so, but you are just checking the card at that number in your getRandomCard() method. You aren't actually removing that card to indicating in any way it has been drawn fro the deck. So then if you happen to choose that same number again (which is possible via Math.random()), you'll end up with the same card result. – mitim Mar 23 '13 at 23:47
  • Thanks so much guys ihsan that worked thank you very much for your help I now just need to get my trace(); to pick up the array i.e. Aces of Spades etc. as I am now getting [object Object] 52 times. Thanks as well mitim you guys have been a great help. – user2203250 Mar 23 '13 at 23:52
  • If you want to thank Ihsan, I think you should comment on his post – duTr Mar 24 '13 at 06:43