This commit is contained in:
gpt-engineer-app[bot] 2025-11-19 03:38:28 +00:00
parent 6f35e0c38e
commit 7b392c9914

View file

@ -1,4 +1,4 @@
import { useState } from 'react'; import { useState, useRef } from 'react';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge'; import { Badge } from '@/components/ui/badge';
@ -23,7 +23,6 @@ const PresentsPuzzle = ({
const [aliceFound, setAliceFound] = useState(0); const [aliceFound, setAliceFound] = useState(0);
const [bobFound, setBobFound] = useState(0); const [bobFound, setBobFound] = useState(0);
const [isRunning, setIsRunning] = useState(false); const [isRunning, setIsRunning] = useState(false);
const [isPaused, setIsPaused] = useState(false);
const [currentStep, setCurrentStep] = useState(0); const [currentStep, setCurrentStep] = useState(0);
const [aliceOrder, setAliceOrder] = useState<number[]>([]); const [aliceOrder, setAliceOrder] = useState<number[]>([]);
const [bobOrder, setBobOrder] = useState<number[]>([]); const [bobOrder, setBobOrder] = useState<number[]>([]);
@ -34,6 +33,7 @@ const PresentsPuzzle = ({
ties: 0 ties: 0
}); });
const [hasSimulated, setHasSimulated] = useState(false); const [hasSimulated, setHasSimulated] = useState(false);
const isPausedRef = useRef(false);
// Generate random present positions // Generate random present positions
const generatePresents = (): Set<number> => { const generatePresents = (): Set<number> => {
@ -84,8 +84,24 @@ const PresentsPuzzle = ({
return 'tie'; // Default, though this should never happen return 'tie'; // Default, though this should never happen
}; };
// Initialize simulation if not already initialized
const initializeSimulation = () => {
if (aliceOrder.length === 0) {
const presents = generatePresents();
setPresentBoxes(presents);
const newAliceOrder = getAliceOrder();
const newBobOrder = getBobOrder();
setAliceOrder(newAliceOrder);
setBobOrder(newBobOrder);
return { presents, aliceOrder: newAliceOrder, bobOrder: newBobOrder };
}
return { presents: presentBoxes, aliceOrder, bobOrder };
};
// Update display for a specific step // Update display for a specific step
const updateStep = (step: number) => { const updateStep = (step: number) => {
const { presents, aliceOrder: aOrder, bobOrder: bOrder } = initializeSimulation();
const aliceOpenedSet = new Set<number>(); const aliceOpenedSet = new Set<number>();
const bobOpenedSet = new Set<number>(); const bobOpenedSet = new Set<number>();
let aliceCount = 0; let aliceCount = 0;
@ -93,13 +109,13 @@ const PresentsPuzzle = ({
let currentWinner: 'alice' | 'bob' | 'tie' | null = null; let currentWinner: 'alice' | 'bob' | 'tie' | null = null;
for (let i = 0; i <= step; i++) { for (let i = 0; i <= step; i++) {
const aliceBox = aliceOrder[i]; const aliceBox = aOrder[i];
const bobBox = bobOrder[i]; const bobBox = bOrder[i];
aliceOpenedSet.add(aliceBox); aliceOpenedSet.add(aliceBox);
bobOpenedSet.add(bobBox); bobOpenedSet.add(bobBox);
if (presentBoxes.has(aliceBox)) aliceCount++; if (presents.has(aliceBox)) aliceCount++;
if (presentBoxes.has(bobBox)) bobCount++; if (presents.has(bobBox)) bobCount++;
if (aliceCount === 26 && bobCount === 26) { if (aliceCount === 26 && bobCount === 26) {
currentWinner = 'tie'; currentWinner = 'tie';
@ -120,10 +136,10 @@ const PresentsPuzzle = ({
// Animate a single simulation // Animate a single simulation
const startSimulation = async () => { const startSimulation = async () => {
if (currentStep === 0) { if (currentStep === 0 || aliceOrder.length === 0) {
// Start new simulation // Start new simulation
setIsRunning(true); setIsRunning(true);
setIsPaused(false); isPausedRef.current = false;
setWinner(null); setWinner(null);
setAliceOpened(new Set()); setAliceOpened(new Set());
setBobOpened(new Set()); setBobOpened(new Set());
@ -143,13 +159,14 @@ const PresentsPuzzle = ({
let currentWinner: 'alice' | 'bob' | 'tie' | null = null; let currentWinner: 'alice' | 'bob' | 'tie' | null = null;
for (let i = 0; i < 100 && !currentWinner; i++) { for (let i = 0; i < 100 && !currentWinner; i++) {
await new Promise(resolve => setTimeout(resolve, 50)); if (isPausedRef.current) {
setCurrentStep(i);
// Check if paused setIsRunning(false);
while (isPaused) { return;
await new Promise(resolve => setTimeout(resolve, 100));
} }
await new Promise(resolve => setTimeout(resolve, 50));
const aliceBox = newAliceOrder[i]; const aliceBox = newAliceOrder[i];
const bobBox = newBobOrder[i]; const bobBox = newBobOrder[i];
setAliceOpened(prev => new Set(prev).add(aliceBox)); setAliceOpened(prev => new Set(prev).add(aliceBox));
@ -180,19 +197,21 @@ const PresentsPuzzle = ({
} else { } else {
// Resume from current step // Resume from current step
setIsRunning(true); setIsRunning(true);
setIsPaused(false); isPausedRef.current = false;
let aliceCount = aliceFound; let aliceCount = aliceFound;
let bobCount = bobFound; let bobCount = bobFound;
let currentWinner: 'alice' | 'bob' | 'tie' | null = winner; let currentWinner: 'alice' | 'bob' | 'tie' | null = winner;
for (let i = currentStep + 1; i < 100 && !currentWinner; i++) { for (let i = currentStep + 1; i < 100 && !currentWinner; i++) {
await new Promise(resolve => setTimeout(resolve, 50)); if (isPausedRef.current) {
setCurrentStep(i);
while (isPaused) { setIsRunning(false);
await new Promise(resolve => setTimeout(resolve, 100)); return;
} }
await new Promise(resolve => setTimeout(resolve, 50));
const aliceBox = aliceOrder[i]; const aliceBox = aliceOrder[i];
const bobBox = bobOrder[i]; const bobBox = bobOrder[i];
setAliceOpened(prev => new Set(prev).add(aliceBox)); setAliceOpened(prev => new Set(prev).add(aliceBox));
@ -224,28 +243,27 @@ const PresentsPuzzle = ({
}; };
const pauseSimulation = () => { const pauseSimulation = () => {
setIsPaused(true); isPausedRef.current = true;
setIsRunning(false); setIsRunning(false);
}; };
const stepNext = () => { const stepNext = () => {
if (aliceOrder.length === 0 || currentStep >= 99 || winner) return; if (currentStep >= 99 || winner) return;
updateStep(currentStep + 1); updateStep(currentStep + 1);
}; };
const stepBack = () => { const stepBack = () => {
if (aliceOrder.length === 0 || currentStep <= 0) return; if (currentStep <= 0) return;
setWinner(null); setWinner(null);
updateStep(currentStep - 1); updateStep(currentStep - 1);
}; };
const stepToEnd = () => { const stepToEnd = () => {
if (aliceOrder.length === 0) return;
updateStep(99); updateStep(99);
}; };
const stepToStart = () => { const stepToStart = () => {
if (aliceOrder.length === 0) return; initializeSimulation();
setAliceOpened(new Set()); setAliceOpened(new Set());
setBobOpened(new Set()); setBobOpened(new Set());
setAliceFound(0); setAliceFound(0);
@ -263,7 +281,7 @@ const PresentsPuzzle = ({
setBobFound(0); setBobFound(0);
setWinner(null); setWinner(null);
setIsRunning(false); setIsRunning(false);
setIsPaused(false); isPausedRef.current = false;
setCurrentStep(0); setCurrentStep(0);
setAliceOrder([]); setAliceOrder([]);
setBobOrder([]); setBobOrder([]);
@ -387,7 +405,7 @@ const PresentsPuzzle = ({
</Button> </Button>
<Button <Button
onClick={stepToStart} onClick={stepToStart}
disabled={isRunning || aliceOrder.length === 0 || currentStep === 0} disabled={isRunning || currentStep === 0}
variant="outline" variant="outline"
className="gap-2" className="gap-2"
title="Step to start" title="Step to start"
@ -396,7 +414,7 @@ const PresentsPuzzle = ({
</Button> </Button>
<Button <Button
onClick={stepBack} onClick={stepBack}
disabled={isRunning || aliceOrder.length === 0 || currentStep === 0} disabled={isRunning || currentStep === 0}
variant="outline" variant="outline"
className="gap-2" className="gap-2"
title="Step back" title="Step back"
@ -405,7 +423,7 @@ const PresentsPuzzle = ({
</Button> </Button>
<Button <Button
onClick={stepNext} onClick={stepNext}
disabled={isRunning || aliceOrder.length === 0 || currentStep >= 99 || winner !== null} disabled={isRunning || currentStep >= 99 || winner !== null}
variant="outline" variant="outline"
className="gap-2" className="gap-2"
title="Step next" title="Step next"
@ -414,7 +432,7 @@ const PresentsPuzzle = ({
</Button> </Button>
<Button <Button
onClick={stepToEnd} onClick={stepToEnd}
disabled={isRunning || aliceOrder.length === 0 || currentStep >= 99} disabled={isRunning || currentStep >= 99}
variant="outline" variant="outline"
className="gap-2" className="gap-2"
title="Step to end" title="Step to end"