Build a Digital Pet Game - Build a Digital Pet Game

Tell us what’s happening:

The test seems to get stuck, running infinitely.

It works when I comment out:

const timer = setInterval(() => {
      setHunger((h) => clamp(h + 1));
      setEnergy((e) => clamp(e + 1));
      setHappiness((h) => clamp(h - 1));
    }, 100);

    return () => clearInterval(timer);

But then tests 6, 24, and 26 fail.

Your code so far

<!-- file: index.html -->

const { useEffect, useMemo, useState } = React;

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

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

export const petMoodEmoji: Record<PetMood, string> = {
  [PetMood.HAPPY]: "😊",
  [PetMood.EXCITED]: "🤩",
  [PetMood.CONTENT]: "😌",
  [PetMood.SAD]: "😢",
  [PetMood.TIRED]: "😴",
  [PetMood.SICK]: "🤒",
  [PetMood.HUNGRY]: "🍽️",
};
export const petMoodText: Record<PetMood, string> = {
  [PetMood.HAPPY]: "Happy",
  [PetMood.EXCITED]: "Excited",
  [PetMood.CONTENT]: "Content",
  [PetMood.SAD]: "Sad",
  [PetMood.TIRED]: "Tired",
  [PetMood.SICK]: "Sick",
  [PetMood.HUNGRY]: "Hungry",
};

const clamp = (value: number) => Math.min(100, Math.max(0, value));

export const PetGame = () => {
  const [started, setStarted] = useState(false);
  const [nameInput, setNameInput] = useState("");
  const [petName, setPetName] = useState("");

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

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

    const timer = setInterval(() => {
      setHunger((h) => clamp(h + 1));
      setEnergy((e) => clamp(e + 1));
      setHappiness((h) => clamp(h - 1));
    }, 100);

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

  const mood = useMemo(() => {
    if (hunger > 95 && happiness < 10) return PetMood.SICK;

    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;
  }, [hunger, energy, happiness]);

  const doAction = (action: Action) => {
    switch (action) {
      case Action.EAT:
        setHunger((v) => clamp(v - 10));
        setEnergy((v) => clamp(v + 10));
        break;

      case Action.PLAY:
        setEnergy((v) => clamp(v - 10));
        setHappiness((v) => clamp(v + 10));
        break;

      case Action.SLEEP:
        setHunger((v) => clamp(v + 10));
        setEnergy((v) => clamp(v + 10));
        break;
    }
  };

  if (!started) {
    return (
      <div className="base-container">
        <form
          onSubmit={(e) => {
            e.preventDefault();
            setPetName(nameInput);
            setStarted(true);
          }}
        >
          <label htmlFor="pet-name">Name your pet</label>
          <br />
          <input
            id="pet-name"
            value={nameInput}
            onChange={(e) => setNameInput(e.target.value)}
          />
          <br />
          <button type="submit">Start Game</button>
        </form>
      </div>
    );
  }

  return (
    <div className="base-container">
      <div className="game-container">
        <h2 className="pet-name">{petName}</h2>

        <div className="pet-sprite">
          {petMoodEmoji[mood]}
          <div>{petMoodText[mood]}</div>
        </div>

        <div className="stats-grid">
          <div className="stat">
            Hunger
            <div className="stat-value">{hunger}</div>
          </div>

          <div className="stat">
            Energy
            <div className="stat-value">{energy}</div>
          </div>

          <div className="stat">
            Happiness
            <div className="stat-value">{happiness}</div>
          </div>
        </div>

        <div className="pet-buttons">
          <button
            id="eat-action"
            className="pet-button"
            onClick={() => doAction(Action.EAT)}
          >
            EAT
          </button>

          <button
            id="play-action"
            className="pet-button"
            onClick={() => doAction(Action.PLAY)}
          >
            PLAY
          </button>

          <button
            id="sleep-action"
            className="pet-button"
            onClick={() => doAction(Action.SLEEP)}
          >
            SLEEP
          </button>
        </div>
      </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/150.0.0.0 Safari/537.36

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