0

I have a deck of cards object that essentially just fills a deck array with 0-51 (52 cards) and then shuffles the cards. I have a cards.deal() method that returns a card. When I use cards.pop() I always get a different number, which is what is expected; however, when I used cards.shift() it always returns 0. I'm content with using pop but would just like to understand for learning purposes why I'm always getting a 0 when I use shift. I've changed the number of shuffles to huge numbers like 10,000 just to make sure it's shuffling enough to actually swap the first element in the array. Could it be possible that the Math.ceil method is not returning a 0, even after 10,000 random numbers generated between 0 and 51? What is going on here?

function Deck(){

    var cards = [];

    this.shuffle = function(){

        var tempCardHolder = 0;
        var randomNumber = 0;
        var randomNumber2 = 0;

        // fill the card array with 52 cards
        for (x = 0; x <= 51; x++){
            cards[x] = x;
        }


        // now let's shuffle them up by swapping two cards randomly 50 times
        for (y = 0; y < 100; y++){

            // make sure we get two random numbers that are different
            do {
                randomNumber = Math.ceil(Math.random() * 51);
                randomNumber2 = Math.ceil(Math.random() * 51);
            } while (randomNumber == randomNumber2);

            tempCardHolder = cards[randomNumber];
            cards[randomNumber] = cards[randomNumber2];
            cards[randomNumber2] = tempCardHolder;

        }

    }

    this.deal = function(){
        return cards.shift();
    }

    this.getNumCardsLeft = function(){
        return cards.length;
    }   

}
Machavity
  • 30,841
  • 27
  • 92
  • 100
Mike P
  • 419
  • 1
  • 7
  • 16
  • 3
    `Math.ceil(x)` will only give `0` if `-1 < x <= 0` and such an `x` is extreeeeeemly unlikely as a result from `y = Math.random()`, which gives `0 <= y < 1` – Paul S. Feb 18 '15 at 00:47
  • ah, that's kind of what i was figuring. So is there a better way to get a random number between 0-51 inclusive? – Mike P Feb 18 '15 at 00:50
  • 1
    You should be using `Math.floor(Math.random() * 52)` – Bergi Feb 18 '15 at 00:52
  • 1
    Btw, your `x` and `y` variables lack a `var` declaration. – Bergi Feb 18 '15 at 00:53
  • 2
    Of course, your shuffle is not a very good one. Even after 50 random swaps the probability of a `0` at index `0` is still about 14%! Why don't you use [a proper one](http://stackoverflow.com/q/2450954/1048572)? – Bergi Feb 18 '15 at 00:56
  • Well that's not surprising... I had that algorithm initially, but then decided to write my own for learning purposes instead of just copying code. And for the reasons seen above (as per my question). Plus, I was having some run-time errors so I had simply things a bit to figure out what was going on. I will likely swap it out for the Fisher-Yates shuffle now that I have a better grasp on things. – Mike P Feb 18 '15 at 01:03

1 Answers1

0

Use Math.floor to round your numbers. For inclusive ranges, make sure you multiply one larger than your desired maximum value

Here is an example of a random integer generator for inclusive end points

function random_int(max, min) {
    min = min || 0;
    return min + Math.floor(Math.random() * (max - min + 1));
}
Paul S.
  • 64,864
  • 9
  • 122
  • 138