Building Symbol matching game in React
Tags: react, html, javascript, css
Published: 2022-07-10 06:15:07

---
title: Building Symbol matching game in React
published: true
description: Hello fellow humanoids. In this post we will build a Symbol matching game in React Js 
tags: React, html, javascript, css
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/alv9hietfi5wbj6q5sgm.png
---

## What is this post about ?
Hello fellow humanoids. Today we will try to implement a basic Symbol matching game in React Js. This post won't be focused much on the styling rather on the bare minimum logic required.

Check out the app here : [Symbol Matching Game](https://symbol-matching-game.netlify.app/)

![Symbol matching game](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/npt8edmqtnd2kt3rgj95.png)

## Content
* Rules
* Start a new game
* Reset the game
* Building game logic

Lets go deep dive into each one and explore how it was implemented.

## Rules
* Select 2 tiles with same symbol for match
* If tiles are not the same then they would be hidden away 
* Once all symbols are matched then game is complete

## Start a new game
As soon as new game is started we need to create random sequences for the symbols which would be used in the game. For building this game we are considering 4 symbols and 8 tiles, i.e matching 2 tiles of same symbol. Symbols in consideration : @, #, $, %

Each tile needs to have certain params i.e state to implement the required functionalities 
```
Tile state = {
  id,
  value, 
  isOpened, 
  isMatched
}
```
For generating random sequences we use the below logic:
```
const SYMBOLS = ["@", "#", "$", "%"];
const l = [...SYMBOLS, ...SYMBOLS];
l.sort(function (a, b) {
      return 0.5 - Math.random();
});
```
here **l** is the array used to represent the board used for the game 

## Reset the game
For implementing reset functionality we need to reset the state of the game. States that needs to be reset are :

1. Generate a new board
2. Reset the active opened tiles to empty list
3. Reset the count to 0

## Building game logic
### Match when 2 tiles are same and Reset tiles when 2 tiles are different 
We would calculate matching tiles as soon as the 2nd tile is opened. If the tiles opened are the same then it’s a match else we would close the opened tiles. 
#### Event : on tile click
```
const onBoardItemClick = (id) => {
    setActiveOpeningItems((openedItems) => [...openedItems, id]);
    setBoard((b) =>
      b.map((_i) => {
        if (_i.id === id) {
          return {
            ..._i,
            isOpened: true,
          };
        }
        return _i;
      })
    );
  };
```
Actions performed :
1. Add the current tile in active opened items
2. set isOpened state as **true** for the clicked tile

#### Event : Matching logic 
```
useEffect(() => {
    if (activeOpenedItems.length === 2) { // trigger matching logic when there are 2 active opened tiles
      const fn = () => {
        const item1 = board.find(({ id }) => id === activeOpenedItems[0]);
        const item2 = board.find(({ id }) => id === activeOpenedItems[1]);
        const isMatch = item1.value === item2.value;
        if (isMatch) {
          setBoard((board) =>
            board.map((item) => {
              if (item.id === item1.id || item.id === item2.id) {
                return {
                  ...item,
                  isMatched: true,
                };
              }
              return item;
            })
          );
        } else {
          setBoard((board) =>
            board.map((item) => {
              if (item.id === item1.id || item.id === item2.id) {
                return {
                  ...item,
                  isOpened: false,
                };
              }
              return item;
            })
          );
        }
        setActiveOpeningItems([]); // Reset active opened after matching operations are completed
      };
      setTimeout(fn, 1500); // To provide a delay is selection for user experience 
    }
  }, [activeOpenedItems, board]);
```
Actions performed :
1. Tiles matched : set **isMatched** state to **true** for the active opened tiles
2. Tiles not matched : set **isOpened** state to **false** for the active opened tiles 
3. Resetting active opened tiles to empty list
4. Executing matching code in setTimeout to provide a delay for user experience of the game

## Count the number of steps taken
To implement this feature we just increment the count on every title click
```
onBoardClick={() => {
                onBoardItemClick(b.id);
                setClicks((c) => c + 1); // Increment count on click
 }}
```

## Finish game when all tiles are matched
To check if the game is finished we need to calculate if all the tiles in the board are matched.

```
const finished =
    board.length > 0 &&
    board.filter((b) => b.isMatched).length === board.length;
```

## Conclusion
Implementing this game will allow you to learn about using state and side effects in React to implement the desired logic. This app was made as part of learning new components which are used in real life applications. 
Stay safe and lend a hand to another :) 

* [Symbol matching game](https://symbol-matching-game.netlify.app/)
* [Project Source](https://github.com/vigneshiyergithub/symbol-match-game)
* [Vignesh Iyer](https://vigneshiyer.netlify.app/)