DEV Community

Cover image for Build a Memory Game using React.Js and JavaScript
Krushna Chandra Dash
Krushna Chandra Dash

Posted on

Build a Memory Game using React.Js and JavaScript

What is Memory Card Game

Memory Game, also known as the Concentration card game or Matching Game, is a simple card game where you need to match pairs by turning over 2 cards at a time.

In this Article we are going to create a game of grid size 3 x 4 .
CodeSandbox DEMO
CodeSandbox Code Example

Step-1

Create A react js project.

npx create-next-app
Enter fullscreen mode Exit fullscreen mode

Step-2

We need some data and image to show in the game.

create a **app.mock.js** file and store the above data.

const MOCK = [
  {
    id: 1,
    name: "Ace",
    pic: 'https://upload.wikimedia.org/wikipedia/commons/thumb/a/ab/01_of_spades_A.svg/800px-01_of_spades_A.svg.png',
    isOpen: false
  },
  {
    id: 2,
    name: "Two",
    pic: 'https://upload.wikimedia.org/wikipedia/commons/thumb/4/40/02_of_spades.svg/800px-02_of_spades.svg.png',
    isOpen: false
  },
  {
    id: 3,
    name: "Three",
    pic: 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/62/03_of_spades.svg/800px-03_of_spades.svg.png',
    isOpen: false
  },
  {
    id: 4,
    name: "Four",
    pic: 'https://upload.wikimedia.org/wikipedia/commons/7/7a/04_of_spades.svg',
    isOpen: false
  },
  {
    id: 5,
    name: "Five",
    pic: 'https://upload.wikimedia.org/wikipedia/commons/thumb/1/16/05_of_spades.svg/800px-05_of_spades.svg.png',
    isOpen: false
  },
  {
    id: 6,
    name: "Six",
    pic: 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6e/06_of_spades.svg/800px-06_of_spades.svg.png',
    isOpen: false
  },
  {
    id: 7,
    name: "Ace",
    pic: 'https://upload.wikimedia.org/wikipedia/commons/thumb/a/ab/01_of_spades_A.svg/800px-01_of_spades_A.svg.png',
    isOpen: false
  },
  {
    id: 8,
    name: "Two",
    pic: 'https://upload.wikimedia.org/wikipedia/commons/thumb/4/40/02_of_spades.svg/800px-02_of_spades.svg.png',
    isOpen: false
  },
  {
    id: 9,
    name: "Three",
    pic: 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/62/03_of_spades.svg/800px-03_of_spades.svg.png',
    isOpen: false
  },
  {
    id: 10,
    name: "Four",
    pic: 'https://upload.wikimedia.org/wikipedia/commons/thumb/7/7a/04_of_spades.svg/800px-04_of_spades.svg.png',
    isOpen: false
  },
  {
    id: 11,
    name: "Five",
    pic: 'https://upload.wikimedia.org/wikipedia/commons/thumb/1/16/05_of_spades.svg/800px-05_of_spades.svg.png',
    isOpen: false
  },
  {
    id: 12,
    name: "Six",
    pic: 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6e/06_of_spades.svg/800px-06_of_spades.svg.png',
    isOpen: false
  }
];
export default MOCK;

Enter fullscreen mode Exit fullscreen mode

Step-3

Then lets create a component name of Board.js.
and the code with logic whick will look like below

import React, { useEffect, useState } from "react";
import Data from "../app.mock";

const Board = () => {
  const [cards, setCards] = useState(Data || []);
  const [firstCard, setFirstCard] = useState();
  const [secondCard, setSecondCard] = useState();

  const setCard = (card) => {
    setCards(
      cards.map((data) =>
        data.id === card.id ? { ...data, isOpen: !card.isOpen } : data
      )
    );
  };

  const handleClick = (card) => {
    if (card.isOpen) {
      return;
    }
    if (!firstCard) {
      setFirstCard(card);
      setCard(card);
    } else if (!secondCard) {
      setSecondCard(card);
      setCard(card);
    }
  };
  useEffect(() => {
    let timeOut;
    if (firstCard?.name !== secondCard?.name) {
      timeOut = setTimeout(() => {
        setCards(
          cards.map((data) =>
            firstCard?.id === data.id || secondCard?.id === data.id
              ? { ...data, isOpen: !data.isOpen }
              : data
          )
        );
        setFirstCard();
        setSecondCard();
      }, 1000);
    } else {
      setFirstCard();
      setSecondCard();
    }
    return () => {
      clearTimeout(timeOut);
    };
  }, [secondCard]);

  return (
    <div className="board ">
      {cards &&
        Array.isArray(cards) &&
        cards.length > 0 &&
        cards.map((card, index) => {
          return (
            <div
              className={`singleCard ${card.isOpen ? "fliped" : "show"}`}
              key={index}
              onClick={() => handleClick(card)}
            >
              {card.isOpen ? (
                <img src={card.pic} className="font_face" alt="img" />
              ) : (
                <img
                  src="https://upload.wikimedia.org/wikipedia/commons/thumb/2/23/The_Jolly_Nero.jpg/800px-The_Jolly_Nero.jpg"
                  className="back_face"
                  alt="img"
                />
              )}
            </div>
          );
        })}
    </div>
  );
};
export default Board;

Enter fullscreen mode Exit fullscreen mode

Step-4

Import Board component to App.js file

import Board from "./components/Board";
import "./styles.css";

export default function App() {
  return (
    <div className="App">
      <Board />
    </div>
  );
}

Enter fullscreen mode Exit fullscreen mode

Step-5

Add css for look and fill in style.css

* {
  padding: 0px;
  margin: 0px;
  box-sizing: border-box;
}
.App {
  font-family: sans-serif;
  display: flex;
  align-self: center;
  text-align: center;
  justify-content: center;
  height: 100vh;
  background-color: azure;
}
.board {
  display: flex;
  align-self: center;
  justify-content: center;
  flex-wrap: wrap;
  justify-content: flex-start;
  margin: 0 -10px;
  max-width: 500px;
  perspective: 1000px;
}
.singleCard {
  width: 100px;
  height: 120px;
  display: flex;
  margin: 10px;
  /* border: 1px solid gray; */
  border-radius: 5px;
  overflow: hidden;
  justify-content: center;
  cursor: pointer;
  /* padding: 4px; */
  /* background-color: #ffff; */
  transition: all 0.5s;
  transform-style: preserve-3d;
  transform: scale(1);
}
.fliped {
  transform: rotateY(180deg);
}
.font_face {
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.back_face {
  width: 100%;
  height: 100%;
  object-fit: contain;
  border: 1px solid black;
}

Enter fullscreen mode Exit fullscreen mode

Folder Structure

Finally our folder structure will look like this

Image description

The End

memory card game

That's all we are ready to play the game..

SurveyJS custom survey software

Simplify data collection in your JS app with a fully integrated form management platform. Includes support for custom question types, skip logic, integrated CCS editor, PDF export, real-time analytics & more. Integrates with any backend system, giving you full control over your data and no user limits.

Learn more

Top comments (0)

SurveyJS custom survey software

JavaScript Form Builder UI Component

Generate dynamic JSON-driven forms directly in your JavaScript app (Angular, React, Vue.js, jQuery) with a fully customizable drag-and-drop form builder. Easily integrate with any backend system and retain full ownership over your data, with no user or form submission limits.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay