I’m building a number puzzle game with React hooks.
The idea is pretty simple. When you click next to box number 16 I want to switch the current box been clicked with the current empty box index (box 16).
Note: (I haven’t added the css or logic to hide the “empty” box).
- I've been adding functions that add properties to each of the value in the initial array:
0: {column: 0, row: 0, box: 1}
- I've also added logic that checks if the box that is been clicked is next to box number 16 (see distanceBetween in codeSandbox example below).
Question
- I want to completely switch the properties (row, column, number...) of box number 16 (empty box) and box that is been clicked.
I made a codeSandbox link to show what it would look like: CodeSandbox
GameWrapper.js
import React, { useEffect, useState } from "react";
import { shuffleArray, addBoxProperties, distanceBetween } from "../lib/utils";
import Box from "./Box";
import WrapperDiv from "../elements/WrapperDiv";
const boxesArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
export const shuffledArray = shuffleArray(boxesArray);
const GameWrapper = () => {
const [boxes, setBoxes] = useState([]);
useEffect(() => {
setBoxes(generateBox(shuffledArray));
}, []);
const generateBox = (boxArr) => {
const tempBox = [];
boxArr.forEach((box, index) => {
tempBox[index] = {
...addBoxProperties(index),
box,
};
});
return tempBox;
};
const boxClick = (box) => {
const emptyBox = boxes.find((empty) => empty.box === 16);
const emptyBoxIndex = boxes.indexOf(emptyBox);
const boxIndex = boxes.findIndex((index) => index.box === box.box);
const distance = distanceBetween(box, emptyBox);
if (distance.neighbours) {
swap(boxIndex, emptyBoxIndex);
}
};
const swap = (clickedBoxIndex, emptyBoxIndex) => {
let tempArr = [...boxes];
tempArr[emptyBoxIndex] = boxes[clickedBoxIndex];
tempArr[clickedBoxIndex] = 0;
setBoxes(() => [...tempArr]);
};
console.log("boxes", boxes);
return (
<>
<WrapperDiv>
{boxes.map((box, index) => {
return <Box {...box} onClick={boxClick} key={index} />;
})}
</WrapperDiv>
</>
);
};
export default GameWrapper;
Please ask if i need to clarify anything further or if you think that I've approaching this the right way!
Thanks beforehand, Erik