2

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]) {

        }
}
Scott Montford
  • 165
  • 1
  • 9
  • How frequently are you getting 2 or 3 of the same in a row? Getting the same card multiple times in a row is still randomly possible, but if you wanted to just avoid that anyway, you could keep track of the last several cards chosen and keep randomly choosing a new card until it's not a recent repeat. – zeterain Aug 19 '20 at 14:45
  • Humans aren't very good at evaluating randomness but very good at detecting patterns, even when there aren't any. If you have only 13 "drinks" cards, you're going to get the same card on average every 13th time, sometimes more often because that's how randomness works. So what you really want is something *less* random that avoids picking same cards again. – Guy Incognito Aug 19 '20 at 14:46

2 Answers2

2

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());
}
xam4lor
  • 64
  • 6
0

You can prevent repetitions by making a shuffled copy of the array, popping from it, and refilling when you run out- like this:

var cards = ["a", "b", "c"], shuffledCards = [];
for(var i = 0; i < 10; i++) console.log((shuffledCards = shuffledCards.length ? shuffledCards : randoSequence(cards)).pop().value);
<script src="https://randojs.com/2.0.0.js"></script>

This code uses Rando.js to shuffle, but you can shuffle with plain JavaScript if you refer.

Aaron Plocharczyk
  • 2,776
  • 2
  • 7
  • 15