How to stop the time automatically when all cards are flipped in memory game using javascript

Viewed 87

I'm having trouble here on how to stop the timer in my memory game. I already try the stop function that I found in the tutorial and google but it didn't work out. Here is my code:

const cards = document.querySelectorAll('.memory-card');

let hasFlippedCard = false;
let lockBoard = false;
let firstCard, secondCard;
let matchCounter=0;


function flipCard() {
  if (lockBoard) return;
  if (this === firstCard) return;

  this.classList.add('flip');

  if (!hasFlippedCard) {
    hasFlippedCard = true;
    firstCard = this;

    return;
  }

  secondCard = this;
  checkForMatch();
}

function checkForMatch() {
  let isMatch = firstCard.dataset.framework === secondCard.dataset.framework;

  if(isMatch){
    matchCounter+=1;
   disableCards();
     if(matchCounter==(cards.length/2)){
      Swal.fire({
        title: 'Congratualtions!!!',
        text: 'You finish the game. Thank you for playng.' ,
      })
      }
   }
   else{ unflipCards(); }

  
}

function disableCards() {
  firstCard.removeEventListener('click', flipCard);
  secondCard.removeEventListener('click', flipCard);

  resetBoard();
}

function unflipCards() {
  lockBoard = true;

  setTimeout(() => {
    firstCard.classList.remove('flip');
    secondCard.classList.remove('flip');

    resetBoard();
  }, 500);
}

function resetBoard() {
  hasFlippedCard = false;
  lockBoard = false;
  firstCard = null;
  secondCard = null;
 
  
}

(function shuffle() {
  cards.forEach(card => {
    let randomPos = Math.floor(Math.random() * 12);
    card.style.order = randomPos;
  });
})();

cards.forEach(card => card.addEventListener('click', flipCard));

function restartButton(){
  location.reload();
}
var i = 0;
function timer(){
  i++;
  if(i === 1){
    time();
  }
}

var numr = 0;
function countClick(){
  numr ++;
  console.log(numr);
}

/*Timer*/

function time(){
 
  // var target = document.getElementsById("back");
  // target.removeAttribute("onclick");
  var minutesLabel = document.getElementById("minutes");
  var secondsLabel = document.getElementById("seconds");
  var totalSeconds = 0;
  setInterval(setTime, 1000);
  
  function setTime() {
    ++totalSeconds;
    secondsLabel.innerHTML = pad(totalSeconds % 60);
    minutesLabel.innerHTML = pad(parseInt(totalSeconds / 60));
  }
  
  function pad(val) {
    var valString = val + "";
    if (valString.length < 2) {
      return "0" + valString;
    } else {
      return valString;
    }
  }
}

var counterVal = 0;

function incrementClick(){
  updateDisplay(++counterVal);
}
function resetCounter(){
  counterVal = 0;
  updateDisplay(counterVal);
}
function updateDisplay(val){
  document.getElementById("counter-label").innerHTML = val;
}
* {
  margin: 0;
  box-sizing: border-box;
}

body {
  background: url('https://github.com/FoxyStoat/memory-game/blob/master/assets/img/ignasi_pattern_s.png?raw=true');
  ;
}
h1{
  font-weight: 400;
  text-shadow: 1px 1px 2px rgba(80, 80, 80, 0.6);
}

.container{
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
}

.memory-game {
  width: 640px;
  height: 640px;
  display: flex;
  flex-wrap: wrap;
  perspective: 100%;
  margin:5px;
}

.memory-card {
  width: calc(25% - 10px);
  height: calc(33.333% - 10px);
  margin:5px;
  /* position: relative; */
  /* transform: scale(1); */
  transform-style: preserve-3d;
  transition: transform .5s;
  box-shadow: 1px 1px 1px rgba(0,0,0,.3);
}

.memory-card:active {
  transform: scale(0.97);
  transition: transform .2s;
}

.memory-card.flip {
  transform: rotateY(180deg);
}

.front-face,
.back-face {
  width: 100%;
  height: 100%;
  /* padding: 1px; */
  position: absolute;
  /* border-radius: 5px; */
  /* background: #1C7CCC; */
  backface-visibility: hidden;
}

.front-face {
  transform: rotateY(180deg);
}

.score-panel {
  text-align: left;
  width: 545px;
  margin-bottom: 10px;
  color: #0d0d0e;
}

.score-panel .stars {
  margin: 0;
  padding: 0;
  display: inline-block;
  margin: 0 5px 0 0;
  color: rgb(24, 23, 23);
}

.score-panel .stars li {
  list-style: none;
  display: inline-block;
}

.score-panel .timer {
  display: inline;
  position: absolute;
  left: 56%;
}

.score-panel .restart {
  float: right;
  cursor: pointer;
}


@media only screen  and (min-device-width: 768px)
  and (max-device-width: 1024px){
     .memory-game{
      width: 860px;
      min-height: 880px;


    }
}
@media only screen
  and (min-device-width: 375px)
  and (max-device-width: 812px) {
    .memory-game{
      width: 860px;
      min-height: 880px;


    }
  }

@media only screen
  and (min-device-width: 320px)
  and (max-device-width: 568px) {
    .memory-game{
      width: 860px;
      min-height: 880px;


    }
  }
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">

<title>Memory Game</title>
<link rel = "stylesheet" href ="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<link rel="stylesheet prefetch" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.1/css/font-awesome.min.css">
<link rel="stylesheet prefetch" href="https://fonts.googleapis.com/css?family=Coda">
<!-- <link rel="stylesheet prefetch" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.1/css/font-awesome.min.css">
    <link rel="stylesheet prefetch" href="https://fonts.googgameleapis.com/css?family=Coda">
    <link rel="stylesheet prefetch" href="https://fonts.googleapis.com/css?family=Gloria+Hallelujah|Permanent+Marker" > 
    <link rel="stylesheet prefetch" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.1/css/font-awesome.min.css">
    <link rel="stylesheet prefetch" href="https://fonts.googleapis.com/css?family=Coda">-->

    <link rel="stylesheet prefetch" href="https://fonts.googleapis.com/css?family=Coda">
    <link rel="stylesheet prefetch" href="https://fonts.googleapis.com/css?family=Gloria+Hallelujah|Permanent+Marker" >

<link href="<?php echo base_url();?>resources/dist/css/style.css" rel="stylesheet">
</head>
<body>
  
<div class = "container">
  <h1>Memory Game</h1>
  <section class="score-panel">
            <!-- <ul class="stars">
                <li><i class="fa fa-star"></i></li>
                <li><i class="fa fa-star"></i></li>
                <li><i class="fa fa-star"></i></li>
            </ul> -->

            <span>Moves <span id = "counter-label">0</span></span>

            <div class="timer">
                <label id="minutes">00</label>:<label id="seconds">00</label>
            </div>

            <div class="restart">
                <button onclick="restartButton()" class="fa fa-repeat"></button>
            <!-- <div class="col text-center">
                <button button type = "button" class = "btn btn-danger">Reset</button>
            </div> -->
            </div>
        </section>
  <div class="memory-game ">
            <div class="memory-card" data-framework="aurelia">
              <img class="front-face" src="<?php echo base_url();?>/resources/dist/img/fb.png" class = "img-fluid"alt="fb" />
              <img onclick = "incrementClick();" id="back" class="back-face" src="<?php echo base_url();?>/resources/dist/img/card.png" class = "img-fluid"alt="yugioh" />
            </div>
            <div class="memory-card" data-framework="aurelia">
              <img class="front-face" src="<?php echo base_url();?>/resources/dist/img/fb.png" class = "img-fluid"alt="fb" />
              <img onclick = "incrementClick(); timer();" id = "back" class="back-face" src="<?php echo base_url();?>/resources/dist/img/card.png" class = "img-fluid"alt="yugioh" />
            </div>

            
  </div> 

</div>
  

<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src = "https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.min.js"></script>
<script src ="<?php echo base_url();?>resources/dist/js/script.js"></script>
<script src="//cdn.jsdelivr.net/npm/sweetalert2@11"></script>
</body>
</html>

Whenever all the cards are flipped the sweet alert will pop up and show the congratulation message but the timer will continue to run despite that the game is finished. I want to stop the timer when all cards are flipped. Thank you in advance for answering. I apologize for my noobness. Kind of new to programming and currently I'm self-thought.

1 Answers

As the guide for setInterval:

setInterval returned intervalID is a numeric, non-zero value which identifies the timer created by the call to setInterval(); this value can be passed to clearInterval() to cancel the interval.

So the answer is uses one variable (timerCtrl in below demo) to save the return value of setInterval, then clearInterval when game over.

const cards = document.querySelectorAll('.memory-card');

let hasFlippedCard = false;
let lockBoard = false;
let firstCard, secondCard;
let matchCounter=0;
let timerCtrl = null; // store the return value of setInterval

function flipCard() {
  if (lockBoard) return;
  if (this === firstCard) return;

  this.classList.add('flip');

  if (!hasFlippedCard) {
    hasFlippedCard = true;
    firstCard = this;

    return;
  }

  secondCard = this;
  checkForMatch();
}

function checkForMatch() {
  let isMatch = firstCard.dataset.framework === secondCard.dataset.framework;

  if(isMatch){
    matchCounter+=1;
   disableCards();
     if(matchCounter==(cards.length/2)){
      Swal.fire({
        title: 'Congratualtions!!!',
        text: 'You finish the game. Thank you for playng.' ,
      })
      clearInterval(timerCtrl); // it will stop the timer
      }
   }
   else{ unflipCards(); }

  
}

function disableCards() {
  firstCard.removeEventListener('click', flipCard);
  secondCard.removeEventListener('click', flipCard);

  resetBoard();
}

function unflipCards() {
  lockBoard = true;

  setTimeout(() => {
    firstCard.classList.remove('flip');
    secondCard.classList.remove('flip');

    resetBoard();
  }, 500);
}

function resetBoard() {
  hasFlippedCard = false;
  lockBoard = false;
  firstCard = null;
  secondCard = null;
 
  
}

(function shuffle() {
  cards.forEach(card => {
    let randomPos = Math.floor(Math.random() * 12);
    card.style.order = randomPos;
  });
})();

cards.forEach(card => card.addEventListener('click', flipCard));

function restartButton(){
  location.reload();
}
var i = 0;
function timer(){
  i++;
  if(i === 1){
    time();
  }
}

var numr = 0;
function countClick(){
  numr ++;
  console.log(numr);
}

/*Timer*/

function time(){
 
  // var target = document.getElementsById("back");
  // target.removeAttribute("onclick");
  var minutesLabel = document.getElementById("minutes");
  var secondsLabel = document.getElementById("seconds");
  var totalSeconds = 0;
  timerCtrl = setInterval(setTime, 1000);
  
  function setTime() {
    ++totalSeconds;
    secondsLabel.innerHTML = pad(totalSeconds % 60);
    minutesLabel.innerHTML = pad(parseInt(totalSeconds / 60));
  }
  
  function pad(val) {
    var valString = val + "";
    if (valString.length < 2) {
      return "0" + valString;
    } else {
      return valString;
    }
  }
}

var counterVal = 0;

function incrementClick(){
  updateDisplay(++counterVal);
}
function resetCounter(){
  counterVal = 0;
  updateDisplay(counterVal);
}
function updateDisplay(val){
  document.getElementById("counter-label").innerHTML = val;
}
* {
  margin: 0;
  box-sizing: border-box;
}

body {
  background: url('https://github.com/FoxyStoat/memory-game/blob/master/assets/img/ignasi_pattern_s.png?raw=true');
  ;
}
h1{
  font-weight: 400;
  text-shadow: 1px 1px 2px rgba(80, 80, 80, 0.6);
}

.container{
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
}

.memory-game {
  width: 640px;
  height: 640px;
  display: flex;
  flex-wrap: wrap;
  perspective: 100%;
  margin:5px;
}

.memory-card {
  width: calc(25% - 10px);
  height: calc(33.333% - 10px);
  margin:5px;
  /* position: relative; */
  /* transform: scale(1); */
  transform-style: preserve-3d;
  transition: transform .5s;
  box-shadow: 1px 1px 1px rgba(0,0,0,.3);
}

.memory-card:active {
  transform: scale(0.97);
  transition: transform .2s;
}

.memory-card.flip {
  transform: rotateY(180deg);
}

.front-face,
.back-face {
  width: 100%;
  height: 100%;
  /* padding: 1px; */
  position: absolute;
  /* border-radius: 5px; */
  /* background: #1C7CCC; */
  backface-visibility: hidden;
}

.front-face {
  transform: rotateY(180deg);
}

.score-panel {
  text-align: left;
  width: 545px;
  margin-bottom: 10px;
  color: #0d0d0e;
}

.score-panel .stars {
  margin: 0;
  padding: 0;
  display: inline-block;
  margin: 0 5px 0 0;
  color: rgb(24, 23, 23);
}

.score-panel .stars li {
  list-style: none;
  display: inline-block;
}

.score-panel .timer {
  display: inline;
  position: absolute;
  left: 56%;
}

.score-panel .restart {
  float: right;
  cursor: pointer;
}


@media only screen  and (min-device-width: 768px)
  and (max-device-width: 1024px){
     .memory-game{
      width: 860px;
      min-height: 880px;


    }
}
@media only screen
  and (min-device-width: 375px)
  and (max-device-width: 812px) {
    .memory-game{
      width: 860px;
      min-height: 880px;


    }
  }

@media only screen
  and (min-device-width: 320px)
  and (max-device-width: 568px) {
    .memory-game{
      width: 860px;
      min-height: 880px;


    }
  }
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">

<title>Memory Game</title>
<link rel = "stylesheet" href ="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<link rel="stylesheet prefetch" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.1/css/font-awesome.min.css">
<link rel="stylesheet prefetch" href="https://fonts.googleapis.com/css?family=Coda">
<!-- <link rel="stylesheet prefetch" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.1/css/font-awesome.min.css">
    <link rel="stylesheet prefetch" href="https://fonts.googgameleapis.com/css?family=Coda">
    <link rel="stylesheet prefetch" href="https://fonts.googleapis.com/css?family=Gloria+Hallelujah|Permanent+Marker" > 
    <link rel="stylesheet prefetch" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.1/css/font-awesome.min.css">
    <link rel="stylesheet prefetch" href="https://fonts.googleapis.com/css?family=Coda">-->

    <link rel="stylesheet prefetch" href="https://fonts.googleapis.com/css?family=Coda">
    <link rel="stylesheet prefetch" href="https://fonts.googleapis.com/css?family=Gloria+Hallelujah|Permanent+Marker" >

<link href="<?php echo base_url();?>resources/dist/css/style.css" rel="stylesheet">
</head>
<body>
  
<div class = "container">
  <h1>Memory Game</h1>
  <section class="score-panel">
            <!-- <ul class="stars">
                <li><i class="fa fa-star"></i></li>
                <li><i class="fa fa-star"></i></li>
                <li><i class="fa fa-star"></i></li>
            </ul> -->

            <span>Moves <span id = "counter-label">0</span></span>

            <div class="timer">
                <label id="minutes">00</label>:<label id="seconds">00</label>
            </div>

            <div class="restart">
                <button onclick="restartButton()" class="fa fa-repeat"></button>
            <!-- <div class="col text-center">
                <button button type = "button" class = "btn btn-danger">Reset</button>
            </div> -->
            </div>
        </section>
  <div class="memory-game ">
            <div class="memory-card" data-framework="aurelia">
              <img class="front-face" src="<?php echo base_url();?>/resources/dist/img/fb.png" class = "img-fluid"alt="fb" />
              <img onclick = "incrementClick();" id="back" class="back-face" src="<?php echo base_url();?>/resources/dist/img/card.png" class = "img-fluid"alt="yugioh" />
            </div>
            <div class="memory-card" data-framework="aurelia">
              <img class="front-face" src="<?php echo base_url();?>/resources/dist/img/fb.png" class = "img-fluid"alt="fb" />
              <img onclick = "incrementClick(); timer();" id = "back" class="back-face" src="<?php echo base_url();?>/resources/dist/img/card.png" class = "img-fluid"alt="yugioh" />
            </div>

            
  </div> 

</div>
  

<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src = "https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.min.js"></script>
<script src ="<?php echo base_url();?>resources/dist/js/script.js"></script>
<script src="//cdn.jsdelivr.net/npm/sweetalert2@11"></script>
</body>
</html>

Related