Search code examples
javascriptarraysplaying-cards

Dealing Cards from a Deck and Removing the Cards from an Array


I have an array of card names like this:

var deckNames = [ "unused",
  "sA", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "sJ", "sQ", "sK",
  "hA", "h2", "h3", "h4", "h5", "h6", "h7", "h8", "h9", "h10", "hJ", "hQ", "hK",
  "cA", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "c10", "cJ", "cQ", "cK",
  "dA", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "dJ", "dQ", "dK",
  ];

And I want to write a function that randomly selects a card from the array and also removes it from the "deckNames" array above. I have written the following, but it does not seem to be working.

var deal = function(){
    var card = Math.floor(Math.random() * 52) + 1;
    return deckNames[card];
    deckNames.splice(card,1);
};

When I run the deal function in the console, it randomly picks and returns a card from the array, but the deckNames array itself does not get the dealt card removed from the array. How can I achieve this? Thank you.


Solution

  • Your return statement ends your function before the deck is modified. Switch the statements around so that the return is the last thing in the function. Additionally, as @DavidE points out, you can't get the card from the array after it's already been removed, so you have to retrieve it before you remove it:

    var deal = function(){
        var index = Math.floor(Math.random() * 52) + 1;
        var card = deckNames[index];
        deckNames.splice(index, 1);
        return card;
    };
    

    Or simply:

    var deal = function(){
        var card = Math.floor(Math.random() * 52) + 1;
        return deckNames.splice(card, 1)[0];
    };
    

    (since splice returns the removed element, wrapped in a new array).


    Some other things to consider:

    • Array indices start at 0, so chances are you don't want the +1 in your random number generator. You actually want numbers from 0 to 51*:

      var card = Math.floor(Math.random() * 52);

    • Every time you deal a card the size of the deck decreases. Instead of generating random numbers up to 51 each time, base that number on the size of the deck when the function is called. Otherwise you'll get index out of bound errors. See below.


    Ultimately, this gives you something like this:

    var deal = function(){
        var card = Math.floor(Math.random() * deckNames.length);
        return deckNames.splice(card, 1)[0];
    };