Memory Game, A JavaScript Mini Project : Bipin Khambu Shrestha

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Memory Game</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body>
  <div class="memory-game" id="memory-game"></div>
  
  <script src="script.js"></script>
</body>
</html>

styles.css

.memory-game {
    display: flex;
    flex-wrap: wrap;
    width: 400px;
    height: 400px;
    margin: 20px auto;
    perspective: 1000px;
  }
  
  .card {
    width: calc(25% - 10px);
    height: calc(25% - 10px);
    margin: 5px;
    position: relative;
    transform-style: preserve-3d;
    transition: transform 0.5s;
    cursor: pointer;
  }
  
  .card.flip {
    transform: rotateY(180deg);
  }
  
  .card-inner {
    position: absolute;
    width: 100%;
    height: 100%;
    text-align: center;
    line-height: calc(25% - 10px);
    backface-visibility: hidden;
  }
  
  .front-face,
  .back-face {
    width: 100%;
    height: 100%;
    position: absolute;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 24px;
    background-color: #f0f0f0;
    border: 1px solid #ccc;
  }

script.js

const cards = ['🍎', '🍊', '🍋', '🍉', '🍇', '🥥', '🍍', '🥝'];
let firstCard = null;
let secondCard = null;
let lockBoard = false;
let pairsMatched = 0;

const memoryGame = document.getElementById('memory-game');

function createCard(cardContent) {
  const card = document.createElement('div');
  card.classList.add('card');

  const cardInner = document.createElement('div');
  cardInner.classList.add('card-inner');

  const frontFace = document.createElement('div');
  frontFace.classList.add('front-face');
  frontFace.innerText = '';

  const backFace = document.createElement('div');
  backFace.classList.add('back-face');
  backFace.innerText = cardContent;

  cardInner.appendChild(frontFace);
  cardInner.appendChild(backFace);
  card.appendChild(cardInner);

  card.addEventListener('click', flipCard);

  return card;
}

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

  this.classList.add('flip');

  if (!firstCard) {
    firstCard = this;
    return;
  }

  secondCard = this;

  checkForMatch();
}

function checkForMatch() {
  const isMatch = firstCard.querySelector('.back-face').innerText === secondCard.querySelector('.back-face').innerText;

  isMatch ? disableCards() : unflipCards();
}

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

  resetBoard();

  pairsMatched++;
  if (pairsMatched === cards.length) {
    setTimeout(() => alert('Congratulations! You won!'), 500);
  }
}

function unflipCards() {
  lockBoard = true;

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

    resetBoard();
  }, 1000);
}

function resetBoard() {
  [firstCard, secondCard] = [null, null];
  lockBoard = false;
}

function initializeGame() {
  const shuffledCards = [...cards, ...cards].sort(() => Math.random() - 0.5);
  shuffledCards.forEach(cardContent => {
    const card = createCard(cardContent);
    memoryGame.appendChild(card);
  });
}

initializeGame();