interactives/src/pages/DogsBunnyPuzzlePage.tsx
gpt-engineer-app[bot] f33b2bfa4f Add Dogs & Bunny puzzle
Recreate the Dogs & Bunny puzzle with random puzzle generation, difficulty levels, screenshot functionality, and shareable URL parameters.
2025-08-10 05:32:16 +00:00

138 lines
No EOL
5 KiB
TypeScript

import { useEffect, useState } from 'react';
import { useSearchParams, useNavigate } from 'react-router-dom';
import Layout from '@/components/Layout';
import DogsBunnyPuzzle from '@/components/DogsBunnyPuzzle';
import { Button } from '@/components/ui/button';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { ArrowLeft } from 'lucide-react';
const DogsBunnyPuzzlePage = () => {
const [searchParams, setSearchParams] = useSearchParams();
const navigate = useNavigate();
const [difficulty, setDifficulty] = useState<'easy' | 'medium' | 'hard'>('medium');
const [seed, setSeed] = useState<string | undefined>(undefined);
useEffect(() => {
const diffParam = searchParams.get('difficulty') as 'easy' | 'medium' | 'hard';
const seedParam = searchParams.get('seed');
if (diffParam && ['easy', 'medium', 'hard'].includes(diffParam)) {
setDifficulty(diffParam);
}
if (seedParam) {
setSeed(seedParam);
}
}, [searchParams]);
const handleDifficultyChange = (newDifficulty: 'easy' | 'medium' | 'hard') => {
setDifficulty(newDifficulty);
const newParams = new URLSearchParams(searchParams);
newParams.set('difficulty', newDifficulty);
setSearchParams(newParams);
};
const handleBackNavigation = () => {
const from = searchParams.get('from');
if (from === 'puzzles') {
navigate('/themes/puzzles');
} else {
navigate('/');
}
};
return (
<Layout>
<div className="min-h-screen bg-background">
<div className="container mx-auto px-4 py-8">
{/* Header */}
<div className="flex items-center justify-between mb-8">
<div className="flex items-center gap-4">
<Button
variant="ghost"
size="sm"
onClick={handleBackNavigation}
className="flex items-center gap-2"
>
<ArrowLeft className="h-4 w-4" />
Back
</Button>
<div>
<h1 className="text-3xl font-bold text-foreground">Dogs & Bunny Puzzle</h1>
<p className="text-muted-foreground mt-1">
A logic puzzle about getting animals to their favorite spots
</p>
</div>
</div>
<div className="flex items-center gap-4">
<div className="flex items-center gap-2">
<span className="text-sm font-medium">Difficulty:</span>
<Select value={difficulty} onValueChange={handleDifficultyChange}>
<SelectTrigger className="w-32">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="easy">Easy</SelectItem>
<SelectItem value="medium">Medium</SelectItem>
<SelectItem value="hard">Hard</SelectItem>
</SelectContent>
</Select>
</div>
</div>
</div>
{/* Instructions */}
<div className="bg-muted/10 rounded-lg p-6 mb-8">
<h2 className="text-xl font-semibold mb-4">Puzzle Rules</h2>
<div className="grid md:grid-cols-2 gap-6">
<div>
<h3 className="font-medium mb-2">Objective:</h3>
<ul className="text-sm text-muted-foreground space-y-1">
<li> Get all bunnies 🐰 to the carrot 🥕</li>
<li> Get the dog 🐕 to the bone 🦴</li>
</ul>
</div>
<div>
<h3 className="font-medium mb-2">Movement Rules:</h3>
<ul className="text-sm text-muted-foreground space-y-1">
<li> Click a character to select it</li>
<li> You can only move along edges where all conditions are met</li>
<li> Multiple animals can occupy the same location</li>
<li> Edge labels show the required conditions</li>
</ul>
</div>
</div>
</div>
{/* Puzzle Component */}
<div className="flex justify-center">
<DogsBunnyPuzzle
difficulty={difficulty}
seed={seed}
onComplete={() => {
// Could add achievements or stats here
}}
/>
</div>
{/* Additional Info */}
<div className="mt-8 text-center text-sm text-muted-foreground">
<p>
Original puzzle concept by <a
href="https://twitter.com/lisperati"
target="_blank"
rel="noopener noreferrer"
className="text-primary hover:underline"
>
Conrad Barski (@lisperati)
</a>
</p>
</div>
</div>
</div>
</Layout>
);
};
export default DogsBunnyPuzzlePage;