Add Guessing Game
Implement a guessing game with user-selectable range via slider. Includes two modes: user guesses computer's number, and computer guesses user's number using random, linear, or binary search strategies.
This commit is contained in:
parent
aaa3b7f06f
commit
a981f2ec87
4 changed files with 559 additions and 0 deletions
|
|
@ -36,6 +36,7 @@ import PlateSwapPuzzlePage from "./pages/PlateSwapPuzzlePage";
|
|||
import ChessboardRepaintPuzzlePage from "./pages/ChessboardRepaintPuzzlePage";
|
||||
import ZeckendorfGamePage from "./pages/ZeckendorfGamePage";
|
||||
import ZeckendorfSearchTrickPage from "./pages/ZeckendorfSearchTrickPage";
|
||||
import GuessingGamePage from "./pages/GuessingGamePage";
|
||||
import Foundations from "./pages/theme-pages/discrete-math/Foundations";
|
||||
import Proofs from "./pages/theme-pages/discrete-math/Proofs";
|
||||
import Counting from "./pages/theme-pages/discrete-math/Counting";
|
||||
|
|
@ -106,6 +107,7 @@ const App = () => (
|
|||
<Route path="/puzzles/n-queens" element={<NQueensPuzzlePage />} />
|
||||
<Route path="/discrete-math/foundations/zeckendorf" element={<ZeckendorfGamePage />} />
|
||||
<Route path="/discrete-math/foundations/zeckendorf-search" element={<ZeckendorfSearchTrickPage />} />
|
||||
<Route path="/guessing-game" element={<GuessingGamePage />} />
|
||||
|
||||
{/* ADD ALL CUSTOM ROUTES ABOVE THE CATCH-ALL "*" ROUTE */}
|
||||
<Route path="*" element={<NotFound />} />
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import NorthcottsGame from '@/components/NorthcottsGame';
|
|||
import NimGame from '@/components/NimGame';
|
||||
import AssistedNimGame from '@/components/AssistedNimGame';
|
||||
import GoldCoinGame from '@/components/GoldCoinGame';
|
||||
import GuessingGame from '@/components/GuessingGame';
|
||||
|
||||
interface Game {
|
||||
id: string;
|
||||
|
|
@ -19,6 +20,13 @@ interface Game {
|
|||
}
|
||||
|
||||
const games: Game[] = [
|
||||
{
|
||||
id: 'guessing-game',
|
||||
title: 'Number Guessing Game',
|
||||
description: 'Experience different search algorithms through interactive gameplay. Compare random, linear, and binary search strategies!',
|
||||
tags: ['algorithms', 'search', 'educational', 'interactive', 'binary-search', 'computer-science'],
|
||||
component: GuessingGame
|
||||
},
|
||||
{
|
||||
id: 'gold-coin',
|
||||
title: 'The Gold Coin Game',
|
||||
|
|
|
|||
536
src/components/GuessingGame.tsx
Normal file
536
src/components/GuessingGame.tsx
Normal file
|
|
@ -0,0 +1,536 @@
|
|||
import React, { useState, useEffect, useCallback } from 'react';
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Slider } from '@/components/ui/slider';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { Switch } from '@/components/ui/switch';
|
||||
import { Label } from '@/components/ui/label';
|
||||
import { Brain, User, Trophy, Target, HelpCircle, CheckCircle, XCircle } from 'lucide-react';
|
||||
import SocialShare from '@/components/SocialShare';
|
||||
|
||||
interface GuessingGameProps {
|
||||
showSocialShare?: boolean;
|
||||
}
|
||||
|
||||
type GameMode = 'user-guesses' | 'computer-asks';
|
||||
type ComputerStrategy = 'random' | 'linear' | 'binary';
|
||||
type GameState = 'setup' | 'playing' | 'won' | 'lost';
|
||||
|
||||
interface Question {
|
||||
text: string;
|
||||
isCorrect: (num: number) => boolean;
|
||||
}
|
||||
|
||||
const GuessingGame: React.FC<GuessingGameProps> = ({ showSocialShare = true }) => {
|
||||
// Game settings
|
||||
const [range, setRange] = useState([50]);
|
||||
const [gameMode, setGameMode] = useState<GameMode>('user-guesses');
|
||||
const [computerStrategy, setComputerStrategy] = useState<ComputerStrategy>('binary');
|
||||
|
||||
// Game state
|
||||
const [gameState, setGameState] = useState<GameState>('setup');
|
||||
const [secretNumber, setSecretNumber] = useState<number | null>(null);
|
||||
const [userGuess, setUserGuess] = useState('');
|
||||
const [guesses, setGuesses] = useState<number[]>([]);
|
||||
const [feedback, setFeedback] = useState<string>('');
|
||||
|
||||
// Computer asking mode
|
||||
const [possibleNumbers, setPossibleNumbers] = useState<number[]>([]);
|
||||
const [currentQuestion, setCurrentQuestion] = useState<Question | null>(null);
|
||||
const [questionsAsked, setQuestionsAsked] = useState<string[]>([]);
|
||||
const [userScore, setUserScore] = useState(0);
|
||||
const [currentSearchIndex, setCurrentSearchIndex] = useState(0);
|
||||
|
||||
const maxRange = range[0];
|
||||
|
||||
// Prime checker utility
|
||||
const isPrime = (num: number): boolean => {
|
||||
if (num < 2) return false;
|
||||
for (let i = 2; i <= Math.sqrt(num); i++) {
|
||||
if (num % i === 0) return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
// Random question generator
|
||||
const generateRandomQuestion = useCallback((): Question => {
|
||||
const questions = [
|
||||
{
|
||||
text: "Is your number prime?",
|
||||
isCorrect: (num: number) => isPrime(num)
|
||||
},
|
||||
{
|
||||
text: "Is your number even?",
|
||||
isCorrect: (num: number) => num % 2 === 0
|
||||
},
|
||||
{
|
||||
text: "Is your number divisible by 3?",
|
||||
isCorrect: (num: number) => num % 3 === 0
|
||||
},
|
||||
{
|
||||
text: "Is your number divisible by 5?",
|
||||
isCorrect: (num: number) => num % 5 === 0
|
||||
},
|
||||
{
|
||||
text: "Is your number a perfect square?",
|
||||
isCorrect: (num: number) => Math.sqrt(num) % 1 === 0
|
||||
},
|
||||
{
|
||||
text: "Is your number greater than half the maximum range?",
|
||||
isCorrect: (num: number) => num > maxRange / 2
|
||||
},
|
||||
{
|
||||
text: "Does your number contain the digit 5?",
|
||||
isCorrect: (num: number) => num.toString().includes('5')
|
||||
}
|
||||
];
|
||||
|
||||
return questions[Math.floor(Math.random() * questions.length)];
|
||||
}, [maxRange]);
|
||||
|
||||
// Linear search question generator
|
||||
const generateLinearQuestion = useCallback((): Question => {
|
||||
const currentNum = currentSearchIndex + 1;
|
||||
return {
|
||||
text: `Is your number ${currentNum}?`,
|
||||
isCorrect: (num: number) => num === currentNum
|
||||
};
|
||||
}, [currentSearchIndex]);
|
||||
|
||||
// Binary search question generator
|
||||
const generateBinaryQuestion = useCallback((): Question => {
|
||||
if (possibleNumbers.length <= 1) {
|
||||
return {
|
||||
text: `Is your number ${possibleNumbers[0]}?`,
|
||||
isCorrect: (num: number) => num === possibleNumbers[0]
|
||||
};
|
||||
}
|
||||
|
||||
const midIndex = Math.floor(possibleNumbers.length / 2);
|
||||
const midValue = possibleNumbers[midIndex];
|
||||
|
||||
return {
|
||||
text: `Is your number ${midValue} or less?`,
|
||||
isCorrect: (num: number) => num <= midValue
|
||||
};
|
||||
}, [possibleNumbers]);
|
||||
|
||||
// Start new game
|
||||
const startGame = () => {
|
||||
if (gameMode === 'user-guesses') {
|
||||
const secret = Math.floor(Math.random() * maxRange) + 1;
|
||||
setSecretNumber(secret);
|
||||
setGuesses([]);
|
||||
setFeedback('');
|
||||
} else {
|
||||
const numbers = Array.from({ length: maxRange }, (_, i) => i + 1);
|
||||
setPossibleNumbers(numbers);
|
||||
setQuestionsAsked([]);
|
||||
setUserScore(0);
|
||||
setCurrentSearchIndex(0);
|
||||
setSecretNumber(null);
|
||||
}
|
||||
|
||||
setGameState('playing');
|
||||
setUserGuess('');
|
||||
};
|
||||
|
||||
// Generate next question for computer
|
||||
const generateNextQuestion = useCallback(() => {
|
||||
if (possibleNumbers.length <= 1) {
|
||||
setGameState('won');
|
||||
return;
|
||||
}
|
||||
|
||||
let question: Question;
|
||||
|
||||
switch (computerStrategy) {
|
||||
case 'random':
|
||||
question = generateRandomQuestion();
|
||||
break;
|
||||
case 'linear':
|
||||
question = generateLinearQuestion();
|
||||
break;
|
||||
case 'binary':
|
||||
question = generateBinaryQuestion();
|
||||
break;
|
||||
}
|
||||
|
||||
setCurrentQuestion(question);
|
||||
}, [computerStrategy, possibleNumbers, generateRandomQuestion, generateLinearQuestion, generateBinaryQuestion]);
|
||||
|
||||
// Handle user's guess
|
||||
const handleGuess = () => {
|
||||
const guess = parseInt(userGuess);
|
||||
if (isNaN(guess) || guess < 1 || guess > maxRange) {
|
||||
setFeedback('Please enter a valid number within the range.');
|
||||
return;
|
||||
}
|
||||
|
||||
const newGuesses = [...guesses, guess];
|
||||
setGuesses(newGuesses);
|
||||
|
||||
if (guess === secretNumber) {
|
||||
setGameState('won');
|
||||
setFeedback(`Congratulations! You found the number in ${newGuesses.length} guesses!`);
|
||||
} else if (guess < secretNumber!) {
|
||||
setFeedback('Too low! Try a higher number.');
|
||||
} else {
|
||||
setFeedback('Too high! Try a lower number.');
|
||||
}
|
||||
|
||||
setUserGuess('');
|
||||
};
|
||||
|
||||
// Handle computer's question answer
|
||||
const handleQuestionAnswer = (answer: boolean) => {
|
||||
if (!currentQuestion) return;
|
||||
|
||||
const questionText = `${currentQuestion.text} → ${answer ? 'Yes' : 'No'}`;
|
||||
setQuestionsAsked([...questionsAsked, questionText]);
|
||||
setUserScore(userScore + 1);
|
||||
|
||||
let newPossibleNumbers = [...possibleNumbers];
|
||||
|
||||
if (computerStrategy === 'random') {
|
||||
// Filter based on the answer to the random question
|
||||
newPossibleNumbers = possibleNumbers.filter(num =>
|
||||
currentQuestion.isCorrect(num) === answer
|
||||
);
|
||||
} else if (computerStrategy === 'linear') {
|
||||
if (answer) {
|
||||
// Found the number
|
||||
setGameState('won');
|
||||
return;
|
||||
} else {
|
||||
// Move to next number in linear search
|
||||
setCurrentSearchIndex(currentSearchIndex + 1);
|
||||
newPossibleNumbers = possibleNumbers.filter(num => num > currentSearchIndex + 1);
|
||||
}
|
||||
} else if (computerStrategy === 'binary') {
|
||||
const midIndex = Math.floor(possibleNumbers.length / 2);
|
||||
const midValue = possibleNumbers[midIndex];
|
||||
|
||||
if (possibleNumbers.length === 1) {
|
||||
setGameState('won');
|
||||
return;
|
||||
}
|
||||
|
||||
if (answer) {
|
||||
// Number is <= midValue
|
||||
newPossibleNumbers = possibleNumbers.slice(0, midIndex + 1);
|
||||
} else {
|
||||
// Number is > midValue
|
||||
newPossibleNumbers = possibleNumbers.slice(midIndex + 1);
|
||||
}
|
||||
}
|
||||
|
||||
setPossibleNumbers(newPossibleNumbers);
|
||||
};
|
||||
|
||||
// Generate question when computer is asking
|
||||
useEffect(() => {
|
||||
if (gameState === 'playing' && gameMode === 'computer-asks') {
|
||||
generateNextQuestion();
|
||||
}
|
||||
}, [gameState, gameMode, possibleNumbers, generateNextQuestion]);
|
||||
|
||||
const resetGame = () => {
|
||||
setGameState('setup');
|
||||
setSecretNumber(null);
|
||||
setUserGuess('');
|
||||
setGuesses([]);
|
||||
setFeedback('');
|
||||
setPossibleNumbers([]);
|
||||
setCurrentQuestion(null);
|
||||
setQuestionsAsked([]);
|
||||
setUserScore(0);
|
||||
setCurrentSearchIndex(0);
|
||||
};
|
||||
|
||||
const getStrategyDescription = (strategy: ComputerStrategy) => {
|
||||
switch (strategy) {
|
||||
case 'random':
|
||||
return 'Asks random mathematical questions about your number';
|
||||
case 'linear':
|
||||
return 'Checks each number sequentially from 1 upward';
|
||||
case 'binary':
|
||||
return 'Uses binary search to efficiently narrow down the range';
|
||||
}
|
||||
};
|
||||
|
||||
const getOptimalGuesses = () => {
|
||||
return Math.ceil(Math.log2(maxRange));
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<Card>
|
||||
<CardHeader className="text-center">
|
||||
<CardTitle className="text-3xl font-bold flex items-center justify-center gap-2">
|
||||
<Target className="w-8 h-8 text-accent" />
|
||||
Number Guessing Game
|
||||
</CardTitle>
|
||||
<CardDescription className="text-lg">
|
||||
Experience different search strategies in this interactive guessing game
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
|
||||
<CardContent className="space-y-6">
|
||||
{gameState === 'setup' && (
|
||||
<div className="space-y-6">
|
||||
{/* Range Selection */}
|
||||
<div className="space-y-4">
|
||||
<Label className="text-lg font-semibold">Number Range: 1 to {maxRange}</Label>
|
||||
<div className="space-y-2">
|
||||
<Slider
|
||||
value={range}
|
||||
onValueChange={setRange}
|
||||
min={10}
|
||||
max={512}
|
||||
step={1}
|
||||
className="w-full"
|
||||
/>
|
||||
<div className="flex justify-between text-sm text-muted-foreground">
|
||||
<span>Min: 10</span>
|
||||
<span>Current: {maxRange}</span>
|
||||
<span>Max: 512</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Game Mode Selection */}
|
||||
<div className="space-y-4">
|
||||
<Label className="text-lg font-semibold">Game Mode</Label>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<Card
|
||||
className={`cursor-pointer transition-all ${gameMode === 'user-guesses' ? 'ring-2 ring-accent' : ''}`}
|
||||
onClick={() => setGameMode('user-guesses')}
|
||||
>
|
||||
<CardContent className="p-4 text-center space-y-2">
|
||||
<User className="w-8 h-8 text-accent mx-auto" />
|
||||
<h3 className="font-semibold">You Guess</h3>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Computer thinks of a number, you try to guess it
|
||||
</p>
|
||||
<Badge variant="secondary" className="text-xs">
|
||||
Optimal: {getOptimalGuesses()} guesses
|
||||
</Badge>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card
|
||||
className={`cursor-pointer transition-all ${gameMode === 'computer-asks' ? 'ring-2 ring-accent' : ''}`}
|
||||
onClick={() => setGameMode('computer-asks')}
|
||||
>
|
||||
<CardContent className="p-4 text-center space-y-2">
|
||||
<Brain className="w-8 h-8 text-accent mx-auto" />
|
||||
<h3 className="font-semibold">Computer Asks</h3>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
You think of a number, computer asks questions
|
||||
</p>
|
||||
<Badge variant="secondary" className="text-xs">
|
||||
Earn points for each question
|
||||
</Badge>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Computer Strategy Selection */}
|
||||
{gameMode === 'computer-asks' && (
|
||||
<div className="space-y-4">
|
||||
<Label className="text-lg font-semibold">Computer Strategy</Label>
|
||||
<div className="grid grid-cols-1 gap-3">
|
||||
{(['random', 'linear', 'binary'] as ComputerStrategy[]).map(strategy => (
|
||||
<Card
|
||||
key={strategy}
|
||||
className={`cursor-pointer transition-all ${computerStrategy === strategy ? 'ring-2 ring-accent' : ''}`}
|
||||
onClick={() => setComputerStrategy(strategy)}
|
||||
>
|
||||
<CardContent className="p-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<h4 className="font-semibold capitalize">{strategy} Search</h4>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
{getStrategyDescription(strategy)}
|
||||
</p>
|
||||
</div>
|
||||
<Badge variant={computerStrategy === strategy ? "default" : "outline"}>
|
||||
{strategy === 'binary' ? `~${getOptimalGuesses()} questions` :
|
||||
strategy === 'linear' ? `~${Math.ceil(maxRange/2)} questions` :
|
||||
'? questions'}
|
||||
</Badge>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<Button onClick={startGame} className="w-full" size="lg">
|
||||
Start Game
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{gameState === 'playing' && gameMode === 'user-guesses' && (
|
||||
<div className="space-y-6">
|
||||
<div className="text-center space-y-2">
|
||||
<h3 className="text-xl font-semibold">Guess the number between 1 and {maxRange}</h3>
|
||||
<p className="text-muted-foreground">Guesses made: {guesses.length}</p>
|
||||
{feedback && (
|
||||
<div className={`p-3 rounded-lg ${feedback.includes('Congratulations') ? 'bg-success/10 text-success' : 'bg-muted'}`}>
|
||||
{feedback}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="flex gap-2">
|
||||
<Input
|
||||
type="number"
|
||||
placeholder="Enter 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}>
|
||||
Guess
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{guesses.length > 0 && (
|
||||
<div className="space-y-2">
|
||||
<h4 className="font-semibold">Previous Guesses:</h4>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{guesses.map((guess, index) => (
|
||||
<Badge key={index} variant="outline">
|
||||
{guess}
|
||||
</Badge>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<Button onClick={resetGame} variant="outline" className="w-full">
|
||||
New Game
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{gameState === 'playing' && gameMode === 'computer-asks' && (
|
||||
<div className="space-y-6">
|
||||
<div className="text-center space-y-2">
|
||||
<h3 className="text-xl font-semibold">Think of a number between 1 and {maxRange}</h3>
|
||||
<p className="text-muted-foreground">
|
||||
Strategy: {computerStrategy.charAt(0).toUpperCase() + computerStrategy.slice(1)} Search
|
||||
</p>
|
||||
<div className="flex justify-center gap-4">
|
||||
<Badge variant="outline">
|
||||
<Trophy className="w-4 h-4 mr-1" />
|
||||
Score: {userScore}
|
||||
</Badge>
|
||||
<Badge variant="outline">
|
||||
Remaining: {possibleNumbers.length}
|
||||
</Badge>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{currentQuestion && (
|
||||
<Card className="text-center">
|
||||
<CardContent className="p-6 space-y-4">
|
||||
<HelpCircle className="w-12 h-12 text-accent mx-auto" />
|
||||
<h4 className="text-lg font-semibold">{currentQuestion.text}</h4>
|
||||
<div className="flex gap-3 justify-center">
|
||||
<Button
|
||||
onClick={() => handleQuestionAnswer(true)}
|
||||
className="bg-success hover:bg-success/90"
|
||||
>
|
||||
<CheckCircle className="w-4 h-4 mr-1" />
|
||||
Yes
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => handleQuestionAnswer(false)}
|
||||
variant="destructive"
|
||||
>
|
||||
<XCircle className="w-4 h-4 mr-1" />
|
||||
No
|
||||
</Button>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
)}
|
||||
|
||||
{questionsAsked.length > 0 && (
|
||||
<div className="space-y-2">
|
||||
<h4 className="font-semibold">Questions Asked:</h4>
|
||||
<div className="space-y-1 max-h-32 overflow-y-auto">
|
||||
{questionsAsked.map((question, index) => (
|
||||
<div key={index} className="text-sm p-2 bg-muted rounded">
|
||||
{question}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<Button onClick={resetGame} variant="outline" className="w-full">
|
||||
New Game
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{gameState === 'won' && (
|
||||
<div className="text-center space-y-4">
|
||||
<div className="space-y-2">
|
||||
<CheckCircle className="w-16 h-16 text-success mx-auto" />
|
||||
<h3 className="text-2xl font-bold text-success">Game Complete!</h3>
|
||||
{gameMode === 'user-guesses' ? (
|
||||
<p className="text-lg">
|
||||
You found the number <span className="font-bold">{secretNumber}</span> in{' '}
|
||||
<span className="font-bold">{guesses.length}</span> guesses!
|
||||
</p>
|
||||
) : (
|
||||
<div className="space-y-2">
|
||||
<p className="text-lg">
|
||||
The computer identified your number using the{' '}
|
||||
<span className="font-bold">{computerStrategy}</span> search strategy!
|
||||
</p>
|
||||
<div className="flex justify-center gap-4">
|
||||
<Badge variant="outline" className="text-lg p-2">
|
||||
<Trophy className="w-5 h-5 mr-2" />
|
||||
Final Score: {userScore} points
|
||||
</Badge>
|
||||
</div>
|
||||
{possibleNumbers.length === 1 && (
|
||||
<p className="text-muted-foreground">
|
||||
Your number was: <span className="font-bold">{possibleNumbers[0]}</span>
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<Button onClick={resetGame} size="lg" className="w-full">
|
||||
Play Again
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{showSocialShare && (
|
||||
<SocialShare
|
||||
title="Number Guessing Game - Learn Search Algorithms"
|
||||
description="Experience different search strategies through this interactive guessing game. Compare random, linear, and binary search approaches!"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default GuessingGame;
|
||||
13
src/pages/GuessingGamePage.tsx
Normal file
13
src/pages/GuessingGamePage.tsx
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import GuessingGame from '@/components/GuessingGame';
|
||||
|
||||
const GuessingGamePage = () => {
|
||||
return (
|
||||
<div className="min-h-screen bg-background">
|
||||
<div className="container mx-auto px-4 py-8">
|
||||
<GuessingGame showSocialShare={true} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default GuessingGamePage;
|
||||
Loading…
Add table
Add a link
Reference in a new issue