Search code examples
javascriptplaying-cards

Javascript while loop (Card deck simulation)


I am having an issue with the following code that simulates a card deck.

The deck is created properly (1 array containing 4 arrays (suits) containing 13 elements each (face values)) and when I use the G.test(); function it is correctly pulling 13 random cards but then returns 39x "Empty" (A total of 52).

I hate to ask for help, but I have left the problem overnight and then some and I still cannot find the reason that this is happening. I appreciate any and all insight that can be offered.

var G = {};
G.cards = [[], [], [], []];

G.newCard = function(v) { //currently a useless function, tried a few things
    return v;
};

G.deck = {    
    n: function() { //new deck
        var x; var list = [];
        list.push(G.newCard("A"));

        for (x = 2; x <= 10; x += 1) {
            list.push(G.newCard(x.toString()));
        }

        list.push(G.newCard("J"), G.newCard("Q"), G.newCard("K"));

        for (x = 0; x < G.cards.length; x += 1) {
            G.cards[x] = list;
        }
    },

    d: function() { //random card - returns suit & value
        var s; var c; var v; var drawn = false; var n;

        s = random(0, G.cards.length);
        c = random(0, G.cards[s].length);
        n = 0;

        while (!drawn) {
            if (G.cards[s].length > 0) {
                if (G.cards[s][c]) {
                    v = G.cards[s].splice(c, 1);
                    drawn = true;
                } else {
                    c = random(0, G.cards[s].length);
                }
            } else {
                s = (s + 1 >= G.cards.length) ? 0 : s + 1;
                n += 1;
                console.log(s);
                if (n >= G.cards.length) {
                    console.log(n);
                    return "Empty";

                }
            }
        }
        return {s: s, v: v[0]};
    },
}; //G.deck

G.test = function() {
    var x; var v;
    G.deck.n();
    for (x = 0; x < 52; x += 1) {
        v = G.deck.d();
        console.log(v);
    }
}; 

Solution

  • Replace

    for (x = 0; x < G.cards.length; x += 1) {
        G.cards[x] = list;
    }
    

    with

    for (x = 0; x < G.cards.length; x += 1) {
        G.cards[x] = list.slice();
    }
    

    as this prevents all elements of G.cards[x] binding to the same (single) array instance.

    If all elements bind to the same instance, mutating one element equals mutating all elements. list.slice() creates a new copy of list and thus a new array instance to prevent the aforementioned issue.