From 0ca6682288d318a288d44508df19d6fcd86d1064 Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Wed, 19 Nov 2025 03:32:42 +0000 Subject: [PATCH] Changes --- src/components/PresentsPuzzle.tsx | 243 ++++++++++++++++++++++++++---- 1 file changed, 212 insertions(+), 31 deletions(-) diff --git a/src/components/PresentsPuzzle.tsx b/src/components/PresentsPuzzle.tsx index bbf589c..d7107d6 100644 --- a/src/components/PresentsPuzzle.tsx +++ b/src/components/PresentsPuzzle.tsx @@ -3,7 +3,7 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/com import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; import SocialShare from './SocialShare'; -import { Gift, Play, RotateCw, Zap } from 'lucide-react'; +import { Gift, Play, RotateCw, Zap, Pause, ChevronRight, ChevronLeft, ChevronsRight, ChevronsLeft } from 'lucide-react'; interface PresentsPuzzleProps { showSocialShare?: boolean; shareUrl?: string; @@ -23,6 +23,10 @@ const PresentsPuzzle = ({ const [aliceFound, setAliceFound] = useState(0); const [bobFound, setBobFound] = useState(0); const [isRunning, setIsRunning] = useState(false); + const [isPaused, setIsPaused] = useState(false); + const [currentStep, setCurrentStep] = useState(0); + const [aliceOrder, setAliceOrder] = useState([]); + const [bobOrder, setBobOrder] = useState([]); const [winner, setWinner] = useState<'alice' | 'bob' | 'tie' | null>(null); const [simulationResults, setSimulationResults] = useState({ alice: 0, @@ -80,40 +84,23 @@ const PresentsPuzzle = ({ return 'tie'; // Default, though this should never happen }; - // Animate a single simulation - const startSimulation = async () => { - setIsRunning(true); - setWinner(null); - setAliceOpened(new Set()); - setBobOpened(new Set()); - setAliceFound(0); - setBobFound(0); - const presents = generatePresents(); - setPresentBoxes(presents); - const aliceOrder = getAliceOrder(); - const bobOrder = getBobOrder(); + // Update display for a specific step + const updateStep = (step: number) => { + const aliceOpenedSet = new Set(); + const bobOpenedSet = new Set(); let aliceCount = 0; let bobCount = 0; let currentWinner: 'alice' | 'bob' | 'tie' | null = null; - for (let i = 0; i < 100 && !currentWinner; i++) { - await new Promise(resolve => setTimeout(resolve, 50)); // Animation delay + for (let i = 0; i <= step; i++) { const aliceBox = aliceOrder[i]; const bobBox = bobOrder[i]; - setAliceOpened(prev => new Set(prev).add(aliceBox)); - setBobOpened(prev => new Set(prev).add(bobBox)); - const aliceFoundPresent = presents.has(aliceBox); - const bobFoundPresent = presents.has(bobBox); - if (aliceFoundPresent) { - aliceCount++; - setAliceFound(aliceCount); - } - if (bobFoundPresent) { - bobCount++; - setBobFound(bobCount); - } + aliceOpenedSet.add(aliceBox); + bobOpenedSet.add(bobBox); + + if (presentBoxes.has(aliceBox)) aliceCount++; + if (presentBoxes.has(bobBox)) bobCount++; - // Check for tie first (both reach 26 on same turn) if (aliceCount === 26 && bobCount === 26) { currentWinner = 'tie'; } else if (aliceCount === 26) { @@ -122,10 +109,151 @@ const PresentsPuzzle = ({ currentWinner = 'bob'; } } + + setAliceOpened(aliceOpenedSet); + setBobOpened(bobOpenedSet); + setAliceFound(aliceCount); + setBobFound(bobCount); setWinner(currentWinner); + setCurrentStep(step); + }; + + // Animate a single simulation + const startSimulation = async () => { + if (currentStep === 0) { + // Start new simulation + setIsRunning(true); + setIsPaused(false); + setWinner(null); + setAliceOpened(new Set()); + setBobOpened(new Set()); + setAliceFound(0); + setBobFound(0); + setCurrentStep(0); + const presents = generatePresents(); + setPresentBoxes(presents); + const newAliceOrder = getAliceOrder(); + const newBobOrder = getBobOrder(); + setAliceOrder(newAliceOrder); + setBobOrder(newBobOrder); + + // Start animation from beginning + let aliceCount = 0; + let bobCount = 0; + let currentWinner: 'alice' | 'bob' | 'tie' | null = null; + + for (let i = 0; i < 100 && !currentWinner; i++) { + await new Promise(resolve => setTimeout(resolve, 50)); + + // Check if paused + while (isPaused) { + await new Promise(resolve => setTimeout(resolve, 100)); + } + + const aliceBox = newAliceOrder[i]; + const bobBox = newBobOrder[i]; + setAliceOpened(prev => new Set(prev).add(aliceBox)); + setBobOpened(prev => new Set(prev).add(bobBox)); + setCurrentStep(i); + + const aliceFoundPresent = presents.has(aliceBox); + const bobFoundPresent = presents.has(bobBox); + if (aliceFoundPresent) { + aliceCount++; + setAliceFound(aliceCount); + } + if (bobFoundPresent) { + bobCount++; + setBobFound(bobCount); + } + + if (aliceCount === 26 && bobCount === 26) { + currentWinner = 'tie'; + } else if (aliceCount === 26) { + currentWinner = 'alice'; + } else if (bobCount === 26) { + currentWinner = 'bob'; + } + } + setWinner(currentWinner); + setIsRunning(false); + } else { + // Resume from current step + setIsRunning(true); + setIsPaused(false); + + let aliceCount = aliceFound; + let bobCount = bobFound; + let currentWinner: 'alice' | 'bob' | 'tie' | null = winner; + + for (let i = currentStep + 1; i < 100 && !currentWinner; i++) { + await new Promise(resolve => setTimeout(resolve, 50)); + + while (isPaused) { + await new Promise(resolve => setTimeout(resolve, 100)); + } + + const aliceBox = aliceOrder[i]; + const bobBox = bobOrder[i]; + setAliceOpened(prev => new Set(prev).add(aliceBox)); + setBobOpened(prev => new Set(prev).add(bobBox)); + setCurrentStep(i); + + const aliceFoundPresent = presentBoxes.has(aliceBox); + const bobFoundPresent = presentBoxes.has(bobBox); + if (aliceFoundPresent) { + aliceCount++; + setAliceFound(aliceCount); + } + if (bobFoundPresent) { + bobCount++; + setBobFound(bobCount); + } + + if (aliceCount === 26 && bobCount === 26) { + currentWinner = 'tie'; + } else if (aliceCount === 26) { + currentWinner = 'alice'; + } else if (bobCount === 26) { + currentWinner = 'bob'; + } + } + setWinner(currentWinner); + setIsRunning(false); + } + }; + + const pauseSimulation = () => { + setIsPaused(true); setIsRunning(false); }; + const stepNext = () => { + if (aliceOrder.length === 0 || currentStep >= 99 || winner) return; + updateStep(currentStep + 1); + }; + + const stepBack = () => { + if (aliceOrder.length === 0 || currentStep <= 0) return; + setWinner(null); + updateStep(currentStep - 1); + }; + + const stepToEnd = () => { + if (aliceOrder.length === 0) return; + updateStep(99); + }; + + const stepToStart = () => { + if (aliceOrder.length === 0) return; + setAliceOpened(new Set()); + setBobOpened(new Set()); + setAliceFound(0); + setBobFound(0); + setCurrentStep(0); + setWinner(null); + }; + // Reset simulation const resetSimulation = () => { setPresentBoxes(new Set()); @@ -135,6 +263,10 @@ const PresentsPuzzle = ({ setBobFound(0); setWinner(null); setIsRunning(false); + setIsPaused(false); + setCurrentStep(0); + setAliceOrder([]); + setBobOrder([]); }; // Run 100 simulations @@ -235,10 +367,59 @@ const PresentsPuzzle = ({ } {/* Control Buttons */} -
- + + + + +