skip to Main Content

I am trying to create a card dealer that deals 5 cards when a button is clicked on the web page.

Basically, I want to create a card object with 2 attributes, ‘suit’ and ‘value’, once that is done I want to create an array of 52 card objects with random suits and values but ideally they should all be unique.
Out of those 52 card objects, I would like 5 to be selected and displayed when the button is clicked.
I am not getting any output from my function that is invoked from my button and I don’t really understand why.

I am really new to Javascript and the professor teaching the intro class I am taking right now isn’t very helpful, unfortunately.

Here is my current code:

  <head>
    <script src="https://code.jquery.com/jquery-3.6.3.min.js"></script>
  </head>
  <body>
    <h1>Robo Dealer</h1>

    <button onclick="dealHand();">Deal Hand</button>

    <hr />
    <div id="card_hand"></div>

    <script>
      // Declaring arrays for suits and values
      const suits = ["Hearts", "Spades", "Clubs", "Diamonds"];
      const values = [
        "Ace",
        2,
        3,
        4,
        5,
        6,
        7,
        8,
        9,
        10,
        "Jack",
        "Queen",
        "King",
      ];
      // Creating the card object
      function cards(value, suit) {
        this.value = value;
        this.suit = suit;
      }
      // Creating array of 52 card objects
      var deck = new Array();
      function getDeck() {
        for (i = 0; i < 52; i++) {
          let cardObject = new cards(
            values[Math.random()],
            suits[Math.random()]
          );
          deck.push(cardObject);
        }
        return deck;
      }
      //  Dealing hand of 5 card objects / outputting it to HTML
      const dealHand = () => {
        for (i = 0; i < 6; i++) {
          $("#card_hand").html(getDeck());
        }

        return false; // prevent page reload
      };
    </script>
  </body>

2

Answers


  1. Here is a tidied up version of your script, involving a Durstenfeld shuffle and a simple array containing the 52 cards deck. The first 5 cards of the shuffled deck are being dealt:

    function shfl(a){ // Durstenfeld shuffle
     for(let j,i=a.length;i>1;){
      j=Math.floor(Math.random()*i--);
      if (i!=j) [a[i],a[j]]=[a[j],a[i]]
     }
     return a
    }
    const suits = ["Hearts", "Spades", "Clubs", "Diamonds"],
      values = ["Ace",2,3,4,5,6,7,8,9,10,"Jack","Queen","King"],
      deck=[];
    suits.forEach(s=>values.forEach(v=>
       deck.push(s+"-"+v)));
    
    console.log(shfl(deck).slice(0,5));
    Login or Signup to reply.
  2. OK, lets take a look at how you might approach this using objects.
    At the moment you’re just iterating 52 times and selecting suits/values at random. What you probably should do is create the deck first by iterating over the suits and values, shuffle them, and then return the top five cards (like a casino would do).

    There’s a couple of bits of code here that you might not be familiar with but I’ll include some notes, and some links to documentation at the end. I did get a little carried away with this but I hope that some of it is useful.

    // Cache the element that will hold the hand,
    // and the button, and add a listener to the button
    const cardHand = document.querySelector('#card_hand');
    const button = document.querySelector('button');
    button.addEventListener('click', play);
    
    // Set up the suits and values
    const suits = ['♥', '♠', '♣', '♦'];
    const values=["Ace",2,3,4,5,6,7,8,9,10,"Jack","Queen","King"];
    
    // https://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array
    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 new deck of cards. Iterate over the suits first
    // and have an inner loop that iterates over the values. That
    // way you'll return a complete deck of 52 card objects. Each object
    // is `{ value, suit }`. You may want to shuffle the deck at some point
    // and you can use the Fisher/Yates algorithm for that (see above)
    function createDeck() {
      const deck = [];
      for (i = 0; i < suits.length; i++) {
        for (j = 0; j < values.length; j++) {
          const card = { value: values[j], suit: suits[i] };
          deck.push(card);      
        }
      }
      return shuffle(deck);
    }
    
    // Create some cards HTML - `map` over the `hand` array
    // and then, using a template string, create some HTML for
    // each card. `map` returns an array so we need to join it up
    // into a single string after the iteration is complete
    function createHTML(hand) {
      return hand.map(card => {
        return (
          `<div class="card ${card.suit}">
            ${card.value} ${card.suit}
           </div>`
        );
      }).join('');
    }
    
    // Create the deck
    const deck = createDeck();
    
    function play() {
    
      // If there are enough cards in the deck
      // take off the first 5 and display them
      if (deck.length >= 5) {
        const hand = deck.splice(0, 5);
        cardHand.innerHTML = createHTML(hand);
      } else {
        cardHand.textContent = 'No cards remaining';
      }
    }
    #card_hand { display: grid; grid-template-columns: repeat(auto-fit, minmax(80px, 1fr)); gap: 0.5em;  }
    .card { height: 100px; width: 70px; border: 1px solid #555; display: flex; justify-content: center; align-items: center; }
    .♥, .♦ { color: red; }
    <button type="button">Deal Hand</button>
    <hr />
    <div id="card_hand"></div>

    Additional documentation

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search