Add range display to guessing game

Show the full range of numbers in the guessing game, and grey out invalid choices when the user is guessing.
This commit is contained in:
gpt-engineer-app[bot] 2025-08-10 13:51:03 +00:00
parent a981f2ec87
commit 9e899131fd

View file

@ -34,6 +34,7 @@ const GuessingGame: React.FC<GuessingGameProps> = ({ showSocialShare = true }) =
const [userGuess, setUserGuess] = useState('');
const [guesses, setGuesses] = useState<number[]>([]);
const [feedback, setFeedback] = useState<string>('');
const [validNumbers, setValidNumbers] = useState<Set<number>>(new Set());
// Computer asking mode
const [possibleNumbers, setPossibleNumbers] = useState<number[]>([]);
@ -116,6 +117,44 @@ const GuessingGame: React.FC<GuessingGameProps> = ({ showSocialShare = true }) =
};
}, [possibleNumbers]);
// Calculate valid numbers based on guesses and feedback
const updateValidNumbers = useCallback((guesses: number[], secretNumber: number | null) => {
if (guesses.length === 0 || !secretNumber) {
const allNumbers = new Set(Array.from({ length: maxRange }, (_, i) => i + 1));
setValidNumbers(allNumbers);
return;
}
const valid = new Set<number>();
for (let num = 1; num <= maxRange; num++) {
let isValid = true;
for (const guess of guesses) {
if (guess === secretNumber) break; // Game would be over
if (guess < secretNumber) {
// Guess was too low, so number must be higher than guess
if (num <= guess) {
isValid = false;
break;
}
} else {
// Guess was too high, so number must be lower than guess
if (num >= guess) {
isValid = false;
break;
}
}
}
if (isValid) {
valid.add(num);
}
}
setValidNumbers(valid);
}, [maxRange]);
// Start new game
const startGame = () => {
if (gameMode === 'user-guesses') {
@ -123,6 +162,8 @@ const GuessingGame: React.FC<GuessingGameProps> = ({ showSocialShare = true }) =
setSecretNumber(secret);
setGuesses([]);
setFeedback('');
const allNumbers = new Set(Array.from({ length: maxRange }, (_, i) => i + 1));
setValidNumbers(allNumbers);
} else {
const numbers = Array.from({ length: maxRange }, (_, i) => i + 1);
setPossibleNumbers(numbers);
@ -160,9 +201,9 @@ const GuessingGame: React.FC<GuessingGameProps> = ({ showSocialShare = true }) =
setCurrentQuestion(question);
}, [computerStrategy, possibleNumbers, generateRandomQuestion, generateLinearQuestion, generateBinaryQuestion]);
// Handle user's guess
const handleGuess = () => {
const guess = parseInt(userGuess);
// Handle user's guess (both input and number click)
const handleGuess = (guessValue?: number) => {
const guess = guessValue || parseInt(userGuess);
if (isNaN(guess) || guess < 1 || guess > maxRange) {
setFeedback('Please enter a valid number within the range.');
return;
@ -174,11 +215,15 @@ const GuessingGame: React.FC<GuessingGameProps> = ({ showSocialShare = true }) =
if (guess === secretNumber) {
setGameState('won');
setFeedback(`Congratulations! You found the number in ${newGuesses.length} guesses!`);
} else if (guess < secretNumber!) {
} else {
if (guess < secretNumber!) {
setFeedback('Too low! Try a higher number.');
} else {
setFeedback('Too high! Try a lower number.');
}
// Update valid numbers based on new feedback
updateValidNumbers(newGuesses, secretNumber);
}
setUserGuess('');
};
@ -388,17 +433,46 @@ const GuessingGame: React.FC<GuessingGameProps> = ({ showSocialShare = true }) =
)}
</div>
{/* Number Grid Display */}
<div className="space-y-4">
<h4 className="font-semibold text-center">Click a number or type your guess:</h4>
<div className="grid grid-cols-8 sm:grid-cols-10 md:grid-cols-12 lg:grid-cols-16 gap-1 max-h-64 overflow-y-auto p-2 border rounded-lg">
{Array.from({ length: maxRange }, (_, i) => i + 1).map(num => {
const isValid = validNumbers.has(num);
const isGuessed = guesses.includes(num);
return (
<Button
key={num}
size="sm"
variant={isGuessed ? "default" : isValid ? "outline" : "ghost"}
className={`
h-8 p-1 text-xs
${!isValid && !isGuessed ? 'opacity-30 cursor-not-allowed text-muted-foreground' : ''}
${isGuessed ? 'bg-accent text-accent-foreground' : ''}
${isValid && !isGuessed ? 'hover:bg-accent/10' : ''}
`}
onClick={() => isValid && !isGuessed && handleGuess(num)}
disabled={!isValid || isGuessed}
>
{num}
</Button>
);
})}
</div>
</div>
<div className="flex gap-2">
<Input
type="number"
placeholder="Enter your guess"
placeholder="Or type your guess"
value={userGuess}
onChange={(e) => setUserGuess(e.target.value)}
onKeyDown={(e) => e.key === 'Enter' && handleGuess()}
min={1}
max={maxRange}
/>
<Button onClick={handleGuess} disabled={!userGuess}>
<Button onClick={() => handleGuess()} disabled={!userGuess}>
Guess
</Button>
</div>