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
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 :
- Generate a new board
- Reset the active opened tiles to empty list
- 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 :
- Add the current tile in active opened items
- 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 :
- Tiles matched : set isMatched state to true for the active opened tiles
- Tiles not matched : set isOpened state to false for the active opened tiles
- Resetting active opened tiles to empty list
- 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 :)
Top comments (0)