Shuffle the Cards
Learn to use the spread and random methods to shuffle the cards.
In the shuffleCard
function, we shuffle our CardImages
in a random order and use the button in the Header
component to create a new game any time a user clicks it. To define the shuffleCard
function, we use CardImages
, which is a collection of flags from various countries that have already been passed for us to use in the App.js
component. We use the spread operator two times to create the array of image pairs. This is because we need to select two similar images. We use JavaScript’s Math.random()
method because we want the images to be placed in random order.
Define the shuffleCard
function
Let’s start by importing the useState
and useEffect
hooks to handle our state of shuffled-card order and turns
, which is the number of turns the user took to guess the correct pair of images. The useEffect
hook calls the shuffleCard
function on each render of the component. The following snippet shows how to define the function:
const [cards, setCards] = useState([]);
const [turns, setTurns] = useState(0);
const shuffleCard = () => {
const shuffledCards = [...cardImages, ...cardImages]
.sort(() => Math.random() - 0.5)
.map((card) => ({ ...card, id: Math.random() }));
setCards(shuffledCards);
setTurns(0);
};
We create the shuffleCards
variable in the snippet above, which holds an array of images that we randomly sort
using the Math.random()
function. which generates negative and positive values at random. The sort
method takes the array of images, compares all of the images with each other to see if they are a pair, and then either swaps the two or leaves them as is. To determine whether the cards should be swapped, we pass the Math.random()
function as an argument to the sort
method. If the Math.random()
function returns a negative value, the two images being compared are swapped. If no two images in the array are swapped, the array will remain in its original form.
To get a random permutation of the image array, we want some values to be swapped—specifically, for this application, we want to swap the images 50 percent of the time. So, we need the value returned by the Math.random()
argument to sort
to be positive 50% of the time, and negative 50% of the time. Because Math.random()
returns a random value between 0 and 1, subtracting 0.5 from the value means that the random result Math.random()
returns will always be between -0.5 and 0.5. This gives us a 50% probability of the value being positive, and a 50% probability of it being negative—which is our goal to randomly sort our cards. We then map over the randomly sorted array and return the object with the card
variable that we defined in the Export Images lesson. It holds the src
and matched
properties. At the end, we use the setCards
state updating function to update the array with the 12 random images and set the value of turns
to 0
on every new game by using setTurns
.
Use the useEffect
hook
Because we want the card to reshuffle on the game’s first render, we use the useEffect
method to execute our shuffleCard
function on the first render.
// Call the shuffle card function
useEffect(() => {
shuffleCard();
}, []);
Get hands-on with 1400+ tech skills courses.