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