2

Click

function click() {

        createCards();
        pickCard();

    }

Pick Card

function pickCard() {
        var x = Math.floor(Math.random() * ((15 - 0) + 1) + 0);
        var title = cards.chance[x].title;
        console.log(x + ". " + title);
        //pop the array we just picked
        //adjust Math.floor since there are only 15 cards to pick from instead of  16

    }

Create Cards

function createCards() {
cards = {

    chance: [{
        title: 'Advance to go',
        type: 'move',
        position: 40
    }, {
        title: "Advance to London",
        type: "move",
        position: 39
    }, {
        title: "Your ass is going to jail",
        type: "move",
        position: 10
    }, {
        title: "Advance to Rome",
        type: "move",
        position: 24
    }, {
        title: "Advance to Charles de Gaulle",
        type: "move",
        position: 15
    }, {
        title: "Advance to Amsterdam",
        type: "move",
        position: 11
    }, {
        title: "Go back 3 spaces",
        type: "movex",
        position: -3
    }, {
        title: "No drink and driving mate1",
        type: "bill",
        bill: 20
    }, {
        title: "Get out of Jail free card",
        type: "bill",
        bill: 150
    }, {
        title: "Pay school fees",
        type: "bill",
        bill: 150
    }, {
        title: "Speeding fine",
        type: "bill",
        bill: 150
    }, {
        title: "Bank pays you dividend",
        type: "bonus",
        bonus: 40
    }, {
        title: "You have won the competition",
        type: "bonus",
        bonus: 200
    }, {
        title: "Your building loan matures",
        type: "bonus",
        bonus: 200
    }, {
        title: "You are assessed for street repairs $40 per house $115 per hotel",
        type: "billx"
    }, {
        title: "House repairs $25 per house $100 per hotel",
        type: "billx"
    }]
};

}

Ok guys, I am trying to pick a random card, then I want to pop it, but since I am using random generator, I would have to adjust the min, max values because there would be 1 card less in the array. Also I would accept a better answer, a more efficient way of doing it. For example shuffle? I wouldnt know how that would work.

Elton Frederik
  • 259
  • 1
  • 3
  • 12

4 Answers4

1

You can use splice to pop the element and use array.length instead of using a fixed number.

   // if there are no more cards, create them

   var cardsLeft = cards.chance.length;
   if(cardsLeft == 0){
     createCards();
   }

    // Math  
    var x = Math.floor(Math.random() * cardsLeft);

    // pop
    cards.chance.splice(x, 1);  
pasine
  • 11,311
  • 10
  • 49
  • 81
  • For me so far this answer seems to do the trick most efficiently. I would just have to `createCards` again once they all have been picked. Just need to look at the other answers to make my decision. – Elton Frederik Jan 25 '14 at 12:44
  • added an extra control to check if there are any cards left before picking one. – pasine Jan 25 '14 at 12:57
  • I just need one more little tweak. In the Monopoly game there are 2 types of cards to be drawn. Chance cards and Chest cards. I want to reuse your answer rather than create another function. So how would I achieve something like `cards.[chance or chest].title`? I could pass the card type as a parameter. – Elton Frederik Jan 25 '14 at 13:02
  • Do you know how the data structure of a Javascript object work? var cards = { chance : [], chest : []} – pasine Jan 25 '14 at 18:07
  • Not exactly. Im learning as I go along. But I asked my last question here [link](http://stackoverflow.com/questions/21351553/get-array-property-value-using-variable/21351574#21351574) – Elton Frederik Jan 25 '14 at 18:38
1

I'd 'shuffle' the cards at the start:

function shuffle(cards) {

    var shuffled = [],
        i = cards.length,
        j = 0;

    while (i--) {
        j = Math.floor(Math.random() * (i+1));
        shuffled.push(cards[j]);
        cards.splice(j,1);    
    }

    return shuffled;

}

var shuffledCards = shuffle(cards.chance);

The shuffledCards array will now hold all the cards but in a random order. You can then either pop cards from shuffledCards as you use them, or use a counter to work your way through them. The latter means you can reshuffle the cards later.

Note: this is just a reworking of what I wrote here: https://stackoverflow.com/a/18806417/1937302

Community
  • 1
  • 1
Ben Jackson
  • 11,722
  • 6
  • 32
  • 42
0

First fill an array with indexes:

var i, indexes, pickedIndex;

indexes = [];
for (i = 0; i < 15; i++) // 16 cards from 0 to 15
{
  indexes[i] = i;
}

Now, when you need a card, pick the index first:

pickedIndex = Math.floor(Math.random() * indexes.length);

Then, remove the consumed index by overwriting the one picked with the last in the array:

i = indexes.pop();

if (pickedIndex <= indexes.length)
{
    indexes[pickedIndex] = i;
}

The above snippet reduces the remaining indexes by one, removes the one picked and keeps the probability of future pickings uniformly distributed across the indexes.

Use the picked index to get the actual card.

When indexes.length is 0, all indexes have been picked.

pid
  • 11,472
  • 6
  • 34
  • 63
0

This answer uses the index method to sort the chance cards in random order then runs through the cards from 0 to 15.

<!DOCTYPE HTML>
<html>
<head>
<title>card shuffle</title>

<script type="text/javascript">
function set() {
        pack = new createCards();
        pack.shuffle();

    }

function click() {
    pack.pickCard();
}    

function pickCard() {
        var title = this.cards.chance[this.pick++].title;
        console.log((this.pick-1) + ". " + title);

    } 

function shuffle() {
    for (var i=0; i<16; i++) {
        this.cards.chance[i].place=Math.random();
    }
    //sort chance cards on place order which is now random 
    this.cards.chance.sort(function(a,b) {return a.place - b.place;});      
}

function createCards() {
this.cards = {

    chance: [{
        place:0,
        title: 'Advance to go',
        type: 'move',
        position: 40
    }, {
        place:0,
        title: "Advance to London",
        type: "move",
        position: 39
    }, {
        place:0,
        title: "Your ass is going to jail",
        type: "move",
        position: 10
    }, {
        place:0,
        title: "Advance to Rome",
        type: "move",
        position: 24
    }, {
        place:0,
        title: "Advance to Charles de Gaulle",
        type: "move",
        position: 15
    }, {
        place:0,
        title: "Advance to Amsterdam",
        type: "move",
        position: 11
    }, {
        place:0,
        title: "Go back 3 spaces",
        type: "movex",
        position: -3
    }, {
        place:0,
        title: "No drink and driving mate1",
        type: "bill",
        bill: 20
    }, {
        place:0,
        title: "Get out of Jail free card",
        type: "bill",
        bill: 150
    }, {
        place:0,
        title: "Pay school fees",
        type: "bill",
        bill: 150
    }, {
        place:0,
        title: "Speeding fine",
        type: "bill",
        bill: 150
    }, {
        place:0,
        title: "Bank pays you dividend",
        type: "bonus",
        bonus: 40
    }, {
        place:0,
        title: "You have won the competition",
        type: "bonus",
        bonus: 200
    }, {
        place:0,
        title: "Your building loan matures",
        type: "bonus",
        bonus: 200
    }, {
        place:0,
        title: "You are assessed for street repairs $40 per house $115 per hotel",
        type: "billx"
    }, {
        place:0,
        title: "House repairs $25 per house $100 per hotel",
        type: "billx"
    }]
}    
this.pick=0;    

this.pickCard=pickCard;
this.shuffle=shuffle;
};

set();
for(var i=0;i<16;i++) {
    click();
}

</script>
</head>
<body>  
</body>
</html>
jing3142
  • 1,821
  • 1
  • 11
  • 16