Add pause functionality to Bulgarian Solitaire

Update the "Playing..." button to "Pause". When clicked, the simulation will pause and the button text will change to "Continue", allowing the user to resume or reset the game.
This commit is contained in:
gpt-engineer-app[bot] 2025-08-22 10:09:13 +00:00
parent 64f864efed
commit a1945611ef

View file

@ -1,4 +1,4 @@
import React, { useState, useEffect } from 'react';
import React, { useState, useEffect, useRef } from 'react';
import { Button } from '@/components/ui/button';
import { Slider } from '@/components/ui/slider';
import SocialShare from '@/components/SocialShare';
@ -18,6 +18,7 @@ const BulgarianSolitaire: React.FC<BulgarianSolitaireProps> = ({ showSocialShare
const [boxes, setBoxes] = useState<Box[]>([]);
const [columns, setColumns] = useState<number[][]>([]);
const [isPlaying, setIsPlaying] = useState(false);
const [isPaused, setIsPaused] = useState(false);
const [draggedBox, setDraggedBox] = useState<number | null>(null);
const [step, setStep] = useState(0);
const [isComplete, setIsComplete] = useState(false);
@ -27,6 +28,8 @@ const BulgarianSolitaire: React.FC<BulgarianSolitaireProps> = ({ showSocialShare
const [selectedBoxForMove, setSelectedBoxForMove] = useState<number | null>(null);
const [showInstructions, setShowInstructions] = useState(false);
const pauseRef = useRef(false);
const totalBoxes = n;
// Initialize boxes and columns when n changes
@ -173,6 +176,22 @@ const BulgarianSolitaire: React.FC<BulgarianSolitaireProps> = ({ showSocialShare
const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
const waitForUnpause = async () => {
while (pauseRef.current) {
await sleep(100);
}
};
const handlePause = () => {
pauseRef.current = true;
setIsPaused(true);
};
const handleResume = () => {
pauseRef.current = false;
setIsPaused(false);
};
const isTriangularConfiguration = (cols: number[][]) => {
const nonEmptyCols = cols.filter(col => col.length > 0).sort((a, b) => a.length - b.length);
@ -215,6 +234,7 @@ const BulgarianSolitaire: React.FC<BulgarianSolitaireProps> = ({ showSocialShare
setHighlightedBoxes(topBoxes);
setIsAnimating(true);
await sleep(800); // Show highlighting
await waitForUnpause(); // Check for pause
// Create new pile from non-empty columns
const newPile: number[] = [];
@ -265,6 +285,7 @@ const BulgarianSolitaire: React.FC<BulgarianSolitaireProps> = ({ showSocialShare
}));
await sleep(1200); // Wait to see the sorted result
await waitForUnpause(); // Check for pause again
}
setIsComplete(isTriangularConfiguration(currentColumns));
@ -278,6 +299,10 @@ const BulgarianSolitaire: React.FC<BulgarianSolitaireProps> = ({ showSocialShare
};
const reset = () => {
pauseRef.current = false;
setIsPaused(false);
setIsPlaying(false);
const newBoxes: Box[] = [];
for (let i = 0; i < totalBoxes; i++) {
newBoxes.push({ id: i, columnIndex: null });
@ -286,7 +311,6 @@ const BulgarianSolitaire: React.FC<BulgarianSolitaireProps> = ({ showSocialShare
setColumns(Array.from({ length: totalBoxes }, () => []));
setStep(0);
setIsComplete(false);
setIsPlaying(false);
setHighlightedBoxes(new Set());
setIsAnimating(false);
};
@ -347,10 +371,10 @@ const BulgarianSolitaire: React.FC<BulgarianSolitaireProps> = ({ showSocialShare
disabled={isPlaying}
/>
</div>
<Button onClick={reset} variant="outline" disabled={isPlaying}>
<Button onClick={reset} variant="outline" disabled={isPlaying && !isPaused}>
Reset
</Button>
<Button onClick={randomStart} variant="default" disabled={isPlaying}>
<Button onClick={randomStart} variant="default" disabled={isPlaying && !isPaused}>
Random Start
</Button>
</div>
@ -428,12 +452,12 @@ const BulgarianSolitaire: React.FC<BulgarianSolitaireProps> = ({ showSocialShare
{/* Play Button */}
<div className="flex justify-center">
<Button
onClick={simulateBulgarianSolitaire}
disabled={isPlaying || containerBoxes.length > 0}
onClick={isPlaying ? (isPaused ? handleResume : handlePause) : simulateBulgarianSolitaire}
disabled={!isPlaying && containerBoxes.length > 0}
size="lg"
className="px-12"
>
{isPlaying ? 'Playing...' : 'Play'}
{isPlaying ? (isPaused ? 'Continue' : 'Pause') : 'Play'}
</Button>
</div>