0
votes

My goal is to display a deck of cards on a webpage. There will be one button on the page per suit of cards, so four buttons for Hearts, Diamonds, Clubs, Spades, respectively. When the button to display all the hearts cards is clicked, I want to display each heart card one at a time for 3 seconds each in the div id "displayArea". The cards cannot be shown more than once, so I'm guessing they need to be placed in different array once they are displayed. Once all 13 cards have been displayed, I want the screen left blank. My images are stored, relative to my index.html file in "img/Hearts/cards/Ace.jpg". Here is my code so far:

$(document).ready(function(){

    //cards already displayed
    var displayedCards = new Array();

    //card object
    function card(name,suit) {
        this.name = name;
        this.suit = suit;
    } 

    var deck = [
        new card('Ace', 'Hearts'),
        new card('Two', 'Hearts'),
        new card('Three', 'Hearts'),
        new card('Four', 'Hearts'),
        new card('Five', 'Hearts'),
        new card('Six', 'Hearts'),
        new card('Seven', 'Hearts'),
        new card('Eight', 'Hearts'),
        new card('Nine', 'Hearts'),
        new card('Ten', 'Hearts'),
        new card('Jack', 'Hearts'),
        new card('Queen', 'Hearts'),
        new card('King', 'Hearts'),
        new card('Ace', 'Diamonds'),
        new card('Two', 'Diamonds'),
        new card('Three', 'Diamonds'),
        new card('Four', 'Diamonds'),
        new card('Five', 'Diamonds'),
        new card('Six', 'Diamonds'),
        new card('Seven', 'Diamonds'),
        new card('Eight', 'Diamonds'),
        new card('Nine', 'Diamonds'),
        new card('Ten', 'Diamonds'),
        new card('Jack', 'Diamonds'),
        new card('Queen', 'Diamonds'),
        new card('King', 'Diamonds'),
        new card('Ace', 'Clubs'),
        new card('Two', 'Clubs'),
        new card('Three', 'Clubs'),
        new card('Four', 'Clubs'),
        new card('Five', 'Clubs'),
        new card('Six', 'Clubs'),
        new card('Seven', 'Clubs'),
        new card('Eight', 'Clubs'),
        new card('Nine', 'Clubs'),
        new card('Ten', 'Clubs'),
        new card('Jack', 'Clubs'),
        new card('Queen', 'Clubs'),
        new card('King', 'Clubs'),
        new card('Ace', 'Spades'),
        new card('Two', 'Spades'),
        new card('Three', 'Spades'),
        new card('Four', 'Spades'),
        new card('Five', 'Spades'),
        new card('Six', 'Spades'),
        new card('Seven', 'Spades'),
        new card('Eight', 'Spades'),
        new card('Nine', 'Spades'),
        new card('Ten', 'Spades'),
        new card('Jack', 'Spades'),
        new card('Queen', 'Spades'),
        new card('King', 'Spades')
    ];

    function getRandom(num){
        var my_num = Math.floor(Math.random()*num);
        return my_num;
    }

    function displayHeartCards(){
        do{
            var index = getRandom(52);
            var c = deck[index];
            if(!$.inArray(index, displayedCards) > -1 && deck[index].suit == "Hearts"){
                $("<img>").attr('src','images/cards/' + c.suit + '/' + c.name + '.jpg')
                    .appendTo("#displayArea")
                    .fadeOut('slow')
                    .fadeIn('slow');
                displayedCards.push(c);
            }
        }
        while {

        }
    }

    $("#btnHearts").click(function(){
        displayHeartCards();
    });
    $("#btnDiamonds").click(function(){
        display();
    });
    $("#btnClubs").click(function(){
        display();
    });
    $("#btnSpades").click(function(){
        display();
    });
});

And my HTML:

<div id="main">
    <h1>Press a button to display each card in the suit</h1>
    <ul>
        <li>
            <button id="btnHearts">Show Hearts Cards</button>
        </li>
        <li>
            <button id="btnDiamonds">Show Diamonds Cards</button>
        </li>
        <li>
            <button id="btnClubs">Show Clubs Cards</button>
        </li>
        <li>
            <button id="btnSpades">Show Spades Cards</button>
        </li>
    </ul>
    <div id="displayArea">
    </div>
</div>

Thank you in advance.

2
What seems to be the issue with your code? You haven't asked a question. - Dan Philip

2 Answers

1
votes

"I'm guessing they need to be placed in different array once they are displayed"

I would do it the other way around. That is, when the button is clicked, put all of the cards for the current suit into an array (easy with the .filter() method), and then remove them from that array one by one as they are displayed, using the .splice() method. When the array is empty, stop.

I've made some other "improvements" too:

  • Created your deck with nested loops, rather than having to list all 52 cards individually.
  • Removed the button elements' id attributes, instead giving them a common class and a data-suit attribute. The click handler is then bound using the class, and retrieves the relevant suit from the data-suit attribute.

$(document).ready(function(){
    function card(name,suit) {
        this.name = name;
        this.suit = suit;
    } 

    var deck = [];
    var values = ['Ace', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine', 'Ten', 'Jack', 'Queen', 'King'];
    ['Hearts', 'Diamonds', 'Clubs', 'Spades'].forEach(function(suit) {
      values.forEach(function(value) {
        deck.push(new card(value, suit));
      });
    });

    function getRandom(num){
        return Math.floor(Math.random()*num);
    }

    function display(suit){
      // Create an array for the current suite:
      var suitCards = deck.filter(function(c) { return c.suit === suit });
      
      function showNext() {
        if (suitCards.length === 0) return;

        // Remove a random card
        // Note that .splice() returns an array containing the removed item(s)
        // so use [0] after the () to get the removed card
        var currentCard = suitCards.splice(getRandom(suitCards.length),1)[0];

        // Setting 'alt' rather than 'src' just so that something is
        // visible in the demo, since the real images aren't available here
        $("<img>").attr('alt','images/cards/' + currentCard.suit + '/' + currentCard.name + '.jpg')
          .appendTo("#displayArea")
          .hide()
          .fadeIn('slow')
          .delay(300)
          .fadeOut('slow', function() { // when finished fading
            $(this).remove();           // remove the img
            showNext();                 // show next one
          });
      }
      showNext(); // show first card
    }

    $(".displaySuit").click(function(){
        display($(this).attr("data-suit"));
    });
});
h1 { font-size: 14px; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="main">
    <h1>Press a button to display each card in the suit</h1>
    <ul>
        <li>
            <button class="displaySuit" data-suit="Hearts">Show Hearts Cards</button>
        </li>
        <li>
            <button class="displaySuit" data-suit="Diamonds">Show Diamonds Cards</button>
        </li>
        <li>
            <button class="displaySuit" data-suit="Clubs">Show Clubs Cards</button>
        </li>
        <li>
            <button class="displaySuit" data-suit="Spades">Show Spades Cards</button>
        </li>
    </ul>
    <div id="displayArea">
    </div>
</div>
0
votes

You are checking for index in displayedCards which will always return -1 as you are pushing the object into it not the index. So the line of code

if(!$.inArray(index, displayedCards) > -1 && deck[index].suit == "Hearts")

Should be

if(!$.inArray(c, displayedCards) > -1 && deck[index].suit == "Hearts")