Problem with last card flipping over in memory game

Viewed 184

I created a memory card game and I am having an issue that the last card is not flipping over before the alert is coming up that they have finished the game. I have been stuck on thios for a while now and I have inserted my js code below. I'm pretty new to all of this so any help would be great.

const badges = document.querySelectorAll(".badge-card");

//Declaring the variables
let hasFlippedCard = false;
let isBoardLocked = true;
let cardOne, cardTwo;
let noOfMatches = 0;

//Funtion to randomise the cards
(function randomiseCards() {
  badges.forEach((card) => {
    let ramdomPos = Math.floor(Math.random() * 16);
    card.style.order = ramdomPos;
  });
})();

badges.forEach((card) => card.addEventListener("click", flipCard));

//Funtion to flip the cards
function flipCard() {
  if (isBoardLocked) return;
  if (this === cardOne) return;

  this.classList.add("flip");

  if (!hasFlippedCard) {
    hasFlippedCard = true;
    cardOne = this;
    return;
  }
  cardTwo = this;
  isBoardLocked = true;
  checkForMatch();
}



//Funtion to check for matches
function checkForMatch() {
  let isMatch = cardOne.dataset.framework === cardTwo.dataset.framework;

  if (isMatch) {
    countMatches();
    disableCards();

  } else {
    unflipCards();
  }
}

//Funtion to count matches of cards
function countMatches() {
  noOfMatches = noOfMatches + 1;
  if (foundAllMatches()) {
    alert("Congratulations you got all " + noOfMatches + " matches");
    stopGame();
  }
}

//Funtion to check if user has found all matches
function foundAllMatches() {
  if (noOfMatches == badges.length / 2) {
    return true;
  } else {
    return false;
  }
}

//Funtion to disbale the cards
function disableCards() {
  cardOne.removeEventListener("click", flipCard);
  cardTwo.removeEventListener("click", flipCard);

  resetBoard();
}

//Funtion to unflip the cards
function unflipCards() {
  setTimeout(() => {
    cardOne.classList.remove("flip");
    cardTwo.classList.remove("flip");

    //time to flip card back over
    resetBoard();
  }, 900);
}

//Funtion to reset the board
function resetBoard() {
  hasFlippedCard = false;
  isBoardLocked = false;
  cardOne = null;
  cardTwo = null;
}

//Funtion to unflip cards at end of game
function unflipAllcards() {
  $(".flip").removeClass('flip');
}

//Timer and start game button
  let timeContainer = $('#timer-value');
  let startButton2 = $('#start-game')
  let timer = 0;
  let maxTime = 60;
  let timeout = null;

  function count() {
    timeout = setTimeout(function () {
      if (timer < maxTime) {
        timer++;
        $(timeContainer).text(timer)
        count();
      } else {
        alert("Time's up! You got " + noOfMatches + " matches");
        startButton2.show()
        stopGame();
      }
    }, 1000);
  }

  //Start game button
  function startGame() {
    if (timeout) {
      clearTimeout(timeout);
    }
    timer = 0;
    $(timeContainer).text(timer)
    startButton2.hide()
    count();
    isBoardLocked = false;
  }

  //Funtion for stopping the game
  function stopGame() {
    if (timeout) {
      clearTimeout(timeout);
      startButton2.show()
    }
    timer = 0; 
    $(timeContainer).text(timer)
    isBoardLocked = true;
    unflipAllcards();
  }

If anyone has any questions please let me know.

2 Answers

An alert stops further javascript execution. You can either wait until the last card has flipped before firing the alert or create your own popup modal that appears when the memory has been solved.

We can introduce a delay to the alert, by setTimeout so alert will play after the card has been flipped, I have changed the function, countMatches as:

function countMatches() {
  noOfMatches = noOfMatches + 1;
  if (foundAllMatches()) {
    setTimeout(function(){
      alert("Congratulations you got all "     + noOfMatches + " matches");
    stopGame();
    },1000);
  }
}

Final Change:

const badges = document.querySelectorAll(".badge-card");

//Declaring the variables
let hasFlippedCard = false;
let isBoardLocked = true;
let cardOne, cardTwo;
let noOfMatches = 0;

//Funtion to randomise the cards
(function randomiseCards() {
  badges.forEach((card) => {
    let ramdomPos = Math.floor(Math.random() * 16);
    card.style.order = ramdomPos;
  });
})();

badges.forEach((card) => card.addEventListener("click", flipCard));

//Funtion to flip the cards
function flipCard() {
  if (isBoardLocked) return;
  if (this === cardOne) return;

  this.classList.add("flip");

  if (!hasFlippedCard) {
    hasFlippedCard = true;
    cardOne = this;
    return;
  }
  cardTwo = this;
  isBoardLocked = true;
  checkForMatch();
}



//Funtion to check for matches
function checkForMatch() {
  let isMatch = cardOne.dataset.framework === cardTwo.dataset.framework;

  if (isMatch) {
    countMatches();
    disableCards();

  } else {
    unflipCards();
  }
}

//Funtion to count matches of cards
function countMatches() {
  noOfMatches = noOfMatches + 1;
  if (foundAllMatches()) {
    setTimeout(function(){
      alert("Congratulations you got all "     + noOfMatches + " matches");
    stopGame();
    },1000);
  }
}

//Funtion to check if user has found all matches
function foundAllMatches() {
  if (noOfMatches == badges.length / 2) {
    return true;
  } else {
    return false;
  }
}

//Funtion to disbale the cards
function disableCards() {
  cardOne.removeEventListener("click", flipCard);
  cardTwo.removeEventListener("click", flipCard);

  resetBoard();
}

//Funtion to unflip the cards
function unflipCards() {
  setTimeout(() => {
    cardOne.classList.remove("flip");
    cardTwo.classList.remove("flip");

    //time to flip card back over
    resetBoard();
  }, 900);
}

//Funtion to reset the board
function resetBoard() {
  hasFlippedCard = false;
  isBoardLocked = false;
  cardOne = null;
  cardTwo = null;
}

//Funtion to unflip cards at end of game
function unflipAllcards() {
  $(".flip").removeClass('flip');
}

//Timer and start game button
  let timeContainer = $('#timer-value');
  let startButton2 = $('#start-game')
  let timer = 0;
  let maxTime = 60;
  let timeout = null;

  function count() {
    timeout = setTimeout(function () {
      if (timer < maxTime) {
        timer++;
        $(timeContainer).text(timer)
        count();
      } else {
        alert("Time's up! You got " + noOfMatches + " matches");
        startButton2.show()
        stopGame();
      }
    }, 1300);
  }

  //Start game button
  function startGame() {
    if (timeout) {
      clearTimeout(timeout);
    }
    timer = 0;
    $(timeContainer).text(timer)
    startButton2.hide()
    count();
    isBoardLocked = false;
  }

  //Funtion for stopping the game
  function stopGame() {
    if (timeout) {
      clearTimeout(timeout);
      startButton2.show()
    }
    timer = 0; 
    $(timeContainer).text(timer)
    isBoardLocked = true;
    unflipAllcards();
  }

Problem 2:

Cards's getting disabled, at the end of matching all cards, you have removed click event listeners for cards after matching hence we must add them in start game.

Paste this part from our starting code ( main.js body ) :

badges.forEach((card) =>
card.addEventListener("click", flipCard));

Into startGame() as :

function startGame() {
    badges.forEach((card) =>                            card.addEventListener("click", flipCard));
    if (timeout) {
      clearTimeout(timeout);
    }
    timer = 0;
    $(timeContainer).text(timer)
    startButton2.hide()
    count();
    isBoardLocked = false;
  }
Related