Project - 6

Project 6: Memory Match Game

Build a classic memory game where players flip cards and try to find matching pairs.

Your challenge: Shuffle the cards, reveal two at a time, count each move, keep matching pairs visible, and show a message when every pair is found.

✦ HTML + CSS + JS Editor
▶ Live Output

Create the cards

The cards array contains two copies of every symbol. After shuffling, create one button for each item.

Store the symbol on the button with: card.dataset.symbol = symbol;

Flip two cards

When the first card is clicked, save it in first. When another card is clicked, save it in second and increase the move counter.

Check for a match

Compare first.dataset.symbol and second.dataset.symbol.

If they match, leave them visible. If they do not match, hide them again after a short delay with setTimeout().

Detect the win

Increase matched by two whenever a pair is found.

When matched === cards.length, every card has been matched and the game is complete.

Try it: Finish the game and see how few moves you can use.

Good JavaScript habit: Use a lock variable while unmatched cards are waiting to flip back. This prevents extra clicks from interfering with the current turn.

👀 Show Full Working Solution
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Memory Match</title>

  <style>
    body {
      background: #000;
      color: #8A8A8A;
      font-family: 'Courier New', monospace;
      text-align: center;
      padding: 40px;
      margin: 0;
    }

    .grid {
      display: grid;
      grid-template-columns: repeat(4, 80px);
      gap: 10px;
      justify-content: center;
      margin: 20px auto;
    }

    .card {
      width: 80px;
      height: 80px;
      background: #111;
      color: #fff;
      border: 1px solid #8A8A8A;
      border-radius: 6px;
      font-size: 2rem;
      cursor: pointer;
    }

    .card:focus-visible {
      outline: 3px solid #fff;
      outline-offset: 3px;
    }

    #status {
      min-height: 24px;
    }
  </style>
</head>

<body>

  <h2>Memory Match Game</h2>

  <p>Moves: <span id="moves">0</span></p>

  <div id="game" class="grid"></div>

  <p id="status" aria-live="polite"></p>

  <script>
    const symbols = [
      "🍎", "🍌", "🍇", "🍒",
      "🍉", "🍍", "🥝", "🍑"
    ];

    let cards = [...symbols, ...symbols];

    let first = null;
    let second = null;
    let lock = false;
    let moves = 0;
    let matched = 0;

    cards.sort(function() {
      return Math.random() - 0.5;
    });

    const game =
      document.getElementById("game");

    const movesDisplay =
      document.getElementById("moves");

    const status =
      document.getElementById("status");

    function createBoard() {
      game.textContent = "";

      cards.forEach(function(symbol) {
        const card =
          document.createElement("button");

        card.className = "card";
        card.type = "button";
        card.dataset.symbol = symbol;
        card.textContent = "";

        card.addEventListener("click", function() {
          flipCard(card);
        });

        game.appendChild(card);
      });
    }

    function flipCard(card) {
      if (
        lock ||
        card === first ||
        card.textContent !== ""
      ) {
        return;
      }

      card.textContent =
        card.dataset.symbol;

      if (first === null) {
        first = card;
      } else {
        second = card;
        lock = true;

        moves++;
        movesDisplay.textContent = moves;

        checkMatch();
      }
    }

    function checkMatch() {
      if (
        first.dataset.symbol ===
        second.dataset.symbol
      ) {
        matched += 2;

        resetTurn();

        if (matched === cards.length) {
          status.textContent =
            "You matched every pair in " +
            moves +
            " moves!";
        }
      } else {
        setTimeout(function() {
          first.textContent = "";
          second.textContent = "";

          resetTurn();
        }, 800);
      }
    }

    function resetTurn() {
      first = null;
      second = null;
      lock = false;
    }

    createBoard();
  </script>

</body>
</html>