Dagger
Dagger

Reputation: 369

Checking to see if I clicked the same image twice (React)

I'm working on a Memory Game where the user cannot click the same image twice.

I have it set up so that each time you click an image, you gain a point.

I have an Images.js file that imports (and exports) all the images. I should note each image is the same 250x250 size image of a random animal.

const Images = [
  card01,
  card02,
  etc...
];

In my Card.js folder I loop through the images to display all 10 on screen.

<div className="card">
  {Images.map((img) => (
    <img
      key={img}
      src={img}
      alt={img}
      onClick={incrementScore}
    />
  ))}
</div>

For the onClick event handler I have the following code which increases my score by 1 for a max value of 10.

const [score, setScore] = useState(0);

const incrementScore = () => {
  setScore(score + 1);
    if (score >= 10) {
      setScore(0);
    }
    shuffleArray();
    console.log(score);
};

I also wasn't sure if it was the React way but I included the shuffleArray() function inside my incrementScore() function.

const shuffleArray = () => {
  Images.sort(() => Math.random() - 0.5);
};

All that code does it make it so any time I click an image, it shuffles all the images around in a random order.

What I'm trying to do

My next step is the one that's giving me the most trouble. Currently, any time I click an image I have a point added to my score. However, the point of this game is to not click the same image twice as you have to rely on memory skills to click each image once as they all shuffle around. I'm having trouble coming up with that logic. The only thing I can think of is to use an array method but I'm not trying to completely remove any images from the array. I still need all 10 images to show on screen at all times.

Upvotes: 1

Views: 379

Answers (1)

Chris
Chris

Reputation: 6631

You can do this in multiple ways. The most easy solution is to keep track of the image src that the user has clicked on in an Array.

But, I would first make sure that the Image variable is React-friendly. Currently, it does update the image order, but this is not guaranteed because it is a variable outside the React world.

// static images
const Images = [
  card01,
  card02,
  etc...
];

const shuffleArray = (input) => {
  // prevent sorting the original Array in place
  return input.slice().sort(() => Math.random() - 0.5);
};

const Component = () => {
  const [images, setImages] = useState(shuffleArray(Images));
  const [clickedImages, setClickedImages] = useState([]);
  const [score, setScore] = useState(0);

  const incrementScore = (image) => {
    if (clickedImages.includes(image)) {
      console.log(`Please don't click me again!`, image);
      return;
    }

    setScore(score + 1);

    // update clicked images
    setClickedImages(current => [...current, image]);
    
    if (score >= 10) {
      setScore(0);
      // reset clicked images
      setClickedImages([]);
    }

    setImages(shuffleArray(Images));
    console.log(score);
  };

  return (
    <div className="card">
      {images.map((img) => (
        <img
          key={img}
          src={img}
          alt={img}
          onClick={() => incrementScore(img)}
        />
      ))}
    </div>
  );
};

Upvotes: 2

Related Questions