Home > Back-end >  I get a random error when generating cards for my deck in JavaScript
I get a random error when generating cards for my deck in JavaScript

Time:12-08

My goal is to make a simple card game. I have this bug where sometimes it doesn't push one of the objects into the array. First I thought that the picked number wouldn't fit between the if statements to declare the values of the objects.

I have tried to redefining the pickedNumber manually right after it got the random value. Then it worked. The numbers that I have problems with are: 36, 38, 24, 25, 37 when it was random, but when I defined the var pickedNumber manually it worked as it should.

How can I fix this?

picture of when the code fails

picture of when it works

function log(txt) {
  console.log(txt);
}
let cards = [];
let hand = [];

// fill card deck
for (let i = 1; i < 53; i  ) {
  cards.push(i);
}

// index for to make the random math not to choose a number over the highest index of cards[]

// loop for picking some random card with a value
for (let i = 0; i < 3; i  ) {
  // random index to choose
  let randomNumber = Math.floor(Math.random() * cards.length);
  log(randomNumber);
  // random number
  let pickedNumber = cards[randomNumber];
  log(pickedNumber);
  // remove the picked card
  const index = cards.indexOf(pickedNumber);
  if (index > -1) {
    cards.splice(index, 1);
  }
  let finalValue;
  let card = {
    value: finalValue,
    suit: "",
  };

  // these if statements are for deviding the cards from 52 to 4x13
  if (pickedNumber < 14) {
    card.value = pickedNumber;
    card.suit = "♥";
    hand.push(card);
  } else if (pickedNumber > 13 && pickedNumber < 26) {
    card.value = pickedNumber -= 13;
    card.suit = "♣";
    hand.push(card);
  } else if (pickedNumber > 26 && pickedNumber < 39) {
    card.value = pickedNumber -= 26;
    card.suit = "♦";
    hand.push(card);
  } else if (pickedNumber > 39 && pickedNumber < 53) {
    card.value = pickedNumber -= 39;
    card.suit = "♠";
    hand.push(card);
  }

  // reduce maxIndex to dont overpick index
}
log(hand);

CodePudding user response:

A fuller representation of a deck of cards is pretty simple and well-advised.

In the snippet below, freshDeck enumerates a complete standard deck, using push() to add cards. The Fisher-Yates shuffle() shuffles the deck, slice() peeks at cards, and splice() moves cards from one pile (array) to another.

function freshDeck() {
  const suits = [ "♥", "♣", "♦","♠"];
  const values = ["A","2","3","4","5","6","7","8","9", "10","J","Q","K"]
  let deck = []
  for (const suit of suits) {
    for (const value of values) {
      deck.push({ suit, value })
    }
  }
  return deck
}

// fy shuffle, thanks to https://stackoverflow.com/a/2450976/294949
function shuffle(array) {
  let currentIndex = array.length,  randomIndex;
  while (currentIndex != 0) {
    randomIndex = Math.floor(Math.random() * currentIndex);
    currentIndex--;
    [array[currentIndex], array[randomIndex]] = [
      array[randomIndex], array[currentIndex]];
  }
  return array;
}

// create a deck
let deck = freshDeck()
console.log(`the deck has ${deck.length} cards`)
console.log(`the first few cards are ${JSON.stringify(deck.slice(0,3))}`)

// suffle the deck
shuffle(deck)
console.log(`\nafter a shuffle, the first few cards are ${JSON.stringify(deck.slice(0,3))}`)

// deal a hand of cards
let hand = deck.splice(0, 5)
console.log(`\ndealt a hand with ${JSON.stringify(hand, null, 0)}`)

console.log(`\nafter dealing, the deck has ${deck.length} cards`)
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

You have an error in your IF statements. You are missing a number in each set

  if (pickedNumber < 14) {
    ...
  } else if (pickedNumber > 13 && pickedNumber < 26) {
    ...
  } else if (pickedNumber > 26 && pickedNumber < 39) {
    ...
  } else if (pickedNumber > 39 && pickedNumber < 53) {
    ...
  }

See how, in the above block of code, if the number is 26 or 39 it won't be picked up. When we change the < 26 to <= 26, that allows it to be detected.

  if (pickedNumber <= 14) { //
    ...
  } else if (pickedNumber > 14 && pickedNumber <= 26) {
    ...
  } else if (pickedNumber > 26 && pickedNumber <= 39) {
    ...
  } else if (pickedNumber > 39 && pickedNumber <= 53) {
    ...
  }
  • Related