javascripthtmlrandomplaying-cards

How to make JS more random?


My code is a drink or dare game. It draws 1 drink card and 1 wildcard everytime the user clicks a button. The issue im having is it picks the same cards too many times and there's not enough variety in the random selection to make it fun. Is there any way I can reduce the amount of times the same cards gets selected. Sometimes the same card gets picked 2 or 3 times in a row.

    var cards = [
    '1-wildcard',
    '2-wildcard',
    '3-wildcard',
    '4-wildcard',
    '5-wildcard',
    '6-wildcard',
    '7-wildcard',
    '8-wildcard',
    '9-wildcard',
    '10-wildcard',
    '11-wildcard',
    '12-wildcard',
    '13-wildcard',
    '14-wildcard',
    '15-wildcard',
    '16-wildcard',
    '17-wildcard',
    '18-wildcard',
    '19-wildcard',
    '20-wildcard',
    '21-wildcard',
    '22-wildcard',
    '23-wildcard',
    '24-wildcard',
    '25-wildcard',
    '26-wildcard',
    '27-wildcard',
    '28-wildcard',
    '29-wildcard',
    '30-wildcard'
];   

var drinks = [
    '1-drink',
    '2-drinks',
    '3-drinks',
    '4-drinks',
    '5-drinks',
    '6-drinks',
    '7-drinks',
    '8-drinks',
    '9-drinks',
    '1-shot',
    '2-shots',
    '3-shots',
    '4-shots'
]


function drawCard() {
        var randomNumber = Math.floor(Math.random() * (cards.length - 1));
        var randomNumber1 = Math.floor(Math.random() * (drinks.length - 1));
        console.log(cards.length);
        console.log(cards[randomNumber]);
        document.getElementById("drinks").src = 'assets/js/games/cards/drinkordare/' + drinks[randomNumber1] + '.png';
        document.getElementById("wildcard").src = 'assets/js/games/cards/drinkordare/' + cards[randomNumber] + '.png';

        switch(cards[randomNumber]) {
            
        }

        switch (drinks[randomNumber1]) {

        }
}

Solution

  • You could add the last selected cards to a temporary array (lets call it card-A), and then select the next card in the remaining cards. Then, when (5 for example) more cards after card-A were picked, you push back card-A to your initial array once again, and so one.

    This removes the possibility that (in this case 5) cards are selected in a row while keeping the algorithm random. For example, I did this algorithm with the cards (but keep note that it's the same algorithm for the drinks, you just need to change names and the array).

    let cards = ['1-wildcard','2-wildcard','3-wildcard','4-wildcard','5-wildcard','6-wildcard','7-wildcard','8-wildcard','9-wildcard','10-wildcard','11-wildcard','12-wildcard','13-wildcard','14-wildcard','15-wildcard','16-wildcard','17-wildcard','18-wildcard','19-wildcard','20-wildcard','21-wildcard','22-wildcard','23-wildcard','24-wildcard','25-wildcard','26-wildcard','27-wildcard','28-wildcard','29-wildcard','30-wildcard'];
    let lastSelectedCards = [];
    
    function getRandomCard() {
      let bufferSize = 5; // If you pick a card, the next 5 cards will not be the same
      let randomNumber = Math.floor(Math.random() * (cards.length - 1));
      
      // Push to the selected array and removes from the cards array
      lastSelectedCards.push(cards[randomNumber]);
      cards.splice(randomNumber, 1);
      
      // Push back the last element in the cards array after 5 new random cards selected
      if (lastSelectedCards.length == bufferSize + 2) {
        cards.push(lastSelectedCards.shift());
      }
      
      // Returns the last selected card
      return lastSelectedCards[lastSelectedCards.length - 1];
    }
    
    // Select 10 cards for testing
    for (let i = 0; i < 10; i++) {
      console.log(getRandomCard());
    }