Build a Digital Pet Game - Build a Digital Pet Game

Tell us what’s happening:

Hello! I’m working on the [Insert Project Name Here] project and I’m running into an issue where clicking the “Check Your Code” button causes the tests to run infinitely. It doesn’t crash or log an “infinite loop” error, it just hangs.

I suspect the issue is coming from my useEffect that handles the idle game state (updating hunger and happiness).

Here is the code:

useEffect(() => {
if (!gameStarted) return;

const timer = setInterval(() => {
setHunger((prev) => Math.min(100

Your code so far

<!-- file: index.html -->
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Digital Pet Game</title>

    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Tektur:wght@400..900&display=swap" rel="stylesheet">

        <link rel="stylesheet" href="styles.css" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.3.1/umd/react.development.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.3.1/umd/react-dom.development.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/7.26.5/babel.min.js"></script>
    <script
      data-plugins="transform-modules-umd"
      type="text/babel"
      src="index.tsx"
    ></script>
  </head>
  <body>
    <div id="root"></div>
    <script
      data-plugins="transform-modules-umd"
      type="text/babel"
      data-presets="react"
      data-type="module"
    >
      import { PetGame } from './index.tsx';
      ReactDOM.createRoot(document.getElementById('root')).render(<PetGame />);
    </script>
  </body>
</html>

/* file: index.tsx */
const { useState, useEffect, useRef } = React;

export enum Action {
  EAT = "EAT",
  PLAY = "PLAY",
  SLEEP = "SLEEP"
}

export enum PetMood {
  HAPPY,
  EXCITED,
  CONTENT,
  SAD,
  TIRED,
  SICK,
  HUNGRY
}

const moodEmojis: Record<PetMood, string> = {
  [PetMood.HAPPY]: "😊",
  [PetMood.EXCITED]: "🤩",
  [PetMood.CONTENT]: "🙂",
  [PetMood.SAD]: "😢",
  [PetMood.TIRED]: "😴",
  [PetMood.SICK]: "🤒",
  [PetMood.HUNGRY]: "🍔"
};


export function PetGame() {

  const [petName, setPetName] = useState("");
  const [gameStarted, setGameStarted] = useState(false);

  const nameInputRef = useRef<HTMLInputElement>(null);


  const [hunger, setHunger] = useState(0);
  const [happiness, setHappiness] = useState(100);
  const [energy, setEnergy] = useState(100);

  useEffect(() => {
    if (!gameStarted) return;

    const timer = setInterval(() => {
      setHunger((prev) => Math.min(100, prev + 10));
      setHappiness((prev) => Math.max(0, prev - 10));
    }, 100);

    return () => clearInterval(timer);
  }, [gameStarted]);

  const getMood = (): PetMood => {

    if (hunger > 70) {
      return PetMood.HUNGRY;
    }
    if (energy < 30) {
      return PetMood.TIRED;
    }
    if (happiness < 30) {
      return PetMood.SAD;
    }
    if (happiness > 80 && energy > 70) {
      return PetMood.EXCITED;
    }
    if (happiness > 60) {
      return PetMood.HAPPY;
    }
    return PetMood.CONTENT;
  };

  const handleAction = (action: Action): void => {

    switch(action) {

      case Action.EAT:

        setHunger((prev) =>
          prev > 0 ? prev - 10 : prev
        );
        setEnergy((prev) =>
          prev < 100 ? prev + 10 : prev
        );
        break;
      case Action.PLAY:
        setEnergy((prev) =>
          prev > 0 ? prev - 10 : prev
        );
        setHappiness((prev) =>
          prev < 100 ? prev + 10 : prev
        );
        break;
      case Action.SLEEP:
        setHunger((prev) =>
          prev < 100 ? prev + 10 : prev
        );
        setEnergy((prev) =>
          prev < 100 ? prev + 10 : prev
        );
        break;
    }
  };


  const handleSubmit = (e: React.FormEvent<HTMLFormElement>): void => {

    e.preventDefault();
    if (!nameInputRef.current) {
      return;
    }
    const name = nameInputRef.current.value.trim();
    if (name) {
      setPetName(name);
      setGameStarted(true);
    }
  };

  return (
    <div>
      {!gameStarted ? (
        <form onSubmit={handleSubmit}>
          <label htmlFor="pet-name">
            Name your pet
          </label>
          <input
            id="pet-name"
            type="text"
            ref={nameInputRef}
          />
          <button type="submit">
            Start Game
          </button>
        </form>
      ) : (
        <div>
          <h2 className="pet-name">
            {petName}
          </h2>
          <div>
            {moodEmojis[getMood()]}
            {" "}
            {PetMood[getMood()]}
          </div>
          <div className="stat">
            <span>
              Hunger
            </span>
            <span className="stat-value">
              {hunger}
            </span>
          </div>
          <div className="stat">
            <span>
              Happiness
            </span>
            <span className="stat-value">
              {happiness}
            </span>
          </div>
          <div className="stat">
            <span>
              Energy
            </span>
            <span className="stat-value">
              {energy}
            </span>
          </div>
          <button
            id="eat-action"
            onClick={() =>
              handleAction(Action.EAT)
            }
          >
            EAT
          </button>
          <button
            id="play-action"
            onClick={() =>
              handleAction(Action.PLAY)
            }
          >
            PLAY
          </button>
          <button
            id="sleep-action"
            onClick={() =>
              handleAction(Action.SLEEP)
            }
          >
            SLEEP
          </button>
        </div>
      )}
    </div>
  );
}
/* file: styles.css */

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/149.0.0.0 Safari/537.36 OPR/133.0.0.0

Challenge Information:

Build a Digital Pet Game - Build a Digital Pet Game

GitHub Link: freeCodeCamp/curriculum/challenges/english/blocks/lab-digital-pet-game/68c362b379059c388d3874f2.md at main · freeCodeCamp/freeCodeCamp · GitHub

I’ve just run into this issue myself. It seems to be caused by the testing procedure. After waiting for three minutes, the tests finally ran on my end.

As I understand it, waiting for the tests to run for a few minutes should always work, even if it is not ideal.

I’ve taken the time to open an issue on GitHub.

Have you checked whether the required IDs and class names match the project specs exactly? The test suite can be pretty strict.