Synchronize auto-play steps
Ensure Alice and Bob's step counts advance in lockstep during auto-play and remain synced when paused. Update PresentsPuzzle logic to keep both sides' opened boxes counts aligned and reflect consistent progression across pause/resume. X-Lovable-Edit-ID: edt-5987193b-4caf-47a0-a0d9-332b2b269e6f
This commit is contained in:
commit
8cb5f4bdf4
1 changed files with 52 additions and 38 deletions
|
|
@ -141,11 +141,6 @@ const PresentsPuzzle = ({
|
|||
setIsRunning(true);
|
||||
isPausedRef.current = false;
|
||||
setWinner(null);
|
||||
setAliceOpened(new Set());
|
||||
setBobOpened(new Set());
|
||||
setAliceFound(0);
|
||||
setBobFound(0);
|
||||
setCurrentStep(0);
|
||||
const presents = generatePresents();
|
||||
setPresentBoxes(presents);
|
||||
const newAliceOrder = getAliceOrder();
|
||||
|
|
@ -153,36 +148,49 @@ const PresentsPuzzle = ({
|
|||
setAliceOrder(newAliceOrder);
|
||||
setBobOrder(newBobOrder);
|
||||
|
||||
// Initialize with empty state
|
||||
setAliceOpened(new Set());
|
||||
setBobOpened(new Set());
|
||||
setAliceFound(0);
|
||||
setBobFound(0);
|
||||
setCurrentStep(-1); // -1 means no boxes opened yet
|
||||
|
||||
// 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 pause after delay, before opening boxes
|
||||
if (isPausedRef.current) {
|
||||
setCurrentStep(i);
|
||||
setIsRunning(false);
|
||||
return;
|
||||
}
|
||||
|
||||
await new Promise(resolve => setTimeout(resolve, 50));
|
||||
|
||||
const aliceBox = newAliceOrder[i];
|
||||
const bobBox = newBobOrder[i];
|
||||
setAliceOpened(prev => new Set(prev).add(aliceBox));
|
||||
setBobOpened(prev => new Set(prev).add(bobBox));
|
||||
setCurrentStep(i);
|
||||
|
||||
// Create new sets with the new boxes (ensures synchronous update)
|
||||
const newAliceOpened = new Set<number>();
|
||||
const newBobOpened = new Set<number>();
|
||||
for (let j = 0; j <= i; j++) {
|
||||
newAliceOpened.add(newAliceOrder[j]);
|
||||
newBobOpened.add(newBobOrder[j]);
|
||||
}
|
||||
|
||||
const aliceFoundPresent = presents.has(aliceBox);
|
||||
const bobFoundPresent = presents.has(bobBox);
|
||||
if (aliceFoundPresent) {
|
||||
aliceCount++;
|
||||
setAliceFound(aliceCount);
|
||||
}
|
||||
if (bobFoundPresent) {
|
||||
bobCount++;
|
||||
setBobFound(bobCount);
|
||||
}
|
||||
if (aliceFoundPresent) aliceCount++;
|
||||
if (bobFoundPresent) bobCount++;
|
||||
|
||||
// Update all state together for perfect sync
|
||||
setAliceOpened(newAliceOpened);
|
||||
setBobOpened(newBobOpened);
|
||||
setAliceFound(aliceCount);
|
||||
setBobFound(bobCount);
|
||||
setCurrentStep(i);
|
||||
|
||||
if (aliceCount === 26 && bobCount === 26) {
|
||||
currentWinner = 'tie';
|
||||
|
|
@ -204,30 +212,36 @@ const PresentsPuzzle = ({
|
|||
let currentWinner: 'alice' | 'bob' | 'tie' | null = winner;
|
||||
|
||||
for (let i = currentStep + 1; i < 100 && !currentWinner; i++) {
|
||||
await new Promise(resolve => setTimeout(resolve, 50));
|
||||
|
||||
// Check pause after delay, before opening boxes
|
||||
if (isPausedRef.current) {
|
||||
setCurrentStep(i);
|
||||
setIsRunning(false);
|
||||
return;
|
||||
}
|
||||
|
||||
await new Promise(resolve => setTimeout(resolve, 50));
|
||||
|
||||
const aliceBox = aliceOrder[i];
|
||||
const bobBox = bobOrder[i];
|
||||
setAliceOpened(prev => new Set(prev).add(aliceBox));
|
||||
setBobOpened(prev => new Set(prev).add(bobBox));
|
||||
setCurrentStep(i);
|
||||
|
||||
// Create new sets with the new boxes
|
||||
const newAliceOpened = new Set<number>();
|
||||
const newBobOpened = new Set<number>();
|
||||
for (let j = 0; j <= i; j++) {
|
||||
newAliceOpened.add(aliceOrder[j]);
|
||||
newBobOpened.add(bobOrder[j]);
|
||||
}
|
||||
|
||||
const aliceFoundPresent = presentBoxes.has(aliceBox);
|
||||
const bobFoundPresent = presentBoxes.has(bobBox);
|
||||
if (aliceFoundPresent) {
|
||||
aliceCount++;
|
||||
setAliceFound(aliceCount);
|
||||
}
|
||||
if (bobFoundPresent) {
|
||||
bobCount++;
|
||||
setBobFound(bobCount);
|
||||
}
|
||||
if (aliceFoundPresent) aliceCount++;
|
||||
if (bobFoundPresent) bobCount++;
|
||||
|
||||
// Update all state together for perfect sync
|
||||
setAliceOpened(newAliceOpened);
|
||||
setBobOpened(newBobOpened);
|
||||
setAliceFound(aliceCount);
|
||||
setBobFound(bobCount);
|
||||
setCurrentStep(i);
|
||||
|
||||
if (aliceCount === 26 && bobCount === 26) {
|
||||
currentWinner = 'tie';
|
||||
|
|
@ -268,7 +282,7 @@ const PresentsPuzzle = ({
|
|||
setBobOpened(new Set());
|
||||
setAliceFound(0);
|
||||
setBobFound(0);
|
||||
setCurrentStep(0);
|
||||
setCurrentStep(-1); // -1 means no boxes opened yet
|
||||
setWinner(null);
|
||||
};
|
||||
|
||||
|
|
@ -282,7 +296,7 @@ const PresentsPuzzle = ({
|
|||
setWinner(null);
|
||||
setIsRunning(false);
|
||||
isPausedRef.current = false;
|
||||
setCurrentStep(0);
|
||||
setCurrentStep(-1); // -1 means not initialized
|
||||
setAliceOrder([]);
|
||||
setBobOrder([]);
|
||||
};
|
||||
|
|
@ -392,7 +406,7 @@ const PresentsPuzzle = ({
|
|||
className="gap-2"
|
||||
>
|
||||
<Play className="w-4 h-4" />
|
||||
{currentStep === 0 ? 'Start' : 'Resume'}
|
||||
{currentStep === -1 ? 'Start' : 'Resume'}
|
||||
</Button>
|
||||
<Button
|
||||
onClick={pauseSimulation}
|
||||
|
|
@ -405,7 +419,7 @@ const PresentsPuzzle = ({
|
|||
</Button>
|
||||
<Button
|
||||
onClick={stepToStart}
|
||||
disabled={isRunning || currentStep === 0}
|
||||
disabled={isRunning || currentStep <= -1}
|
||||
variant="outline"
|
||||
className="gap-2"
|
||||
title="Step to start"
|
||||
|
|
@ -414,7 +428,7 @@ const PresentsPuzzle = ({
|
|||
</Button>
|
||||
<Button
|
||||
onClick={stepBack}
|
||||
disabled={isRunning || currentStep === 0}
|
||||
disabled={isRunning || currentStep <= -1}
|
||||
variant="outline"
|
||||
className="gap-2"
|
||||
title="Step back"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue