0

My problem is that I want to make reset/new game button to my simple memory game and it went well until the cards have to shuffle again. Now it only works to play same game over and over again. Here is my code,

$(document).ready(function() {

  var app = {
    cards: ["bmw.jpg", "bmw.jpg", "Daisy.jpg", "Daisy.jpg", "koira.jpg", "koira.jpg", "Macarons.jpg", "Macarons.jpg", "owl.jpg", "owl.jpg", "shakki.jpg", "shakki.jpg"],
    init: function() {
      app.shuffle();

    },

    shuffle: function() { // shuffle the cards
      var random = 0;
      var temp = 0;
      for (i = 1; i < app.cards.length; i++) {
        random = Math.round(Math.random() * i);
        temp = app.cards[i];
        app.cards[i] = app.cards[random];
        app.cards[random] = temp;



      }
      app.assignCards();

      console.log('Shuffled Card Array: ' + app.cards);
    },
    assignCards: function() { // matching the shuffled card array with html
      $('.card').each(function(index) {
        $(this).attr('data-card-value', app.cards[index]);



      });
      app.clickHandlers();

    },
    clickHandlers: function() { // showing the card picture
      $('.card').on('click', function() {
        $(this).html('<img src="' + $(this).data('cardValue') + '">').addClass('selected');
        app.checkMatch();



      });

    },
    checkMatch: function() { //check the match
      if ($('.selected').length == 2) { // if 2 cards is selected
        if ($('.selected').first().data('cardValue') == $('.selected').last().data('cardValue')) {
          // same cards ->> remove the cards
          $('.selected').each(function() {
            $(this).animate({
              opacity: 0
            }).removeClass('unmatched');
            var numItems = $('.unmatched').length
            var numSel = $('.selected').length
            console.log(numSel)

          });

          $('.selected').each(function() {
            $(this).removeClass('selected');
          });
          app.checkWin();
        } else { // if no match, remove the selected
          setTimeout(function() {
            $('.selected').each(function() {
              $(this).html('').removeClass('selected');
            });

          }, 500)

        }
      }
    },
    checkWin: function() {
      if ($('.unmatched').length === 0) {
        $('.main').html('<h1>You Won!</h1>');
      }
    },

  };
  app.init();

  $('.al').on('click', function() {

    newGame();
    app.init();

  });

  function newGame() { //reset/starting a new game
    $('.card').empty('<img src="' + $(this).data('cardValue') + '">').removeClass('selected');
    $('.card').animate({
      opacity: 1
    }).addClass('card');

  };



});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1> Memory Game </h1>


<button class="al">New Game</button>

<main class="main">
  <div class="card unmatched"></div>
  <div class="card unmatched"></div>
  <div class="card unmatched"></div>
  <div class="card unmatched"></div>
  <div class="card unmatched"></div>
  <div class="card unmatched"></div>
  <div class="card unmatched"></div>
  <div class="card unmatched"></div>
  <div class="card unmatched"></div>
  <div class="card unmatched"></div>
  <div class="card unmatched"></div>
  <div class="card unmatched"></div>

</main>

<div class="memory-game">

  <img class="front" src="bmw.jpg" alt="bmw">
  <img class="front" src="Daisy.jpg" alt="daisy">
  <img class="front" src="Daisy.jpg" alt="daisy">
  <img class="front" src="koira.jpg" alt="koira">
  <img class="front" src="koira.jpg" alt="koira">
  <img class="front" src="Macarons.jpg" alt="maca">
  <img class="front" src="Macarons.jpg" alt="maca">
  <img class="front" src="owl.jpg" alt="owl">
  <img class="front" src="owl.jpg" alt="owl">
  <img class="front" src="shakki.jpg" alt="shakki">
  <img class="front" src="shakki.jpg" alt="shakki">
</div>

I have tried to do variables/arrays to make the game remember the old cards so it could shuffle them again. But it only shuffles the new array.

5
  • 1
    The clickHandlers function adds the event handlers to the elements whether they've been added previously or not. Consider using event delegation to attach a single event handler higher up in the DOM so you don't have to worry about attaching/reattaching handlers. Commented Aug 29, 2023 at 13:07
  • remove app.clickHandlers(); and directly use $('.card').on('click', function() {. put it outside of clickHandlers: function() { Commented Aug 29, 2023 at 13:14
  • cards: $(".memory-game img").map(function() { return this.src }).get(), and cache the selected cards to be DRYer: const $selected = $('.selected'); if ($selected.length == 2) .... $selected.removeClass("selected") instead of each etc Commented Aug 29, 2023 at 13:25
  • Your issue is that you are mixing .attr("data-xyz", newVal) with .data("xyx") to write/read the data. Change .attr('data-card-value', app.cards[index]) to .data('card-value', app.cards[index]) and you'll probably be ok. Commented Aug 29, 2023 at 14:09
  • Off topic: when changing data-card-value you might also like to change the alt attribute or not use an alt= at all (or set it to "unmatched" or so until clicked. Commented Aug 29, 2023 at 14:21

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.