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.

Alive to die - Anant
  • 70,531
  • 10
  • 51
  • 98
  • 1
    The `clickHandlers` function adds the event handlers to the elements whether they've been added previously or not. Consider using [event delegation](https://stackoverflow.com/q/1687296/215552) to attach a single event handler higher up in the DOM so you don't have to worry about attaching/reattaching handlers. – Heretic Monkey Aug 29 '23 at 13:07
  • remove `app.clickHandlers();` and directly use `$('.card').on('click', function() {`. put it outside of `clickHandlers: function() {` – Alive to die - Anant Aug 29 '23 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 – mplungjan Aug 29 '23 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. – freedomn-m Aug 29 '23 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. – freedomn-m Aug 29 '23 at 14:21
  • 1
    @freedomn-m thank you so much, this solved the problem! – Johanna Aug 29 '23 at 14:34

0 Answers0